长双 vs 双

发布于 2024-09-13 23:31:25 字数 339 浏览 8 评论 0原文

我知道各种数据类型的大小可能会根据我所在的系统而变化。

我使用XP 32位,并在C++中使用sizeof()运算符,看起来long double是12个字节,而double是8个字节。

然而,大多数主要来源都指出,long double 是 8 个字节,因此范围与 double 相同。

我怎么有12个字节?如果long double确实是12字节,这不是也扩展了值的范围吗?或者只有当值超出 double 的范围并因此超出 8 个字节时才使用长签名(编译器计算)?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

失去的东西太少 2024-09-20 23:31:27

对于 x64 上的现代编译器,Clang 和 GCC 使用 16 字节双精度作为 long double,而 VC++ 使用 8 字节双精度。换句话说,使用 Clang 和 GCC,您可以获得更高精度的 double,但对于 VC++,long doubledouble 相同。现代 x86 CPU 确实支持这些 16 字节双精度,因此我认为 Clang 和 GCC 正在做正确的事情,并允许您使用高级语言原语访问较低级别的硬件功能。

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.

太阳公公是暖光 2024-09-20 23:31:27

数字的标准字节大小是所有平台上保证的最小大小。它们在某些系统上可能更大,但永远不会更小。

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.

回心转意 2024-09-20 23:31:27

X86 编译器上的 long double 仅将尾数从 52 位略微增加到 64 位,因此它提供了大约 3.5 个额外的十进制数字的精度。指数大小也从 11 位增加到 15 位,因此 long double 总共使用 80 位(包括符号位)。不过,由于 2 字节(在 32 位系统上)甚至 6 字节(在 64 位系统上)的填充,内存中 long double 的实际大小为 12 甚至 16 字节。

但不要让 sizeof(long double) 的大值欺骗您,让您相信您获得了很高的精度,如果实际上,您只是在 X86 上获得了很多填充!您始终可以通过以下方式查询平台上保证的精度:

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

long double 在 X86 上是 80 位类型的原因是,旧版 X87 数字协处理器在内部使用该格式。因此,long double 使协处理器的全部精度可供 C 应用程序使用。

如果您需要更高的浮点精度,最新的 C++ 标准 C++23 将助您一臂之力。在 #include 标头中,您将找到新类型 std::float128_t。不幸的是,您的编译器没有义务支持它。在撰写此答案时,似乎只有 GCC 和 MSVC 添加了对 std::float128_t 的支持。不过,其他主要编译器有望在未来几年内跟进。

如果您还无法切换到 C++23 或者需要其中一个不支持 128 位浮点的编译器,那么使用 128 位浮点数作为 C 类型而不是 C++ 类型可能是一种替代方法。可以在本文中找到一个很好的起点: https://cpufun .substack.com/p/portable-support-for-128b-floats

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

暖风昔人 2024-09-20 23:31:26

引用自维基百科

在 x86 架构上,大多数编译器实现 long double 作为该硬件支持的 80 位扩展精度类型(有时存储为 12 或 16 字节以维护数据结构。

编译器还可以使用 long double 来实现 128 位四倍精度格式,目前已在软件中实现。

换句话说,是的,long double可能能够比double存储更大范围的值。但这完全取决于编译器。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文