NumberFormat Parse问题

我对将字符串解析为Double时遇到的这种特殊“错误”感到困惑。

我已经设置了NumberFormat属性和符号。

当传递一个15位和2位小数的字符串(例如str = "333333333333333,33" )并用Number num = NumberFormat.parse(str)解析它时,结果省略了一个数字。

num的实际值是3.333333333333333E14

它似乎与Strings一起使用所有的1,2和4但是……

有人可以开导我吗?

干杯恩里科

答案简短; 由于圆误差

 (double) 111111111111111.11 != (double) 111111111111111.1 

 (double) 333333333333333.33 == (double) 333333333333333.3 

如果你想要更高的精度,使用setParseBigDecimal和parse将返回一个BigDecimal。


为什么会这样? 这是因为你处于双倍精度的极限。 17个很好,因为它可以代表。 2是两倍,双倍存储2的力量,所有17个中的两个的每一个力量,所以17个四分之一和17个八分是好的。

但是,17个三分位数需要多于一个位来表示该值,并且最后一位被截断。 类似地,17五,六和九也有舍入误差。

 double[] ds = { 111111111111111.11, 222222222222222.22, 333333333333333.33, 444444444444444.44, 555555555555555.55, 666666666666666.66, 777777777777777.77, 888888888888888.88, 999999999999999.99}; for (double d : ds) { System.out.println(d + " - " + new BigDecimal(d)); } 

打印以下内容。 在打印之前, double会略微舍入,BigDecimal会显示double所代表的确切值。

 1.1111111111111111E14 - 111111111111111.109375 2.2222222222222222E14 - 222222222222222.21875 3.333333333333333E14 - 333333333333333.3125 4.4444444444444444E14 - 444444444444444.4375 5.5555555555555556E14 - 555555555555555.5625 6.666666666666666E14 - 666666666666666.625 7.777777777777778E14 - 777777777777777.75 8.888888888888889E14 - 888888888888888.875 1.0E15 - 1000000000000000 

在这种情况下, DecimalFormat.parse方法将返回Double ,其精度有限

你不能指望它始终能够返回一个完全代表输入的数字。

您可以使用BigDecimal.setParseBigDecimal允许数字格式从parse方法返回BigDecimal 。 此Number能够以任意精度表示您的值。 (感谢@Peter Lawrey指出这一点!)

Interesting Posts