-1

I have a problem getting a correct/accurate string representation of float/double/long double values.

I have this function that attempts to get a string representation of a floating point value:

template <typename T>
std::string double_to_string(const T& v) {
  static_assert(std::is_floating_point<T>::value,
                "T is not a floating point type");
  std::stringstream sstr;
  sstr.setf(std::ios::fixed | std::ios::showpoint);
  sstr << v << std::ends;
  return sstr.str();
}

I invoke it with float, double and long double values, but do not get a correct/accurate string representation of the actual value I pass in to the function:

// float:
std::cout << double_to_string(77777777777777.7777777f) << std::endl;
// double:
std::cout << double_to_string(77777777777777.7777777) << std::endl;
// long double:
std::cout << double_to_string(77777777777777.7777777L) << std::endl;

The output I get is as below:

// float: 
77777780867072.000000

// double:
77777777777777.781250

// long double:
77777777777777.777779

Is there any way I can get an accurate string representation of float/double/long double values in C++?

(p.s. I'm using g++ 7.2.0)

Thanks.

  • Are you allowed to use external libraries? – Carl Dec 14 '18 at 09:32
  • You can't get an accurate string repesentation because the `float` and `double` can't store the value accurately. According to wikipedia, a 32 bit float has a precision of 6-9 digits (15-17 for 64 bit), and that's what we observe here. – Blaze Dec 14 '18 at 09:35
  • @Carl Yes, probably I can. Can you suggest anything please? – Adrian Mercieca Dec 14 '18 at 09:40
  • What are your requirements? In mathematics there are no "float" or "double" numbers. There are real numbers. Floats and doubles are (inexact) representations of real numbers in a computer. They need not be represented any further. One cannot represent all real numbers exactly in a computer. – n. m. could be an AI Dec 14 '18 at 09:51
  • Your question is (incorrectly) marked as a duplicate, so I cannot post a proper answer. The answer is [std::numeric_limits::digits10](https://en.cppreference.com/w/cpp/types/numeric_limits/digits10) – Kit. Dec 14 '18 at 09:53
  • They never explained why it was marked as duplicate. I read that supposed previous answer, but that doesn't solve my problem. Do you have any clues about this std::numeric_limits::digits10 thing please? – Adrian Mercieca Dec 14 '18 at 10:26
  • `std::numeric_limits::digits10` is how many digits in the string representation are safe to convert to the floating point T and back to the string resulting in the same string value. For `float`, it's 6, that's why you have 6 of `7`s in your output. For `double`, it's 15 - check again. For `long double`, it's 18 - so you are just lucky to have 19. Then, there is `std::numeric_limits::max_digits10` - it is how many digits you need to have in your string to convert from floating point to string and back and end up with the same value. It's bigger than `std::numeric_limits::digits10`. – Kit. Dec 14 '18 at 10:47
  • That's, of course, the mantissa part. For the exponent, you have `min_exponent` and `max_exponent` in the same [numeric limits](https://en.cppreference.com/w/cpp/types/numeric_limits). – Kit. Dec 14 '18 at 10:56
  • Thanks a lot for your help @Kit. – Adrian Mercieca Dec 14 '18 at 11:46

1 Answers1

3

Number 77777777777777.7777777 can not be exactly represented by floating-point number: float, double, or long double. Instead the closest representable floating-point number will be chosen. Since floating-point types have different precision float's closest number is farther than long double's.

AMA
  • 4,114
  • 18
  • 32