snippetcppMinor
Implement strtod parsing
Viewed 0 times
strtodparsingimplement
Problem
In this comment the OP wrote,
I am a newbie so i would like to know how would i parse the negetive numbers/arguments ?
In this answer @200_success showed an implementation using the strtod function.
The following is my implementation of the strtod function:
A valid floating point number for strtod using the "C" locale is formed by an optional sign character (+ or -), followed by a sequence of digits, optionally containing a decimal-point character (.), optionally followed by an exponent part (an e or E character followed by an optional sign and a sequence of digits).
I'm not using a modern compiler so I didn't implement this portion of the spec.:
If the correct value is out of the range of representable values for
the type, a positive or negative HUGE_VAL is returned, and errno is
set to ERANGE.
If the correct value would cause underflow, the function returns a
value whose magnitude is no greater than the smallest normalized
positive number and sets errno to ERANGE.
1(except comments on where I put
```
double strtod(const char* str, char** endptr)
{
double result = 0.0;
char signedResult = '\0';
char signedExponent = '\0';
int decimals = 0;
bool isExponent = false;
bool hasExponent = false;
bool hasResult = false;
// exponent is logically int but is coded as double so that its eventual
// overflow detection can be the same as for double result
double exponent = 0;
char c;
for (; '\0' != (c = *str); ++str)
{
if ((c >= '0') && (c (str);
for (; exponent != 0; --exponent)
{
if (signedExponent == '-')
result /= 10;
else
result *= 10;
}
if
I am a newbie so i would like to know how would i parse the negetive numbers/arguments ?
In this answer @200_success showed an implementation using the strtod function.
The following is my implementation of the strtod function:
A valid floating point number for strtod using the "C" locale is formed by an optional sign character (+ or -), followed by a sequence of digits, optionally containing a decimal-point character (.), optionally followed by an exponent part (an e or E character followed by an optional sign and a sequence of digits).
I'm not using a modern compiler so I didn't implement this portion of the spec.:
If the correct value is out of the range of representable values for
the type, a positive or negative HUGE_VAL is returned, and errno is
set to ERANGE.
If the correct value would cause underflow, the function returns a
value whose magnitude is no greater than the smallest normalized
positive number and sets errno to ERANGE.
- Is my implementation correct (does it return correct output for all input)?
- Is it easy to read even without comments?
- Is the set of test cases sufficiently complete?
- Any other suggestions for improvement?1
1(except comments on where I put
{ } braces, and whether I use them around single-line control statements```
double strtod(const char* str, char** endptr)
{
double result = 0.0;
char signedResult = '\0';
char signedExponent = '\0';
int decimals = 0;
bool isExponent = false;
bool hasExponent = false;
bool hasResult = false;
// exponent is logically int but is coded as double so that its eventual
// overflow detection can be the same as for double result
double exponent = 0;
char c;
for (; '\0' != (c = *str); ++str)
{
if ((c >= '0') && (c (str);
for (; exponent != 0; --exponent)
{
if (signedExponent == '-')
result /= 10;
else
result *= 10;
}
if
Solution
After reading the specification of the input ...
... instead of a single for loop, it might have been clearer (easier to see the mapping from requirements to implementation) to have a succession of 3
It's not completely clear from the specification what the behaviour of "12." should be. "12." is accepted as a valid number by the C++ compiler in source code. This assert succeeds:
... but is missing from the set of test cases in the OP.
- Optional sign
- One or more digits
- Optional decimal with one or more digits
- Optional exponent with
- Optional sign
- one or more digits
... instead of a single for loop, it might have been clearer (easier to see the mapping from requirements to implementation) to have a succession of 3
for loops.It's not completely clear from the specification what the behaviour of "12." should be. "12." is accepted as a valid number by the C++ compiler in source code. This assert succeeds:
assert("12.", 12., "");... but is missing from the set of test cases in the OP.
Code Snippets
assert("12.", 12., "");Context
StackExchange Code Review Q#44869, answer score: 5
Revisions (0)
No revisions yet.