Boost logo

Boost :

Subject: [boost] MS VC10 std::numeric_limits<float>::max_digits10 is wrong for float
From: Paul A. Bristow (pbristow_at_[hidden])
Date: 2011-06-06 10:45:53

Inexplicably, MS for VS 10 have chosen std::numeric_limits<float>::max_digits10 == 8 for VS 10

rather than 9, when the formula

  max_digits10 = 2 + std::numeric_limits<FPT>::digits * 3010/10000;

and values have been known for 30 years.

  std::numeric_limits<T>:: max_digits10; is 'new for C++0X'.

Briefly, max_digits10 is the number of decimal digits that you need to output to make sure that a
one least significant bit (ULP) change produces a different decimal digit string. Any more digits
are just noise with no useful information.

Using max_digits10 rather than the formula above may be more efficient, and is certainly very much

"Executive Summary"

Don't use max_digits10 for float or floating-point template types for MS VS - yet!

You can safely (and very usefully) use


when you want to be sure that all significant decimal digits are output.

GCC provides the correct values of 9 for float (and 17 for double).

The Fuller Story

This might affect anyone planning to use VS10 and this new (and very useful numeric_limits value)
with built-in *type float, or a floating-point template type*, potentially, for example, with Boost
Lexical_cast, Serialization. Round tripping would be 1 bit wrong in perhaps 1/3 of cases! If
max_digits10 was used, Boost.Test might detect values that are different, but are reported to be the
same, for example. As far as I know, none of these utilities yet try to use max_digits10.

Mercifully, this fault only affects type T = float (not the most popular double or long double), and
only in new code that uses the 'new for C++0X' numeric_limits<T>:: max_digits10. Other types like
double and long double (and possibly user defined types that specialize numeric_limits) are, I
believe, correct.

So you can safely (and very usefully) use


when you want to be sure that all significant decimal digits are output.

(If you want this to be 'Boost portable' you will have to use the inscrutably named


as a proxy for "C++0x numeric_limits before using new-for-C++0X max_digits10. Unless we add yet
another macro for max_digits10? Groan.).

The workaround is to continue to use the well-tried and test Kahan formula

  max_digits10 = 2 + std::numeric_limits<FPT>::digits * 3010/10000;

Reported and confirmed as

(It might help if, you could confirm you can 'reproduce' this too).

I trust this mistake will be corrected pronto - but I'm not holding my breath :-(

I will post again if it is resolved.


Paul A. Bristow,
Prizet Farmhouse, Kendal LA8 8AB  UK
+44 1539 561830  07714330204

Boost list run by bdawes at, gregod at, cpdaniel at, john at