Menu

#501 atof("inf") not standard-compliant (returns 0)

v1.0 (example)
open
nobody
5
2017-09-02
2015-10-11
No

using:
MinGW gcc.exe (i686-posix-dwarf-rev1, Built by MinGW-W64 project) 4.9.2
MSYS2 in Windows 7
atof is not C standard compliant for "-inf", "inf", "-NaN", "NaN", "+NaN" (including all ignoring cases variations) as described at ISO/IEC 9899:1999, sections 7.20.1.1 & 7.20.1.3. It returns 0., but it should return infinity and quiet-NaN values for which there are valid representations under IEEE 754, as it does in Linux.

minimal case(s):

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

int main()
{
    char s[256];

    strcpy(s, "-inf");
    printf("atof(\"%s\") = %.17g\n", s, atof(s));

    strcpy(s, "inf");
    printf("atof(\"%s\") = %.17g\n", s, atof(s));

    strcpy(s, "-NaN");
    printf("atof(\"%s\") = %.17g\n", s, atof(s));

    strcpy(s, "nan");
    printf("atof(\"%s\") = %.17g\n", s, atof(s));

    strcpy(s, "+NAN");
    printf("atof(\"%s\") = %.17g\n", s, atof(s));

    return 1;
}

gives output:

$ ./a.exe
atof("-inf") = 0
atof("inf") = 0
atof("-NaN") = 0
atof("nan") = 0
atof("+NAN") = 0

Please make it standard compliant, or if there is a strong reason why this is already not done (maybe even intentionally implemented as it is now), please introduce compiler flag to enforce it.

I was told mingw uses MSVCRT.DLL for atof, and that this should be brought to MS's attention. But mingw-w64 gcc should mirror gcc execution, no matter VC implementations, if possible. I was instructed to insert the following macro into stdlib.h as an improvised workaround, just to give you an idea...

#define atof(S) (double)(strtold((S),NULL))

Thanks!

Discussion

  • Hrvoje Abraham

    Hrvoje Abraham - 2015-10-11

    Looks like mingw-w64 works with ordinary strtod(s, NULL), (double) strtold(s, NULL) is needed for mingw.

    Does mingw-w64 has MSVC independent implementation of strtod(...)? Where can I obtain a list of mingw-w64 MSVC dependent methods?

     
  • Zufu Liu

    Zufu Liu - 2017-09-01

    It seems strtod is correct with gcc version 7.1.0 (x86_64-posix-seh-rev2, Built by MinGW-W64 project). say the result for atof(), strtod(), and strtold():

    atof("-inf") = 0, -1.#INF, -1.#INF
    atof("inf") = 0, 1.#INF, 1.#INF
    atof("-NaN") = 0, -1.#IND, 1.#QNAN
    atof("nan") = 0, 1.#QNAN, 1.#QNAN
    atof("+NAN") = 0, 1.#QNAN, 1.#QNAN
    

    with -D__USE_MINGW_ANSI_STDIO

    atof("-inf") = 0, -inf, -inf
    atof("inf") = 0, inf, inf
    atof("-NaN") = 0, nan, nan
    atof("nan") = 0, nan, nan
    atof("+NAN") = 0, nan, nan
    

    however different from MSVC 2017:

    atof("-inf") = -inf, -inf, -inf
    atof("inf") = inf, inf, inf
    atof("-NaN") = -nan, -nan, -nan
    atof("nan") = nan, nan, nan
    atof("+NAN") = nan, nan, nan
    
     

    Last edit: Zufu Liu 2017-09-02
  • Zufu Liu

    Zufu Liu - 2017-09-02

    full test code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main()
    {
        char s[256];
    
        strcpy(s, "-inf");
        printf("atof(\"%s\") = %.17g, %.17g, %.17g\n", s, atof(s), strtod(s, NULL), (double)strtold(s, NULL));
    
        strcpy(s, "inf");
        printf("atof(\"%s\") = %.17g, %.17g, %.17g\n", s, atof(s), strtod(s, NULL), (double)strtold(s, NULL));
    
        strcpy(s, "-NaN");
        printf("atof(\"%s\") = %.17g, %.17g, %.17g\n", s, atof(s), strtod(s, NULL), (double)strtold(s, NULL));
    
        strcpy(s, "nan");
        printf("atof(\"%s\") = %.17g, %.17g, %.17g\n", s, atof(s), strtod(s, NULL), (double)strtold(s, NULL));
    
        strcpy(s, "+NAN");
        printf("atof(\"%s\") = %.17g, %.17g, %.17g\n", s, atof(s), strtod(s, NULL), (double)strtold(s, NULL));
    
        return 1;
    }
    
     
  • Zufu Liu

    Zufu Liu - 2017-09-02

    result from http://www.tutorialspoint.com/compile_cpp_online.php

    atof("-inf") = -inf, -inf, -inf                                                                                                                                 
    atof("inf") = inf, inf, inf                                                                                                                                     
    atof("-NaN") = nan, nan, nan                                                                                                                                    
    atof("nan") = nan, nan, nan                                                                                                                                     
    atof("+NAN") = nan, nan, nan
    
    --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
    Thread model: posix                                                                                                                                             
    gcc version 7.1.1 20170622 (Red Hat 7.1.1-3) (GCC)
    
     

Log in to post a comment.