如何在Java中比较两个数字?

时间:2012-09-24 08:39:37

标签: java numbers compare

  

可能重复:
  Comparing the values of two generic Numbers

我想比较Number的两个任意实例,以找出哪个更大。如您所知,这些可能是整数,长整数或双数,但也可能是BigIntegers或BigDecimals。那该怎么办?

  1. 号码未实现Comparable
  2. 无法使用doubleValue(),因为BigDecimals或BigIntegers可能会失去精确度。
  3. 我真的必须进行实例测试和投射吗? 必须是一些执行此操作的库。但我已经检查过Apache Commons和Guava,但没有运气。

    编辑1:评论指出了这一点:Comparing the values of two generic Numbers。它有一个解决方案,使用toString()将所有内容转换为BigDecimal。真的没有更好的办法吗?

    编辑2:我刚刚发布了my own version as an answer to the other question。它应该比公认的答案更有效和更强大。

2 个答案:

答案 0 :(得分:17)

您无法比较Number类型的两个任意实例,因为这可能是无穷无尽的操作。想象一下两个无理数,其中唯一的区别在于十亿分之一。你必须比较几十亿个小数。

您需要将Number个实例转换为BigDecimal,根据需要应用舍入,然后比较这两个实例。

答案 1 :(得分:7)

严格来说,Number无法比较。首先需要定义比较的语义。由于您提到它用于库,您可能只想依赖Number API提供的内容。

所以它要比较longValue()或doubleValue()的值。我建议首先使用longValue()进行比较,如果结果是相等,则比较doubleValue()(这样可以捕获长溢出,但仍保持64位长精度)当值不是浮点数时):

public static int compare(Number n1, Number n2) {
    long l1 = n1.longValue();
    long l2 = n2.longValue();
    if (l1 != l2)
        return (l1 < l2 ? -1 : 1);
    return Double.compare(n1.doubleValue(), n2.doubleValue());
}

其他所有内容都是超出Number API提供的猜谜游戏。对于标准用途,上面代码应该运行得相当好。是的,如果你传递它(例如)BigIntegers或BigDecimals超出双精度值范围或者只有超过53位的尾数精度,它们被错误地检测为相等,但是就数字API而言,这个错误的结果可以被视为“正确的”。