RobK
RobK

Reputation: 366

errno NOT being set to ERANGE after converting a string with a HUGE number to a double floating point number using strtod() in C

I am perplexed that errno is not being set to ERANGE after strtod() tries to convert a string with a huge real number to an double floating point number.

Here is what happens when I run my code:

Enter a real number: 5656565656565652622326352635236523652362356235
You entered 5656565656565652358969982685269310483757793280.000000.

Here is my code:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int getDouble(char* prompt, double* doubleRealNumber);

int main(void)
{  
    double d;

    getDouble("Enter a real number: ", &d);
    printf("You entered %lf.\n", d);

    return 0;
}

int getDouble(char* prompt, double* doubleRealNumber)
{
    int const MAXBUFSIZE = 1024;
    char buf[MAXBUFSIZE]; // use 1KiB just to be sure
    int success; // flag for successful conversion
    
    do
    {
        printf("%s", prompt);
        fflush(stdout);
        
        if (!fgets(buf, MAXBUFSIZE, stdin))
        {
            // reading input failed:
            return 1;
        }
        
        // have some input, convert it to integer:
        char *endptr;
        
        errno = 0; // reset error number
    
        *doubleRealNumber = strtod(buf, &endptr);
        
        if (errno == ERANGE)
        {
            printf("Sorry, this number is too small or too large.\n");
            success = 0;
        }
        else if (endptr == buf)
        {
            // no character was read
            success = 0;
        }
        else if (*endptr && *endptr != '\n')
        {
            // *endptr is neither end of string nor newline,
            // so we didn't convert the *whole* input
            success = 0;
        }
        else
        {
            success = 1;
        }
    } while (!success); // repeat until we got a valid real number
    
    return 0;        
}

Upvotes: 5

Views: 268

Answers (1)

RobK
RobK

Reputation: 366

errno is in fact being set properly to ERANGE when a very large (or very small) number is entered.

If one enters a really big number like "100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", errno is set to ERANGE and the following is printed -- "Sorry, this number is too small or too large." So, the code posted is valid and works properly.

The reason is the input number and the output number do not match in the question is due to a loss of precision rather than out of range. Not every number within the dynamic range (of the exponent) can be accurately represented (by the mantissa).

Many thanks to Useless and Jabberwocky for pointing this out!

Upvotes: 1

Related Questions