在二进制浮点中可以表示哪些类型的数字?

时间:2012-08-25 19:21:31

标签: math language-agnostic floating-point

我已经阅读了很多关于花车的内容,但这些都是不必要的。我想想我已经理解了它,但我只想知道一件事:

我知道,1/pow(2,n)形式的分数,n一个整数,可以用浮点数精确表示。这意味着,如果我将1/32添加到自身3200万次,我会得到1,000,000

1/(32+16)之类的内容怎么样?它是两个两个幂之和的一个,这有用吗?或者1/32+1/16是否有效?这是我很困惑的地方,所以如果有人能为我澄清这一点,我会很感激。

4 个答案:

答案 0 :(得分:28)

规则可以概括为:

  • 如果分母的素数因子化仅包含2,则数字可以精确地用二进制表示。(即分母是2的幂)

所以1/(32 + 16)在二进制中不可表示,因为它在分母中的因子为3。但1/32 + 1/16 = 3/32是。

也就是说,在浮点类型中可以表示更多限制。例如,您在IEEE double中只有53位尾数,因此1/2 + 1/2^500无法表示。

所以只要指数的范围不超过53次,你就可以得到两个幂的总和。


将此概括为其他基础:

  • 如果分母的素数因子化只包含2和5,则数字可以在基数10中精确表示。

  • 如果X的分母的素数因子化仅包含{{1}的因子分解中找到的素数,则有理数N可以在基数X中准确表示}。

答案 1 :(得分:10)

有限数可以用通用的IEEE 754双精度格式表示,当且仅当它等于M•2 e 对于某些整数M和e,使得-2 53 < / sup>&lt; M&lt; 2 53 和-1074≤e≤971。

对于单精度,-2 24 &lt; M&lt; 2 24 和-149≤e≤104。

对于双精度,这些是双精度格式使用52位来存储有效数字(由于隐式1通常具有53位)并使用11位来存储指数的事实的结果。 11位编码从0到2047的数字,但0和2047被排除用于特殊目的,并且编码的数字偏向1023,因此它表示从-1022到1023的无偏指数。但是,这些无偏指数用于区间中的有效数字[1,2],这些有效数字有分数。为了将有效数表示为整数,我将指数范围调整为52.单精度类似,23位用于存储24位有效数,8位用于指数,偏差为127.

使用2的幂的整数倍表示可表示的数字而不是更常见的分数有效数,简化了一些数论和其他关于浮点属性的推理。我在这个答案中使用了它,因为它允许简洁地表达一组可表示的值。

答案 2 :(得分:4)

浮点数用字面表示:

1.m * 2^e

其中1.m是二进制分数,e是正整数或负整数。

因此,您可以完全代表1/32 + 1/16,如下:

1.1000000 * 2^-4

1.10是相当于1.5的二进制分数。)1/48但是,此格式无法表示。

答案 3 :(得分:0)

尚未提及的一点是,在语义上,浮点数最好被视为表示一系列值。值范围具有非常精确定义的中心点,并且IEEE规范通常要求浮点计算的结果是其范围包含将在原始数字的中心点上操作的点的数字,但按顺序:

  double N1 = 0.1;
  float  N2 = (float)N1;
  double N3 = N2;

N2是在N1中表示的值的明确正确的单精度表示,尽管语言愚蠢地要求使用显式强制转换。 N3将表示N2可以表示的值之一(语言规范恰好选择范围以double范围的中间为中心的float值。请注意,虽然N2表示其类型的值,其范围包含正确的值,但N3不包含。

顺便说一下,在.net和.net语言中将数字从字符串转换为float似乎会经历中间转换为double,这有时会改变该值。例如,即使值13571357可表示为单精度浮点数,值13571357.499999999069f也会舍入为13571358(即使它显然更接近13571357)。