HiveBrain v1.2.0
Get Started
← Back to all entries
snippetcppMinor

Implement strtod parsing

Submitted by: @import:stackexchange-codereview··
0
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.

  • 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 ...

  • 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.