2014-10-03 132 views
2

当我这样做浮点值解析Java中

value = Float.parseFloat("5555998.558f"); 

System.out.println("Value: " + value); 

它给我造成5555998.5而不是5555998.558 我使用了一些计算的变量值。我需要的确切数值,即5555998.558

如何克服这一点?

+3

为什么你使用float而不是double? – 2014-10-03 16:32:02

+1

为什么使用原始的浮点数据类型而不是'BigDecimal'? – Makoto 2014-10-03 16:32:45

+0

价值来自一个文本框这就是为什么我这样做。 – 2014-10-03 16:33:34

回答

7

该高值的float值精度仅为0.5,因此Java将其解析为最接近的值float它可能= 5555998.5,这就是打印的内容。

要查看2个最接近值之间的差值在这个幅度,(最后一位单位)使用Math.ulp

String s = "5555998.558f"; 
float value = Float.parseFloat(s); 
System.out.println(value); 
System.out.println(Math.ulp(value)); 

这将打印

5555998.5 
0.5 

您可以使用double其中有精度要好得多:

double d = Double.parseDouble(s); 
System.out.println(d); 
System.out.println(Math.ulp(d)); 

This print

5555998.558 
9.313225746154785E-10 

有趣的是,Double.parseDouble似乎并不介意到底fDouble.parseDoubleString转换为double“由double类的valueOf方法执行”。而Double.valueOf状态:

的floatValue:

  • Signopt NaN的

  • Signopt无限

  • Signopt FloatingPointLiteral

  • Signopt HexFloatingPointLiteral

  • SignedInteger

这种方法将需要String就好像它是一个Java数字文字,哪个Java与端部的支持f指示浮点文字。

+1

...或更好,BigDecimal将保留输入的确切十进制值。 – 2014-10-03 16:34:53

+0

@JonSkeet当然,'BigDecimal'将具有任意的精度。但'new BigDecimal(“5555998.558f”)'抛出'NumberFormatException'因为'f'存在。现在我很好奇为什么'Float.parseFloat'和'Double.parseDouble'似乎忽略了字符串中的'f'。 – rgettman 2014-10-03 16:37:51

+0

我也很惊讶,虽然它被记录在'Float.valueOf'中。我想最好的解决方案将取决于为什么f'存在,以及OP真正想要达到什么。 – 2014-10-03 16:41:40

5

BigDecimal可能是您确切的小数表示形式的最佳选择。

BigDecimal value = new BigDecimal("5555998.558"); 

这是不变的,所以每次你做它的操作会导致你创建一个新的BigDecimal实例,但其精度也有可能你所需要的。

0

也可以这样做:

Double value = Double.valueOf("5555998.558f"); 
System.out.println("Value: " + value); 

输出:

Value: 5555998.558 
0

http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html 浮动:浮子数据类型是单精度32位IEEE 754浮点。其值范围超出了本讨论的范围,但在Java语言规范的浮点类型,格式和值部分中进行了指定。与对byte和short的建议一样,如果需要将内存保存在浮点数的大数组中,请使用float(而不是double)。此数据类型不应用于精确值,例如货币。为此,您需要改为使用java.math.BigDecimal类。 Numbers和Strings涵盖了Java平台提供的BigDecimal和其他有用的类。

所以使用BigDecimal,你就没有问题了。