提问人:xdxt 提问时间:4/25/2022 最后编辑:Peter Cordesxdxt 更新时间:4/25/2022 访问量:780
为什么IEEE754双精度格式只能精确到 15 位?
Why is the IEEE754 double precision format only accurate to 15 digits?
问:
我目前正在学习浮点表示。根据本网站,以下是此表示的可能范围。-1.79E+308 至 -2.23E-308、0 和 2.23E-308 至 1.79E+308。问题是,我不太明白这个范围意味着什么。既然指数是 10^308,那么它不应该精确到 308 位吗?当然,这似乎是不对的,因为根据我的经验,浮点的准确性几乎不高。
我在这里误解了什么?将不胜感激。
答:
去读 https://en.wikipedia.org/wiki/Significant_figures - 浮点有固定数量的有效数字(精度由尾数宽度给出),但它们可以移动到指数范围内的任何幅度(指数单独编码)。
在浮点数中,它是一定数量的二进制位,因此巨大的浮点数只能表示 4、8、16、32 的倍数,并且浮点数越大,就越粗糙。
关于双精度浮点的 wiki 文章非常好。除其他事项外,它指出:
- 可以精确表示从 −2 53 到 253(−9,007,199,254,740,992 到 9,007,199,254,740,992)的整数
- 介于 253 和 254 之间的整数 = 18,014,398,509,481,984 四舍五入为 2 的倍数(偶数)
- 介于 254 和 255 之间的整数 = 36,028,797,018,963,968 四舍五入为 4 的倍数
对于像这样的大型双精度部分,没有尾数位可以对小数部分进行编码:指数场将它们全部向上移动到整数部分。只有像 1.125 这样的小数才能有小数部分。 (而且你仍然不能这样做,因为两个非零部分彼此相距太远。2^53
1.00000000000000000000000000000000001
如果你的推理有效,如果你在小数点右边包含小数部分,那么每个浮点数难道不应该能够表示无限数量的数字吗?显然没有固定的 64 位值,只有 2^64 种不同的位模式,因此问题在于如何在要表示的范围内分散这些值。
浮点选择固定数量的位数,并让小数点根据指数“浮动”到不同的位置。(实际上是二进制数字,因此不是小数点:正确的术语是以 2 为基数的基数点。除非您使用的是“十进制浮点数”格式。
例如,假设在 4 位小数位的左右两侧有无限串零,但您可以将小数点放在指数范围限制内的任何位置。
0000012340000000.0 # large integer
000001234.00000000 # small integer
000001.23400000000 # small number near 1
0.0000123400000000 # quite small number
您可以等效地考虑尾数被指数相对于小数点向左或向右移动,以创建一个可变大小的定点表示,该表示实际上具有零位来填充空间。1.234
出于说明目的,我使用十进制;只有少数 CPU 具有支持十进制指数的指令(例如某些 PowerPC)。对于二进制(以 2 为底数),基数点位于某个位置,概念相同。
我还遗漏了一些东西,例如非零指数编码隐含的二进制尾数顶部的隐式 1,以及指数实际使用偏差编码的方式。有关完整详细信息,请参阅 wiki 文章。
使用单精度浮点 https://www.h-schmidt.net/FloatConverter/IEEE754.html 也很有指导意义,它显示位模式(带有用于修改位的复选框),以及由尾数和指数字段分别表示的值,以及总体表示的实际值。
有关一些简洁的浮点内容的更高级了解,请参阅 Bruce Dawson 的系列浮点文章。比较浮点数,2012 版有指向所有 16 个浮点数的链接,例如只有 40 亿个浮点数——所以全部测试一下!
他们中的一些人专注于 x86 和 x86-64 上 C 语言中 FP 环境的实用性,另一个人指出,增加浮点数的整数位模式是如何实现的,从而增加其幅度。(指数编码中的偏差使得 FP 位模式可与符号/幅度整数相媲美,但 NAN 特殊情况除外。nextafter
评论
double