繁体   English   中英

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

[英]What's the right way to parseFloat in Java

我注意到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

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

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

使上述问题更加明显的另一个问题是0.001是一个double而不是float ,所以你的float被提升为double来执行减法,当然在这一点上系统无法恢复double 可能代表的缺失精度。 为了解决这个问题,你会写:

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

使用0.001f而不是0.001

看看每个计算机科学家应该知道的关于浮点运算的内容 你的结果对我来说是正确的。

如果您不喜欢浮点数的工作方式,请尝试使用类似BigDecimal的方法

你得到了正确的结果。 没有像0.027那样的float ,也没有这样的double 如果使用floatdouble总会出现这些错误。

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

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

从“ 原始数据类型Java教程”页面

如果浮点字面值以字母Ff结尾,则浮点字面值为float类型; 否则它的类型是双倍的,它可以选择以字母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

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

这个链接解释得很好

new BigDecimal(String.valueOf(yourDoubleValue));

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

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

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

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

BigDecimal d = new BigDecimal("0.0065");

暂无
暂无

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

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