比较Java中的数字

Dav*_*vid 20 java comparison numbers

在Java中,所有数字类型都从java.lang.Number扩展.拥有如下方法是一个好主意:

public boolean areEqual(Number first, Number second) {
    if (first != null && second != null) {
        return first.equals(second);
    }
}
Run Code Online (Sandbox Code Playgroud)

我担心双重2.00000不等于int 2的情况.这些是由内置等于处理吗?如果没有,有没有办法在java中编写一个简单的数字比较函数?(apache commons等外部库都可以)

pol*_*nts 41

一个Double从来没有 equalsInteger.而且,a double与a不同Double.

Java具有原始类型和引用类型.Java中真正的数字类型并没有扩展Number,因为它们是原始的.

您可能想要考虑一个不混合类型的系统,因为这通常会导致很多可能/可能不会丢失信息的隐式/显式转换的麻烦等.

相关问题

intvs Integer:

Number对比:

也可以看看


关于混合型计算

混合型计算是Java Puzzler中至少4个难题的主题.

以下是各种摘录:

通常最好避免混合型计算[...],因为它们本质上令人困惑[...]这在条件表达式中更为明显.混合类型比较总是令人困惑,因为系统被迫提升一个操作数以匹配另一个操作数的类型.转换是不可见的,可能无法产生您期望的结果

处方:避免混合整数和浮点类型的计算.首选积分算法到浮点.


小智 11

我知道这是一个古老的话题,但是......要比较Java中的两个数字,你可以使用BigDecimal中的compareTo方法.BigDecimal可以容纳从short到double或BigInteger的所有内容,因此它是完美的类.

所以你可以尝试写这样的东西:

public int compareTo(Number n1, Number n2) {
    // ignoring null handling
    BigDecimal b1 = new BigDecimal(n1.doubleValue());
    BigDecimal b2 = new BigDecimal(n2.doubleValue());
    return b1.compareTo(b2);
}
Run Code Online (Sandbox Code Playgroud)

这肯定不是关于性能的最佳方法.到目前为止,以下测试工作至少使用JDK7:

assertTrue(compareTo(new Integer(1), new Integer(2)) == -1);
assertTrue(compareTo(new Integer(1), new Double(2.0)) == -1);
assertTrue(compareTo(new Integer(1), new Double(Double.MAX_VALUE)) == -1);
assertTrue(compareTo(new Integer(1), new Double(Double.MIN_VALUE)) == 1);
assertTrue(compareTo(new Integer(1), new Double(1.000001)) == -1);
assertTrue(compareTo(new Integer(1), new Double(1.000)) == 0);
assertTrue(compareTo(new Integer(1), new Double(0.25*4)) == 0);
assertTrue(compareTo(new Integer(1), new AtomicLong(1)) == 0);
Run Code Online (Sandbox Code Playgroud)

  • 对于所有`Number`实现,更喜欢`Type.valueOf(value)`到`new Type(value)`.它们都提供缓存,这将节省大规模应用程序的内存. (3认同)
  • 我刚刚否决了您的答案,因为使用 doubleValue() 将 Long.MAX_VALUE 转换为 BigDecimal 给出了 9223372036854775808 而不是 9223372036854775807。从 BigInteger 到 BigDecimal 的转换更糟。为了正确起见,请遵循pickypg的建议,而在转换整数时调用 BigDecimal.valueOf(long) 和 new BigDecimal(BigInteger) 。1647684687678982643434436666777443865 变成 1647684687678982604257012050286346240 将您的方法应用于可存储到 BigInteger 的数字时。 (2认同)

Pop*_*ops 6

你建议的具体方法会失败,因为它使用的是equals()继承自的Object.也就是说,它会检查Number 对象是否相同,而不是它们的是否相同.

如果那只是一个说明性的例子,我会更新我的答案.

多基因的答案实际上几乎覆盖了我前进的基础.您可能也对此问题感兴趣:为什么java.lang.Number不能实现Comparable?.

  • @polygenelubricants如果我不得不猜测,对于“ Number”的所有内置Java实现,“等于”的描述是不准确的。它们都覆盖“等于”以执行“ instanceOf”检查(并因此执行“ null”检查),然后检查原始值,而不是进行引用检查,这就是描述的内容。换句话说,他们_do_检查其“ Class”的_and_值。 (2认同)