在16位,32位和64位IEEE-754系统中可以表示哪些数字?

时间:2009-05-16 14:37:42

标签: floating-point precision numerical ieee-754

我对浮点数的表示有一点了解,但还不够,我担心。

一般问题是:

  

对于给定的精度(对于我的目的,基数10中的精确小数位数),可以为16位,32位和64位IEEE-754系统表示什么范围的数字?

具体来说,我只对16位和32位数字的范围感兴趣,精确到+/- 0.5(那些位置)或+/- 0.0005(千分位数)。

7 个答案:

答案 0 :(得分:93)

我从MATLAB文档中为函数EPS绘制了这个答案,但它应该普遍应用于IEEE-754浮点数。

对于给定的浮点数 X ,如果

2^E <= abs(X) < 2^(E+1)

然后从 X 到下一个最大可表示浮点数( epsilon )的距离为:

epsilon = 2^(E-52)    % For a 64-bit float (double precision)
epsilon = 2^(E-23)    % For a 32-bit float (single precision)
epsilon = 2^(E-10)    % For a 16-bit float (half precision)

上述等式允许我们计算以下内容:

  • 适用于half precision ...

    如果您想要+/- 0.5(或2 ^ -1)的精度,则该数字的最大大小为2 ^ 10。大于此值且浮点数之间的距离大于0.5。

    如果您希望精度为+/- 0.0005(约2 ^ -11),则该数字的最大大小为1.任何大于此值且浮点数之间的距离大于0.0005。

  • 适用于single precision ...

    如果您想要+/- 0.5(或2 ^ -1)的精度,则该数字的最大大小为2 ^ 23。大于此值且浮点数之间的距离大于0.5。

    如果您想要+/- 0.0005(约2 ^ -11)的精度,则该数字的最大大小为2 ^ 13。大于此值且浮点数之间的距离大于0.0005。

  • 适用于double precision ...

    如果您想要+/- 0.5(或2 ^ -1)的精度,则该数字的最大大小为2 ^ 52。大于此值且浮点数之间的距离大于0.5。

    如果您想要+/- 0.0005(约2 ^ -11)的精度,则该数字的最大大小为2 ^ 42。大于此值且浮点数之间的距离大于0.0005。

答案 1 :(得分:21)

对于浮点整数(我将根据IEEE双精度给出我的答案),1到2 ^ 53之间的每个整数都是完全可表示的。超过2 ^ 53,可精确表示的整数通过增加2的幂来间隔开。例如:

  • 2 ^ 53 + 2和2 ^ 54之间的每个第2个整数都可以准确表示。
  • 2 ^ 54 + 4和2 ^ 55之间的每4个整数都可以准确表示。
  • 2 ^ 55 + 8和2 ^ 56之间的每第8个整数都可以准确表示。
  • 可以准确表示2 ^ 56 + 16和2 ^ 57之间的每个第16个整数。
  • 2 ^ 57 + 32和2 ^ 58之间的每32个整数都可以准确表示。
  • 可以准确表示2 ^ 58 + 64和2 ^ 59之间的每个第64个整数。
  • 2 ^ 59 + 128和2 ^ 60之间的每个第128个整数都可以准确表示。
  • 可以准确表示2 ^ 60 + 256和2 ^ 61之间的每256个整数。
  • 可以精确表示2 ^ 61 + 512和2 ^ 62之间的每个第512个整数。 。 。

不完全可表示的整数被舍入到最接近的可表示整数,因此最坏情况舍入是可表示整数之间间距的1/2。

答案 2 :(得分:17)

精确引用形式Peter R与MSDN ref的链接可能是一个很好的经验法则,但当然现实更复杂。

“浮点”中的“点”是二进制点而不是小数点的事实有一种方法可以打败我们的直觉。典型的例子是0.1,它需要十进制中只有一位数的精度,但根本不能用二进制表示。

如果你有一个周末要杀人,请看看What Every Computer Scientist Should Know About Floating-Point Arithmetic。您可能对PrecisionBinary to Decimal Conversion上的部分特别感兴趣。

答案 3 :(得分:4)

首先,IEEE-754-2008和-1985都没有16位浮点数;但它是一个具有5位指数和10位分数的建议加法。 IEE-754使用专用符号位,因此正负范围是相同的。此外,该分数在前面有一个隐含的1,所以你得到一个额外的位。

如果你想要精确到某个地方,就像你可以表示每个整数一样,答案很简单:指数将小数点移动到分数的右端。因此,10位分数可以得到±2 11

如果你想要小数点后面的一位,你先放弃一位,所以你有±2 10

单精度具有23位分数,因此你有±2 24 整数。

小数点后需要多少精度位完全取决于你正在进行的计算,以及你正在做多少。

  • 2 10 = 1,024
  • 2 11 = 2,048
  • 2 23 = 8,388,608
  • 2 24 = 16,777,216
  • 2 53 = 9,007,199,254,740,992(双精度)
  • 2 113 = 10,384,593,717,069,655,257,060,992,658,440,192(四精度)

另见

答案 4 :(得分:2)

请参阅IEEE 754-1985

v = (-1)^sign * s^(exponent-exponent_bias) * (1 + fraction)

注意(1 +分数)。正如@bendin指出的那样,使用二进制浮点数,你不能表达简单的十进制值,如0.1。这意味着您可以通过多次简单添加或调用截断等操作来引入舍入错误。如果您对任何类型的精度感兴趣,实现它的唯一方法是使用定点十进制,它基本上是一个缩放的整数。

答案 5 :(得分:0)

如果我理解你的问题,这取决于你的语言 对于C#,请查看the MSDN ref。 Float具有7位精度和15-16位精度。

答案 6 :(得分:0)

我花了很长时间才弄清楚在Java中使用双打时,我的计算精度并没有下降。浮点实际上具有非常好的能力来表示数字到相当合理的精度。我失去的精度是在将用户输入的十进制数字转换为本机支持的二进制浮点表示后立即丢失的。我最近开始将所有数字转换为BigDecimal。 BigDecimal在代码中处理的工作比浮点数或双精度要多得多,因为它不是原始类型之一。但另一方面,我将能够准确地表示用户输入的数字。