简体   繁体   English

java计算的意外结果

[英]Unexpected result of java calculation

Why does the following code: 为什么以下代码:

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

produce the result "1998"? 产生结果“1998”?

Rounding errors. 舍入错误。 If you look at the result of your calculation without the cast, you get: 如果你在没有演员表的情况下查看计算结果,你会得到:

1998.9999999999998

So when you cast to int, the decimal part is dropped, not rounded up, and you get 1998. 因此当你转换为int时,小数部分被删除,而不是向上舍入,你得到1998。

The moral is, if you need an exact answer, don't use float / double at all. 道德是,如果你需要一个确切的答案,不要使用float / double。 If you're talking about a discrete value like money, use int and deal with the atomic unit (eg. pence.) If you do need exact decimals, then BigDecimal is your friend. 如果你正在谈论像money这样的离散值,请使用int并处理原子单位(例如pence。)如果你确实需要精确的小数,那么BigDecimal就是你的朋友。

While you can bodge the result here using Math.round() to bring the result to where it's expected, this won't work in all cases and fails to address the underlying issue. 虽然你可以使用Math.round()将结果提交到预期的位置,但这并不适用于所有情况,也无法解决潜在的问题。

That is because 19.99 cannot be represented exactly. 那是因为19.99无法准确表示。

System.out.println(new BigDecimal(19.99));

prints the value this actually represents which is the closest to 19.99 it can represent. 打印实际代表的值,它最接近19.99。

19.989999999999998436805981327779591083526611328125

and 19.99 * 100 is 19.99 * 100

System.out.println(new BigDecimal(19.99 * 100));

which is 是的

1998.999999999999772626324556767940521240234375

The problem is that you have a representation error in 19.99 which is still there when multiplied by 100 you get a number which is slightly too small. 问题是你在19.99中有一个表示错误,当它乘以100时仍然存在,你会得到一个稍微过小的数字。

if you multiply by 100 and round down which is what (int) does you should expect to get 1998. 如果你乘以100并向下舍入 ,那么你应该期望获得1998年的(int)

An alternative is 另一种选择是

System.out.println(Math.round(19.99 * 100));

因为19.99 * 100的计算将导致1998.999999并且你将它转换为int它将丢弃它的小数部分。

It is due to a rounding issues. 这是由于四舍五入的问题。 double and float are prone to these issues, which is why it is recommended you use the BigDecimal class. doublefloat很容易出现这些问题,这就是为什么建议你使用BigDecimal类。

This code should print what is expected: 此代码应打印预期的内容:

BigDecimal bg = new BigDecimal("19.99");
System.out.println(bg.multiply(new BigDecimal("10")));

This yields: 这会产生:

199.90

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

通过添加int cast生成结果1998.9999999999998,它截断小数部分并返回1998

Floating point data types (float and double in Java) can only approximately represent most decimal values. 浮点数据类型(Java中的float和double)只能近似表示大多数十进制值。 See Joshua Bloch's words of wisdom on the subject for more details. 有关详细信息,请参阅Joshua Bloch关于此主题的智慧语言。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM