IEEE 754-2019标准下除以10的幂是否保证浮点运算结果精确?
回答
IEEE 754-2019 标准从未对“除以10的幂的浮点运算必然返回精确值”做出通用保证,你观察到的两个运算结果差异,是浮点操作数可表示性、舍入规则共同作用的结果,和“除以10的幂”这个操作本身没有绑定的特殊准确性规则。
标准层面的核心规则
- IEEE 754 对所有基本算术运算(加、减、乘、除、平方根、融合乘加等)的统一准确性要求为:运算返回值必须等于对应数学精确结果,按照当前生效的舍入模式,舍入到当前浮点格式下最接近的可表示值。标准没有为“除以10的整数次幂”这类场景设置任何特殊的精确计算条款,也没有要求这类运算绕过通用舍入规则。
- 绝大多数场景下默认使用的是二进制浮点格式(binary32对应单精度float、binary64对应双精度double),这类格式的基数为2,所有分母不是2的整数次幂的分数都无法被精确表示。你代码中写入的字面量
0.0001(即10^-4)本身就是无限循环二进制小数,在被解析为浮点值的阶段就已经完成了第一次舍入,存储的并不是数学上精确的万分之一。你得到的9 * 0.0001 = 0.0009000000000000001,是第一次对0.0001舍入、第二次对乘积结果舍入的累积误差导致的。 - 你观察到的
9 / 10000 = 0.0009只是巧合:10000是整数,在双精度浮点格式下可以被精确表示,9除以这个精确值得到的数学结果,经过一次舍入后刚好落在了距离0.0009最近的可表示浮点数上。注意这个返回值本身也不是数学上精确的0.0009——0.0009同样是无限循环二进制小数,你看到的规整显示值只是输出阶段做了截断处理。
反例验证
只需要更换参数就能打破这个巧合,在通用双精度浮点环境下执行以下运算:
1 / 10的实际存储值约为0.100000000000000005551 / 1000的实际存储值约为0.0010000000000000000208
这两个都是典型的除以10的正整数次幂的运算,返回值都不是精确的数学结果,完全符合IEEE 754的通用运算规则。
补充:IEEE 754-2019 确实定义了十进制浮点格式(decimal32/decimal64/decimal128),这类格式基数为10,在指数范围允许的前提下,除以10的幂确实可以得到精确值,但这是十进制格式本身的基数特性决定的,并非标准为这类运算提供了特殊准确性保证,绝大多数编程语言默认使用的二进制浮点格式不具备这个特性。
内容的提问来源于stack exchange,提问作者Andrii Biletskyi
相关产品推荐
相关产品推荐

