如何正确截断双精度

时间:2013-09-21 20:33:14

标签: java precision truncate

如何正确截断Java中的double,例如1.99999999999999999总是被截断为1而不是舍入到2,如下例所示。

    double d1 = 1.999999999999999999;
    double d2 = 1.0; 
    long i1 = (long)Math.floor(d1);
    long i2 = (long)Math.floor(d2);
    System.out.println("i1="+i1 + " i2="+i2); //i1 == 2

在此处运行示例:http://www.browxy.com/SubmittedCode/42603

解决方案

使用具有仲裁精度的BigDecimal

BigDecimal bd = new BigDecimal("0.9999999999999999999999999999");
bd = bd.setScale(0, BigDecimal.ROUND_DOWN); //truncate

3 个答案:

答案 0 :(得分:7)

1.99999999999999999未向上舍入为2 2

System.out.println(1.999999999999999999);      // 2
System.out.println(1.999999999999999999 == 2); // true

浮点数不是无限精确的。 Java使用的存储格式(IEEE double)中没有足够的位来区分1.9999999999999999992

如果您需要更高的准确度,请尝试使用其他数字格式,例如BigDecimal

答案 1 :(得分:1)

我认为你的d1有太多的精确度,无法表达为双倍。

如果您将d1直接打印到System.out,则会获得2.0

因此,对floorround的任何调用均无效。

如果你需要这样的精确度,你应该选择BigDecimal

答案 2 :(得分:0)

解释了一些例子here

Documentation

double d1 = 1.999999999999999999;
double d2 = 1.0; 
long i1 = (long)Math.round(d1);
long i2 = (long)Math.floor(d2);

System.out.println("i1="+i1 + " i2="+i2);

然后输出

i1=2 i2=1