在 C 中使用 strtod() 将具有巨大数字的字符串转换为双浮点数后,errno 未设置为 ERANGE

时间:2021-07-15 16:11:40

标签: c

我很困惑,在 ERANGE 尝试将具有巨大实数的字符串转换为双浮点数后,errno 没有被设置为 strtod()。 >

这是我运行代码时发生的情况:

Enter a real number: 5656565656565652622326352635236523652362356235
You entered 5656565656565652358969982685269310483757793280.000000.

这是我的代码:

#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;        
}

1 个答案:

答案 0 :(得分:1)

当输入一个非常大(或非常小)的数字时,errno 实际上被正确设置为 ERANGE。

如果一个人进入一个非常大的数字,如“100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000”,errno设置为ERANGE和以下被打印 - “对不起,此数量过小或过大”因此,发布的代码有效且工作正常。

问题中输入数字和输出数字不匹配的原因是由于精度损失而不是超出范围。 并非动态范围(指数)内的每个数字都可以(由尾数)准确表示。

非常感谢 Useless 和 Jabberwocky 指出这一点!

相关问题