5 ms·
> It is misleading to print more decimal digits out of a double than DBL_DIG If you want round-trip conversion for all `double` numbers, i.e. from `double` to
by mortehu 11y ago
> It is misleading to print more decimal digits out of a double than DBL_DIG
If you want round-trip conversion for all `double` numbers, i.e. from `double` to text and back, you need 17 digits of precision (%.17g).
Likewise, if you want round-trip conversion for all `float` number, you need 9 digits (%.9g).
The reason for this is that even though these types can really only reliably give 15 and 6 digits of precision, some of the numbers they can represent are closer to each other than that.
In C++, you can get the former limit using std::numeric_limits<double>::digits10, and the latter using std::numeric_limits<double>::max_digits10.
http://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10 http://en.cppreference.com/w/cpp/types/numeric_limits/max_di...
- kazinator 11y ago> If you want round-trip conversion for all `double` numbers, i.e. from `double` to text and back I don't. Rather, I want round-trip conversion of all 15-digit-precision decimal numbers to the machine and back. If the machine calculates some numbers which are different from some of these but alias to them textually, I don't care. Someone else might want the decimal text representation to provide bit-exact storage semantics for arbitrary doubles. For that reason it might be a better design choice to obtain the default printing precision from a special variable, which itself defaults to 15, rather than a hard-coded default.
- deleted 11y ago[deleted]
- mortehu 11y agoIf you want that, that comes at the cost of printing 0.99999999999999989 as "1".
- kazinator 11y agoWell, yes; 0.99999999999999989 isn't a 15 digit number, so it lies outside of the requirement.
- thedufer 11y agoThe downside to printing only 15 is that you then have numbers that print the same but compare as not equal.
- kazinator 11y ago> In C++, you can get the former limit using std::numeric_limits<double>::digits10, and the latter using std::numeric_limits<double>::max_digits10. Also, via GCC specific constants: $ echo | gcc -E -dM - | grep -E '(FLT|DBL).*DIG' #define __DBL_DIG__ 15 #define __FLT_MANT_DIG__ 24 #define __LDBL_MANT_DIG__ 64 #define __FLT_DIG__ 6 #define __DBL_MANT_DIG__ 53 #define __DBL_DECIMAL_DIG__ 17 #define __LDBL_DIG__ 18 #define __FLT_DECIMAL_DIG__ 9 __DBL_DIG__ versus __DBL_DECIMAL_DIG__. Useful to know. __DBL_DECIMAL_DIG__ corresponds to DBL_DECIMAL_DIG which was added to C in C11. In C90 or C99 we can do some hack like: #if DBL_DECIMAL_DIG use this #elif __DBL_DECIMAL_DIG__ use this from gcc. #else fall back on DBL_DIG + 2 #endif