Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what can to_string() return in NaN cases

Im using VS 2012 and I encountered really irritating behaviour(sometimes my float is NaN):

auto dbgHelp = std::to_string(myFloat);

dbgHelp ends up containing 5008 charachters ( you cant invent this stuff up) most of them 0, it ends up with : 0.#INF00

So is this a bug or standard allows idiotic return values like this ?

fix is trivial, for me to manualy do the proper thig with ternary operator and isnan() but I wonder if standard is specific regarding this...

like image 993
NoSenseEtAl Avatar asked Dec 27 '25 20:12

NoSenseEtAl


1 Answers

The std::to_string overloads are specified in [string.conversions]/7:

string to_string(int val);
string to_string(unsigned val);
string to_string(long val);
string to_string(unsigned long val);
string to_string(long long val);
string to_string(unsigned long long val);
string to_string(float val);
string to_string(double val);
string to_string(long double val);

7 Returns: Each function returns a string object holding the character representation of the value of its argument that would be generated by calling sprintf(buf, fmt, val) with a format specifier of "%d", "%u", "%ld", "%lu", "%lld", "%llu", "%f", "%f", or "%Lf", respectively, where buf designates an internal character buffer of sufficient size.

sprintf is detailed in C99 (N1256 actually) 7.19.6.6/2:

The sprintf function is equivalent to fprintf, except that the output is written into an array (specified by the argument s) rather than to a stream. A null character is written at the end of the characters written; it is not counted as part of the returned value. If copying takes place between objects that overlap, the behavior is undefined.

Jumping over to 7.19.6.1 for fprintf, the format flags are described in paragraph 8. Specifically, for the f format:

A double argument representing a floating-point number is converted to decimal notation in the style [−]ddd.ddd, where the number of digits after the decimal-point character is equal to the precision specification. If the precision is missing, it is taken as 6; if the precision is zero and the # flag is not specified, no decimal-point character appears. If a decimal-point character appears, at least one digit appears before it. The value is rounded to the appropriate number of digits.

A double argument representing an infinity is converted in one of the styles [-]inf or [-]infinity — which style is implementation-defined. A double argument representing a NaN is converted in one of the styles [-]nan or [-]nan(n-char-sequence) — which style, and the meaning of any n-char-sequence, is implementation-defined. The F conversion specifier produces INF, INFINITY, or NAN instead of inf, infinity, or nan, respectively.

Putting it all together, when float foo is positive infinity, std::to_string(foo) should return std::string("inf").

like image 103
Casey Avatar answered Dec 31 '25 00:12

Casey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!