java计算的意外结果

Mar*_*k W 4 java

为什么以下代码:

System.out.println((int)(19.99 * 100));

产生结果"1998"?

Mic*_*rry 9

舍入错误.如果你在没有演员表的情况下查看计算结果,你会得到:

1998.9999999999998
Run Code Online (Sandbox Code Playgroud)

因此当你转换为int时,小数部分被删除,而不是向上舍入,你得到1998.

道德是,如果你需要一个确切的答案,不要使用float/double.如果你在谈论像钱这样的离散值,请使用int并处理原子单位(例如便士).如果你确实需要精确的小数,那么BigDecimal你的朋友就是.

虽然您可以使用结果Math.round()将结果提交到预期的位置,但这并不适用于所有情况并且无法解决根本问题.


Pet*_*rey 5

那是因为19.99无法准确表示.

System.out.println(new BigDecimal(19.99));
Run Code Online (Sandbox Code Playgroud)

打印实际代表的值,它最接近19.99.

19.989999999999998436805981327779591083526611328125
Run Code Online (Sandbox Code Playgroud)

并且19.99 * 100

System.out.println(new BigDecimal(19.99 * 100));
Run Code Online (Sandbox Code Playgroud)

是的

1998.999999999999772626324556767940521240234375
Run Code Online (Sandbox Code Playgroud)

问题是你在19.99中有一个表示错误,当它乘以100时仍然存在,你会得到一个稍微过小的数字.

如果你乘以100并向下舍入,那么(int)你应该期望得到1998年.

另一种选择是

System.out.println(Math.round(19.99 * 100));
Run Code Online (Sandbox Code Playgroud)

  • 虽然这是事实,但这个理由并不能解释1998年的回归,19.99*100是1999年. (5认同)