25

我读过很多关于花车的文章,但都是不必要的。我我已经很明白了,但是我只想确定一件事:

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

类似的东西1/(32+16)呢?这是二的二乘方之和的一,这行得通吗?或者它1/32+1/16有效吗?这是我感到困惑的地方,所以如果有人能为我澄清这一点,我将不胜感激。

4

4 回答 4

33

规则可以总结为:

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

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

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

因此,只要指数的范围不超过 53 次方,您就可以进行二次幂之和。


将其推广到其他基础:

  • 如果分母的素数分解仅由 2 和 5 组成,则可以以 10 为底精确表示一个数字。

  • 如果 的分母的素数因式分解仅包含在 的因式分解中找到的素数,则有理数X可以精确地表示为基数。NXN

于 2012-08-25T19:26:21.083 回答
10

当且仅当对于某些整数 M 和 e 等于 M•2 e使得 -2 53 < M < 2 53和 -1074 ≤ e ≤ 971时,有限数可以用常见的 IEEE 754 双精度格式表示。

对于单精度,-2 24 < M < 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 的幂而不是更常见的小数有效位来表示可表示的数字可以简化一些数论和其他关于浮点属性的推理。我在这个答案中使用了它,因为它允许简洁地表达一组可表示的值。

于 2012-08-25T20:08:19.467 回答
4

浮点数使用以下形式逐字表示:

1.m * 2^e

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

因此,您可以1/32 + 1/16准确地表示为:

1.1000000 * 2^-4

(1.10是相当于 1.5 的二进制小数。)1/48但是,不能以这种格式表示。

于 2012-08-25T19:27:53.417 回答
0

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

  双 N1 = 0.1;
  浮动 N2 = (浮动)N1;
  双 N3 = N2;

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

顺便说一句,在 .net 和 .net 语言中将数字从字符串转换为浮点数似乎需要经过中间转换double,这有时可能会改变值。例如,即使值 13571357 可以表示为单精度浮点数,但值 13571357.499999999069f 会四舍五入为 13571358(尽管它显然更接近 13571357)。

于 2012-08-25T20:04:36.123 回答