System.out.println(2.14656);
2.14656
System.out.println(2.14656%2);
0.14656000000000002
怎么回事?
System.out.println(2.14656);
2.14656
System.out.println(2.14656%2);
0.14656000000000002
怎么回事?
确实给出了预期的结果。你的期望是不正确的。
当您键入双精度字面2.14656
量时,您实际得到的是最接近的双精度值,即:
2.14656000000000002359001882723532617092132568359375
当它打印出来(到 17 位有效数字)时,println
碰巧将它四舍五入,所以你会看到你期望的不错的值。
模运算后(准确),值为:
0.14656000000000002359001882723532617092132568359375
再一次,它在打印时是四舍五入的,但是因为前导数字少了一位,所以舍入点向右更远一位数字,所以你会看到尾随2
.
以 2 为底的系统用于存储以 10 为底的任意精度数。
使用整数二进制时,“整数”是 2、4、8、16、32、64 等。您会注意到,这些数字都不是 10、100、1000、10000 或任何会被视为“以 10 为基数的“舍入”数字。
浮点和双精度值是为 CPU 内的快速操作而构建的。即使您将 1.42E-13 除以 2.11E47,也可以快速完成多个数字之间的数学运算。它们的构造不是为了提供以 10 为底的“四舍五入”数字。这是该决定的副作用。
使用浮点数时,您必须接受这种情况会发生。它不是 100% 准确的,但在其他方面它是准确的。所以你永远不应该在需要 100% 精度的地方使用浮点变量。在需要这样做的地方,找到一种方法将其存储在 int 值中。这也是一个好主意,您确实使用浮点数,将输出四舍五入到小数位,以避免像您那样偶尔显示。
例如,我在金融行业工作,我们将市场价格表示为刻度数而不是实际价格。当我们需要显示价格时,我们将该值乘以刻度大小、1/100、1/32 或 1/20 等,然后四舍五入到适当的小数位数。刻度的数量,刻度大小的分子和分母,都以整数形式存储在我们的数据库中。除了移动平均线等计算值外,我们实际上不存储任何浮点值。