十进制数和精确表示

时间:2012-01-30 17:57:19

标签: c++ floating-point double

在c ++中,如何使用IEEE 754-1985标准知道十进制数何时可以准确表示。 例如0.2不能完全代表。

有一个简单的规则吗?

3 个答案:

答案 0 :(得分:6)

如果数字可以写成 B ×2 n ,那么数字可以完全表示为IEEE755浮点数,其中 B 是一个整数( B n 属于某个有效范围)。换句话说,必须有一些整数 n ,这样如果你的数字超过2 n ,你会得到一个整数。显然,对于1/5,没有这样的 n

另一种说法是,你的数字必须是两个有限多个幂的总和,它们相距不太远(幂之间的最大距离是浮子的精度)。

另一种说法非常宽松的方式是“分母为2的幂的有理数”是可以表示的(虽然具有明显的精度约束)。

浮点数的精度,即 B 的宽度,单个为24位,双精度为53位,扩展双精度为64位。

答案 1 :(得分:5)

是的,有一个简单的规则。如果小数部分不能用某个数字n表示超过2的幂,则无法准确表示 - 它将无限重复。否则,只要表示符合可用的位数,它就是精确的。

所以例如0.75有效,因为它是3/4。没有办法使0.2工作,因为它是1/5并且没有什么可以调整它使分子的功率为2。

无法精确表示这么多十进制数的原因是十进制数在分母中的组合为2和5。如果您可以简化分数以删除所有5个,则只能获得精确的表示。

再举一个例子,考虑0.625。作为一个分数,它是625/1000,但它简化到5/8。简化形式底部的功率为2,因此它将是精确的。

一个有趣的副作用是所有可精确表示的小数以“5”结尾。如果没有,那么你可以很快地告诉它不准确。

答案 2 :(得分:1)

  

有一个简单的规则吗?

经验:转换并转换回来,如果你得到相同的数字,那么它就是可以代表的。

理论:IEEE-754使用符号位,M个尾数位和E指数位(64-bit double,M = 52,E = 11,32-bit float,M = 23,E = 8) ,表示为(+/- 1)*(1 +(m / 2 ^ M))*(2 ^(e-(2 ^(E-1)-1))),对于m =无符号M位尾数,e =无符号E位指数。如果您的号码可以用这种方式表示,那么它就是可以表示的。 (对于适合浮点数位空间的更小的指数,也有subnormal numbers

以上的英文翻译是,如果您的数字X可以写为0或(+/- 1)*非负奇数m'乘以2的幂2 ^(e')则X 可能可以代表;确保你必须检查m'和e'是否适合它们各自的位空间:

m'= 2k + 1,k <1。 2 ^ M

e'=一个指数范围,我对我的代数没有足够的信心来确保我是对的。对于双精度数字,在+/- 900范围内的任何地方都可以,但如果指数超过900,那么你需要小心,并且真的应该更仔细地看待比特实际表示的方式。