使用 BigDecimal 确实有效。您仍然必须小心使用 double 表示的确切值并在算术上舍入。
BigInteger myBI = new BigInteger("1000000000000000000000000000000000000000000000000000000");
double d = 0.1;
BigDecimal bd = new BigDecimal(myBI);
BigInteger doubleWithStringValue = bd.multiply(BigDecimal.valueOf(d)).toBigInteger();
BigDecimal bdresult = bd.multiply(new BigDecimal(d));
BigInteger unrounded = bdresult.toBigInteger();
BigInteger correct = bdresult.add(new BigDecimal("0.5")).toBigInteger(); // this way of rounding assumes positive numbers
BigInteger lostprecision = new BigDecimal(myBI.doubleValue() * d).toBigInteger();
System.out.println("DoubleString: " + doubleWithStringValue);
System.out.println("Unrounded: " + unrounded);
System.out.println("Correct: " + correct);
System.out.println("Lost precision: " + lostprecision);
输出:
DoubleString: 100000000000000000000000000000000000000000000000000000
Unrounded: 100000000000000005551115123125782702118158340454101562
Correct: 100000000000000005551115123125782702118158340454101563
Lost precision: 100000000000000020589742799994816764107083808679919616