我同意jmcnamara之前的答案。这个答案在其基础上进行了扩展。
对于每个IEEE 754 64位二进制浮点数,存在一系列十进制小数,在输入时会舍入为该数字。从-130.98999999999069开始,最接近的可表示值是-130.98999999999068677425384521484375。使用四舍五入和“银行家舍入规则”,任何位于[-130.9899999999907009851085604168474674224853515625,-130.9899999999906725633991300128400325775146484375]范围内的值都会舍入到该值。(该范围是封闭的,因为中心数字的二进制表示是偶数。如果它是奇数,则范围将是开放的)。-130.98999999999069和-130.9899999999907都在范围内。
你拥有与Excel相同的浮点数。你拥有与输入到Excel相同的浮点数。不幸的是,进一步的实验表明,Excel 2007只转换了您输入的最高15位数字。我将-130.98999999999069粘贴到Excel单元格中。它不仅被显示为-130.98999999999,而且使用它的算术与最接近该值的双精度数-130.989999999990004653227515518665313720703125一致,而不是原始输入。
要获得与Excel相同的效果,您可能需要使用例如BigDecimal将其截断为15位小数,然后转换为double。
Java用于浮点值的默认字符串转换基本上选择具有最少小数位的十进制小数,该小数可以转换回原始值。-130.9899999999907比-130.98999999999069少几位小数。显然,Excel显示更少的数字,但Apache POI正在获取您在Java中拥有的同一个数字的表示之一。
这是我用来获取此答案中的数字的程序。请注意,我仅使用BigDecimal来获取双精度数的精确输出,并计算两个连续双精度数之间的中点。
import java.math.BigDecimal;
class Test {
public static void main(String[] args) {
double d = -130.98999999999069;
BigDecimal dDec = new BigDecimal(d);
System.out.println("Printed as double: "+d);
BigDecimal down = new BigDecimal(Math.nextAfter(d, Double.NEGATIVE_INFINITY));
System.out.println("Next down: " + down);
System.out.println("Half down: " + down.add(dDec).divide(BigDecimal.valueOf(2)));
System.out.println("Original: " + dDec);
BigDecimal up = new BigDecimal(Math.nextAfter(d, Double.POSITIVE_INFINITY));
System.out.println("Half up: " + up.add(dDec).divide(BigDecimal.valueOf(2)));
System.out.println("Next up: " + up);
System.out.println("Original in hex: "+Long.toHexString(Double.doubleToLongBits(d)));
}
}
以下是它的输出:
Printed as double: -130.9899999999907
Next down: -130.989999999990715195963275618851184844970703125
Half down: -130.9899999999907009851085604168474674224853515625
Original: -130.98999999999068677425384521484375
Half up: -130.9899999999906725633991300128400325775146484375
Next up: -130.989999999990658352544414810836315155029296875
Original in hex: c0605fae147ae000