printf("%Lf", long double)
truncates the output to double
It clearly doesn't truncate anything. It's easy to see the result for double
and long double
are completely different and long double
are more precise than double
So there's nothing wrong with it. On x86 long double
is typically 80-bit extended precision type whose precision is around 18 digits, and 3.141592653589793238
is correct to 19 significant digits
If you need some more precision then use quadruple precision by setting the -mlong-double-128
option or use __float128
directly. Of course this is emulated by software so it'll be significantly slower than the native x87 80-bit format
Demo on Godbolt
For higher precisions you'll have to use a 3rd party arbitrary-precision floating-point library
Why is size(long double)
16 bytes?
Size has nothing to do with precision. Just like trap representations and padding bits are allowed in C++, a type's size can be wider than the real precision
In the 80-bit extended format the internal representation is 10 bytes but padding bytes are added to align the type to 4 bytes (x86) or 8 bytes (x86-64), resulting in a 16-byte type in 64-bit mode. The padding can be changed by the -m96/128bit-long-double
options in gcc
What's important here is LDBL_DIG
/LDBL_MANT_DIG
/LDBL_MAX_EXP
/LDBL_MAX_10_EXP
or std::numeric_limits<long double>::digits/digits10/max_exponent/max_exponent10
which are the real precision of the type. In fact by changing the combinations of the above -m-long-double
options you'll get many different results:
The default result is size = 16, digits10 = 18, digits2 = 64. You'll get size = 10 if you disable padding, but that'll come at a performance expense due to misalignment. See more demo on Godbolt
See
In PowerPC you can also see the same phenomena when changing the floating-point format. While the size is still 16 bytes, the precision can vary. With -mabi=ibmlongdouble
(double-double arithmetic, which is the default) you'll get (size, digits10, digits2) = (16, 31, 106) but with -mabi=ieeelongdouble
the tuple will become (16, 33, 113)