如何在 Java 中正确截断双精度,例如 1.9999999999999999999 总是被截断为 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
1.99999999999999999
没有四舍五入到2
,而是2
。
System.out.println(1.999999999999999999); // 2
System.out.println(1.999999999999999999 == 2); // true
浮点数不是无限精确的。Java使用的存储格式(IEEE double
)中没有足够的位来区分1.999999999999999999
和2
。
如果您需要更高的准确性,请尝试其他数字格式,例如 BigDecimal
。
我认为您的d1
精度太高,无法表示为双精度。
如果d1
直接打印到 System.out,则会得到2.0
。
因此,任何对floor
或round
的调用都没有效果。
如果您需要这样的精度,您应该选择BigDecimal
。
这里解释了一些例子
文档
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