CppLearner
CppLearner

Reputation: 17040

long double vs double

I know that size of various data types can change depending on which system I am on.

I use XP 32bits, and using the sizeof() operator in C++, it seems like long double is 12 bytes, and double is 8.

However, most major sources states that long double is 8 bytes, and the range is therefore the same as a double.

How come I have 12 bytes? If long double is indeed 12 bytes, doesn't this extends the range of value also? Or the long signature is only used (the compiler figures) when the value exceed the range of a double, and thus, extends beyond 8 bytes?

Upvotes: 86

Views: 88596

Answers (4)

Kai Petzke
Kai Petzke

Reputation: 2984

long double on X86 compilers increases the mantissa only slightly from 52 bit to 64 bit, so it gives around 3.5 extra decimal digits of precision. The exponent size also increases from 11 to 15 bit, so long double uses 80 bit in total including the sign bit. Due to 2 byte (on 32 bit systems) or even 6 byte (on 64 bit systems) of padding, the actual size of a long double in memory is 12 or even 16 bytes, though.

But don't let the large value of sizeof(long double) trick you into believing, that you get a lot of precision, if in reality, you just get a lot of padding on X86! You can always query the guaranteed precision on your platform via:

std::cout << "precision: " << std::numeric_limits<long double>.digits10() << std::endl;

The reason behind that long double is an 80-bit-type on X86 is, that the legacy X87 numeric coprocessor used that format internally. So long double made the full precision of the coprocessor available to C applications.

If you need higher floating point precision, the latest C++ standard C++23 will be to your rescue. In the #include <stdfloat> header, you will find the new type std::float128_t. Unfortunately, your compiler is not obliged to support it, though. As of writing this answer, only GCC and MSVC seem to have added support for std::float128_t. The other major compilers will hopefully follow in the next few years, though.

If you cannot switch to C++23 yet or need one of the compilers, that don't support 128-Bit-Floating-point, yet, then using 128 bit floats as a C type, not C++ type, might be an alternative. A good starting point can be found in this article: https://cpufun.substack.com/p/portable-support-for-128b-floats

Upvotes: 0

Shital Shah
Shital Shah

Reputation: 68878

For modern compilers on x64, Clang and GCC uses 16-byte double for long double while VC++ uses 8-byte double. In other words, with Clang and GCC you get higher precision double but for VC++ long double is same as double. The modern x86 CPUs do support these 16-byte doubles so I think Clang and GCC are doing the right thing and allows you to access lower level hardware capability using higher level language primitives.

Upvotes: 21

Borealid
Borealid

Reputation: 98559

Quoting from Wikipedia:

On the x86 architecture, most compilers implement long double as the 80-bit extended precision type supported by that hardware (sometimes stored as 12 or 16 bytes to maintain data structure .

and

Compilers may also use long double for a 128-bit quadruple precision format, which is currently implemented in software.

In other words, yes, a long double may be able to store a larger range of values than a double. But it's completely up to the compiler.

Upvotes: 79

scott77777
scott77777

Reputation: 718

The standard byte sizes for numbers are the guaranteed minimum sizes across all platforms. They may be larger on some systems, but they will never be smaller.

Upvotes: 5

Related Questions