0

如何在 Java 中正确截断双精度数,例如 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
4

3 回答 3

7

1.99999999999999999不是四舍五入2 2

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

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

如果您需要更高的准确性,请尝试不同的数字格式,例如BigDecimal.

于 2013-09-21T20:42:47.647 回答
1

我认为您d1的精度太高,无法表示为双精度。

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

所以任何调用floorround没有效果。

如果你需要这样的精度,你应该去BigDecimal

于 2013-09-21T20:43:16.260 回答
0

这里解释了一些示例

文档

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
于 2013-09-21T20:38:18.047 回答