在Java中使用parseFloat的正确方法是什么

时间:2012-10-05 18:29:26

标签: java floating-point precision

我注意到Java浮点精度的一些问题

       Float.parseFloat("0.0065") - 0.001  // 0.0055000000134110451
       new Float("0.027") - 0.001          // 0.02600000000700354575
       Float.valueOf("0.074") - 0.001      // 0.07399999999999999999

我不仅遇到Float问题,还问Double

有人可以解释幕后发生的事情,我们怎样才能获得准确的数字?在处理这些问题时,处理这个问题的正确方法是什么?

7 个答案:

答案 0 :(得分:29)

问题很简单float具有有限的精度;它不能完全代表0.0065。 (当然,double也是如此:它具有更高的精度,但仍然是有限的。)

使上述问题更加明显的另一个问题是,0.001double而不是float,因此您的float正在升级为double执行减法操作,当然此时系统无法恢复double 所表示的缺失精度。要解决这个问题,你可以写:

float f = Float.parseFloat("0.0065") - 0.001f;

使用0.001f代替0.001

答案 1 :(得分:6)

What Every Computer Scientist Should Know About Floating-Point Arithmetic。你的结果对我来说是正确的。

如果您不喜欢浮点数的工作方式,请尝试使用BigDecimal之类的内容。

答案 2 :(得分:5)

你得到了正确的结果。完全没有这样的float 0.027,也没有这样的double。如果您使用floatdouble总是会收到这些错误。

floatdouble存储为二进制分数:类似于1/2 + 1/4 + 1/16 ......您无法获得所有小数要精确存储的值作为有限精度二进制分数。这在数学上是不可能的。

唯一的选择是使用BigDecimal,您可以使用它来获取精确的小数值。

答案 3 :(得分:4)

来自Java Tutorials page on Primitive Data Types

  

浮点字面值的类型为float,如果它以字母Ff结尾;否则其类型为double,并且可以选择以字母Dd结尾。

所以我认为你的文字(0.001)是双打的,你从浮动中减去双打。

请改为尝试:

System.out.println((0.0065F - 0.001D)); // 0.005500000134110451
System.out.println((0.0065F - 0.001F)); // 0.0055

......你会得到:

0.005500000134110451
0.0055

因此,为您的文字添加F后缀,您应该会得到更好的结果:

Float.parseFloat("0.0065") - 0.001F
new Float("0.027") - 0.001F
Float.valueOf("0.074") - 0.001F

答案 4 :(得分:3)

我会将你的float转换为字符串,然后使用BigDecimal。

This链接很好地解释了

new BigDecimal(String.valueOf(yourDoubleValue));

不要使用BigDecimal双构造函数,因为你仍会遇到错误

答案 5 :(得分:1)

如果您需要任意精度,请使用BigDecimal,不要浮动或加倍。您将使用float看到各种这种性质的舍入问题。

另外要小心不要使用BigDecimal的float / double构造函数,因为它会有同样的问题。改为使用String构造函数。

答案 6 :(得分:1)

浮点数无法准确表示十进制数。如果您需要在Java中准确表示数字,则应使用java.math.BigDecimal类:

BigDecimal d = new BigDecimal("0.0065");