C++ 一些浮点精度和数字极限问题

C++ 一些浮点精度和数字极限问题,c++,floating-point,limit,C++,Floating Point,Limit,我知道有很多像这样的问题,但我找不到答案。请在投票结束前阅读(: 根据: 这些是巨大的数字,你不能将它们存储到8B甚至16B(这是扩展精度,只有128位) 显然,我遗漏了一些东西。实际上,很明显,有很多东西。FPU使用的空间大小和内存中用于表示double的空间量是两个不同的东西。IEEE 754(可能是大多数架构使用的)指定32位单精度和64位双精度数字,这就是为什么sizeof(double)提供8字节。英特尔x86内部使用80位进行浮点运算 std::numeric\u limits:

我知道有很多像这样的问题,但我找不到答案。请在投票结束前阅读(:

  • 根据:
这些是巨大的数字,你不能将它们存储到8B甚至16B(这是扩展精度,只有128位)


显然,我遗漏了一些东西。实际上,很明显,有很多东西。

FPU使用的空间大小和内存中用于表示
double
的空间量是两个不同的东西。IEEE 754(可能是大多数架构使用的)指定32位单精度和64位双精度数字,这就是为什么
sizeof(double)
提供8字节。英特尔x86内部使用80位进行浮点运算

std::numeric\u limits::max()
long double
提供了正确的大小,通常为80位。如果希望64位double的最大大小,则应将其用作模板参数

对于关于范围的问题,为什么你认为不能将它们存储在8字节中?它们实际上是合适的,你缺少的是在范围的极端有一些无法表示的数字(例如接近308的指数,有许多整数根本无法表示)

有关浮点的信息,请参见。

1)
sizeof
是内存中的大小,而不是寄存器中的大小
sizeof
以字节为单位,因此8字节=64位。当在内存中计算double(在此架构上)时,它们会得到额外的16位,以便进行更精确的中间计算。当值被复制回内存时,额外的16位丢失

2) 你为什么认为长双精度
不能达到1.18973e+4932

3) 为什么不能将10^308存储在8字节中?我只需要13位:4位存储10位,9位存储308位

  • 双精度
  • 不是英特尔协处理器80位浮点,而是IEEE 754 64位浮点。使用sizeof(double),您将获得后者的大小

  • 这是获取长双精度最大值的正确方法,因此您的问题毫无意义

  • 您可能忽略了浮点数不是精确的数字。10^308不能存储308位数字,只能存储大约19位数字


  • 计算机上的浮点数根据IEEE 754-2008表示

    它定义了几种格式,其中
    binary32=单精度,
    binary64=双精度和
    binary128=四倍精度是最常见的。

    双精度数字的数字为52位,表示精度,指数为10位,表示数字的大小。
    所以双精度是1.xxx(52位二进制数字)*2^指数(10位二进制数字,最多2^10=1024)

    和2^1024=1,79*10^308
    这就是为什么这是一个双精度存储中可以存储的最大值

    当使用四倍精度数字时,它们的精度为112位,指数为14位,因此最大指数为16384


    2,16384给出1,18*10 ^ 4932,你看到你的C++测试是完全正确的,在x64上你的双实际上是以四倍精度的数字存储的。

    时间,读“每个计算机科学家应该知道关于浮点算术”,只有<代码> STD::数字限制< /代码>是C++,不适用于C。其他东西对这两种语言都是一样的-谈论
    浮点
    双精度
    长双精度
    ,对吗? The numeric coprocessor has eight floating point registers. Each register holds 80 bits of data. Floating point numbers are always stored as 80-bit extended precision numbers in these registers. Double precision magnitudes can range from approximately 10^−308 to 10^308