为何循环小数乘法获精确结果?(1/3)*3为何等于1.000...而非0.999...?
关于循环小数乘法与浮点数计算的疑问解答
嘿,咱们结合你贴的Java代码和运行结果,来拆解你这两个问题:
问题1:此类循环小数乘法为何能得到精确结果?
首先得搞清楚:Java里的double类型遵循IEEE 754双精度浮点数标准,它没办法精确表示像1/3这样的无限循环十进制小数——存储的其实是一个和0.(3)非常接近的二进制近似值。
但为什么这个近似值乘以3之后能得到精确的1.0呢?说白了,这个近似值的误差在乘以3之后刚好被抵消了,或者说这个近似值×3的结果,刚好落在了double能精确表示的数值范围内。你可以理解成:虽然1/3存的不是精确值,但这个“不精确”的数,在和3相乘时,计算结果刚好就是double里1.0的二进制表示,所以输出时就显示成了精确值。
问题2:为何(1 / 3) * 3 = 1.00000000000000000000,是否是从0.999...四舍五入而来?
答案是不是四舍五入,而且得先明确一个数学事实:0.999...(无限循环)本来就等于1,这是数学上的定论。
回到浮点数计算的层面:1/3的double近似值,在和3相乘时,IEEE 754的运算规则会直接得到精确的1.0,而不是先算出一个接近0.999...的数再四舍五入。因为这个近似值的二进制表示,乘以3的二进制表示后,结果刚好能被double精确存储为1.0,所以输出的时候就是全零的小数位,没有四舍五入的过程。
你的测试代码
public static void main(String[] args) { double numerator = 1.0; double denominator = 3.0; double result = numerator / denominator; System.out.printf("1 / 3 = %f \n", result); double multiplied = result * 3; System.out.printf("3 * (1/3) = %.20f \n", multiplied); System.out.format("%.14f", 1.0/3.0 * 3); }
运行结果
1 / 3 = 0.333333
3 * (1/3) = 1.00000000000000000000
1.00000000000000
内容的提问来源于stack exchange,提问作者el_pup_le
相关产品推荐
相关产品推荐

