## Java如何正确比较浮点数

java 比较 浮点数 正确 浮点

``````double d1 = .1 * 3;
double d2 = .3;
System.out.println(d1 == d2);
``````

``````final double THRESHOLD = .0001;
double d1 = .1 * 3;
double d2 = .3;
if(Math.abs(d1-d2) < THRESHOLD) {
System.out.println("d1 和 d2 相等");
} else {
System.out.println("d1 和 d2 不相等");
}
``````

`Math.abs()` 方法用来返回 double 的绝对值，如果 double 小于 0，则返回 double 的正值，否则返回 double。也就是说，`abs()` 后的结果绝对大于 0，如果结果小于阈值（THRESHOLD），我们就认为 d1 和 d2 相等。

`a.compareTo(b)` 如果 a 和 b 相等，则返回 0，否则返回 -1。

tips: 不要使用 `equals()` 方法对两个 BigDecimal 对象进行比较，这是因为 `equals()` 方法会考虑位数，如果位数不同，则会返回 false，尽管数学值是相等的。

``````BigDecimal a = new BigDecimal("2.00");
BigDecimal b = new BigDecimal("2.0");
System.out.println(a.equals(b));
System.out.println(a.compareTo(b) == 0);
``````

`compareTo()` 方法比较的过程非常严谨，源码如下：

``````private int compareMagnitude(BigDecimal val) {
// Match scales, avoid unnecessary inflation
long ys = val.intCompact;
long xs = this.intCompact;
if (xs == 0)
return (ys == 0) ? 0 : -1;
if (ys == 0)
return 1;
long sdiff = (long)this.scale - val.scale;
if (sdiff != 0) {
// Avoid matching scales if the (adjusted) exponents differ
long xae = (long)this.precision() - this.scale; // [-1]
long yae = (long)val.precision() - val.scale; // [-1]
if (xae < yae)
return -1;
if (xae > yae)
return 1;
if (sdiff < 0) {
// The cases sdiff <= Integer.MIN_VALUE intentionally fall through.
if ( sdiff > Integer.MIN_VALUE &&
(xs == INFLATED ||
(xs = longMultiplyPowerTen(xs, (int)-sdiff)) == INFLATED) &&
ys == INFLATED) {
BigInteger rb = bigMultiplyPowerTen((int)-sdiff);
return rb.compareMagnitude(val.intVal);
}
} else { // sdiff > 0
// The cases sdiff > Integer.MAX_VALUE intentionally fall through.
if ( sdiff <= Integer.MAX_VALUE &&
(ys == INFLATED ||
(ys = longMultiplyPowerTen(ys, (int)sdiff)) == INFLATED) &&
xs == INFLATED) {
BigInteger rb = val.bigMultiplyPowerTen((int)sdiff);
return this.intVal.compareMagnitude(rb);
}
}
}
if (xs != INFLATED)
return (ys != INFLATED) ? longCompareMagnitude(xs, ys) : -1;
else if (ys != INFLATED)
return 1;
else
return this.intVal.compareMagnitude(val.intVal);
}
``````

``````BigDecimal d1 = new BigDecimal("0.1");
BigDecimal three = new BigDecimal("3");
BigDecimal d2 = new BigDecimal("0.3");
d1 = d1.multiply(three);
System.out.println("d1 = " + d1);
System.out.println("d2 = " + d2);
System.out.println(d1.compareTo(d2));
``````

``````d1 = 0.3
d2 = 0.3
0
``````

d1 和 d2 都为 0.3，所以 `compareTo()` 的结果就为 0，表示两个值是相等的。

https://www.cnblogs.com/p1ng/p/13945704.html