private static void simpleFloatsComparison() {
//Method 1
double f1 = .0;
for (int i = 1; i <= 11; i++) {
f1 += .1;
}
//Method 2
double f2 = .1 * 11;
System.out.println("f1 = " + f1);
System.out.println("f2 = " + f2);
if (f1 == f2)
System.out.println("f1 and f2 are equal\n");
else
System.out.println("f1 and f2 are not equal\n");
}
输出:
f1 = 1.0999999999999999
f2 = 1.1
f1 and f2 are not equal
观察这两个值。 f1计算为1.0999999999999999。 它正是内部导致四舍五入的问题。 这就是为什么不推荐简单方式浮点比较的原因。
private static void thresholdBasedFloatsComparison() {
final double THRESHOLD = .0001;
//Method 1
double f1 = .0;
for (int i = 1; i <= 11; i++) {
f1 += .1;
}
//Method 2
double f2 = .1 * 11;
System.out.println("f1 = " + f1);
System.out.println("f2 = " + f2);
if (Math.abs(f1 - f2) < THRESHOLD)
System.out.println("f1 and f2 are equal using threshold\n");
else
System.out.println("f1 and f2 are not equal using threshold\n");
}
f1 = 1.0999999999999999
f2 = 1.1
f1 and f2 are equal using threshold
a.compareTo(b); // returns (-1 if a < b), (0 if a == b), (1 if a > b)
切勿使用.equals()方法比较BigDecimals。 那是因为这个等于函数会比较尺度。 如果比例不同,.equals()将返回false,即使它们是数学上相同的数字。
private static void testBdEquality()
{
BigDecimal a = new BigDecimal("2.00");
BigDecimal b = new BigDecimal("2.0");
System.out.println(a.equals(b)); // false
System.out.println(a.compareTo(b) == 0); // true
}
现在我们来验证一下,我们使用BigDecimal类来解决原始问题。
private static void bigDecimalComparison()
{
//Method 1
BigDecimal f1 = new BigDecimal("0.0");
BigDecimal pointOne = new BigDecimal("0.1");
for (int i = 1; i <= 11; i++) {
f1 = f1.add(pointOne);
}
//Method 2
BigDecimal f2 = new BigDecimal("0.1");
BigDecimal eleven = new BigDecimal("11");
f2 = f2.multiply(eleven);
System.out.println("f1 = " + f1);
System.out.println("f2 = " + f2);
if (f1.compareTo(f2) == 0)
System.out.println("f1 and f2 are equal using BigDecimal\n");
else
System.out.println("f1 and f2 are not equal using BigDecimal\n");
}
f1 = 1.1
f2 = 1.1
f1 and f2 are equal using BigDecimal
https://www.leftso.com/article/373.html