innochenti
innochenti

Reputation: 1103

Numeric conversion

In the header of C++11, there are three new functions for conversion between number and string.

std::string std::to_string(unsigned long long);
std::string std::to_string(long double);
std::string std::to_string(long long);

The first question - why there is only 3 functions? What about simple int or unsigned int, etc.?

The second question - why to_string doesn't throw exception in following code?

long double x = std::numeric_limits<long double>::quiet_NaN();
std::string i = std::to_string( x ); 
long double c = std::stold( i ); // i = "1.#QNAN"

And the third question - why c equals 1.0 ?

Upvotes: 6

Views: 724

Answers (2)

Filip Ros&#233;en
Filip Ros&#233;en

Reputation: 63862

  • "As long as it yields the behavior described, do what you please.."

    All intrinsic numeric types can implicitly be converted to either unsigned long long, long double or long long and still hold the precision required, therefore no more overloads are necessary.

    The standard says that the following functions should be defined, though a lib confirming to the standard is free to do "whatever it wants" as long as it yields the same behavior as described.


  • Why should it throw an exception?

    std::numeric_limits<long double>::quiet_NaN(); is a valid value, and std::to_string (T) is described in the standard to yield the same behavior as calling sprintf with the appropriate format-string.

§ 21.5/6                   Numeric conversions

  • 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);

    ..

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.

  • On what compiler is c equal to 1.0?

    The conversion should yield a NaN-value if the value of i is string representation of NaN (not containing any digits).

    If no suitable conversion can be found the function is described to throw invalid_argument.

    MSVC will yield 1.#QNAN when trying to convert std::numeric_limits<long double>::quiet_NaN(); to a std::string.

    When using std::stold it will look for the first none whitespace character, and then use as many digits as found (in this case only 1), therefore c will be equal to 1.0 after the function call.

Upvotes: 5

Bo Persson
Bo Persson

Reputation: 92331

I find the whole package in my copy of the standard:

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);

Perhaps your compiler just hasn't implemented all of them yet?

The functionality is described as

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.

As it is supposed to be a wrapper around sprintf it was probably decided not to throw any exceptions, as sprintf does not.

Upvotes: 1

Related Questions