根据这个问题我知道
1.0 / 3.0
不能用IEEE浮点格式精确表示,而是四舍五入为略小于1/3的IEEE浮点数,尾数是被截断的部分实数,如下图:
我的问题是为什么
1.0 / 3.0 * 3.0
会产生精确的 1。我在 Lua 和 C++ 中尝试过,得到相同的结果,我认为这是 IEEE 标准定义的。结果不应该是尾数全 1 的浮点数吗,因为我认为第二次乘法运算中没有发生舍入?
因为四舍五入。在默认的“舍入到最近偶数”模式下,最终结果舍入为 @1@ 的精确值,因为它是最接近的可表示值。
您可以更改舍入模式以查看您想要的结果,如下所示:
#include <stdio.h>
#include <fenv.h>
#pragma STDC FENV_ACCESS ON
int main(void) {
double a = 1;
double b = 3;
printf("Default rounding (RNE) : %lf\n", (a/b)*b);
fesetround(FE_TOWARDZERO);
printf("Round towards zero (RTZ): %lf\n", (a/b)*b);
return 0;
};
当我运行这个程序时,我得到:
Default rounding (RNE) : 1.000000
Round towards zero (RTZ): 0.999999