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

问题描述 投票:0回答:4

我读过很多关于浮动的内容,但都是不必要的。我认为我已经基本理解了,但只有一件事我想确定:

我知道,

1/pow(2,n)
形式的分数(其中
n
是整数)可以精确地用浮点数表示。这意味着,如果我将
1/32
与自身相加 3200 万次,我将准确地得到
1,000,000

1/(32+16)
这样的东西怎么样?它是 2 的 2 次方之和的 1,这有效吗?还是
1/32+1/16
有效?这就是我感到困惑的地方,所以如果有人能为我澄清这一点,我将不胜感激。

math language-agnostic floating-point
4个回答
35
投票

规则可以总结为:

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

所以

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

也就是说,用浮点类型表示有更多限制。例如,IEEE

double
中只有 53 位尾数,因此
1/2 + 1/2^500
无法表示。

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


将此推广到其他基础:

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

  • 如果

    X
    分母的素数分解仅包含
    N
    分解中找到的素数,则有理数
    X
    可以精确地用底数
    N
    表示。


10
投票

有限数可以用通用 IEEE 754 双精度格式表示当且仅当对于某些整数 M 和 e 来说它等于 M•2e,使得 -253 < M < 253 和 -1074 ≤ e ≤ 971.

对于单精度,-224 < M < 224 和 -149 ≤ e ≤ 104。

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

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


4
投票

浮点数的字面意思是使用以下形式表示:

1.m * 2^e

其中

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

因此,您可以准确地将

1/32 + 1/16
表示为:

1.1000000 * 2^-4

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


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)。

© www.soinside.com 2019 - 2024. All rights reserved.