Menu

#711 strtold returns a finite value when it should return Inf

v1.0 (example)
open
nobody
None
3
2018-07-01
2018-03-11
Sisyphus
No

strtold() should evaluate any string that consists (solely) of more than 4933 decimal digits as Inf - that is, if the leading digit is something other than zero.
But in fact, if the number of digits is greater than 4933, the chances of strtold returning a long double set to Inf is only 25 in 8192.
The values are not, however, determined at random - there's a well defined pattern.

The attached bug.c sets a string to argv[1] digits - the first digit being 9, and all ensuing digits being 0.
Correct values are assigned by strtold so long as the string length is less than 4958.
If the string length is in the range 4958 to 8216, then strtold sets a value of 0.
Then, if the string length is in the range 8217 to 13124 the values range from 9.000000e+024 (for 8217) through to 9.000000e+4931 (for 13124).

As we increment the lengths by 1, we keep cycling through 25 infs, followed by 3259 zeroes, followed by the 4908 values 9.000000e+024 to 9.000000e+4931.

This seems to have been the case with mingw-w64 for quite a while. I see the bahaviour in 4.9.2 and in 7.2.0.
I don't see this behaviour with gcc on linux at all - so I figure the problem is with the mingw runtime.

It would be most helpful to me if this could be fixed in the next runtime release.
I find that the strtod function does not suffer from this issue.

Cheers,
Rob

1 Attachments

Discussion

  • Sisyphus

    Sisyphus - 2018-04-29

    I've just noticed that something similar (and perhaps related) is happening for strings that are written in scientific notation.
    For example, although strtold("1e4956", NULL) correctly returns "inf", strtold("1e4957", NULL) returns zero.
    As I keep incrementing the exponent, the returned value remains "0" until we reach strtold("1e4978", NULL) when we start to get correct returns of "inf" again.

    Cheers,
    Rob

     
  • Sisyphus

    Sisyphus - 2018-07-01

    As a workaround, it's simply a matter of calling __mingw_strtold() instead of strtold().

    Cheers,
    Rob

     

Log in to post a comment.

MongoDB Logo MongoDB