20

可能重复:
比较两个通用数字的值

我想比较Number的两个任意实例以找出哪个更大。如您所知,它们可能是整数、长整数或双精度数,也可能是大整数或大小数。那么该怎么办?

  1. Number 没有实现Comparable
  2. 不能使用doubleValue(),因为 BigDecimals 或 BigIntegers 可能会损失精度。

我真的需要进行实例测试和铸造吗?必须有一些图书馆可以做到这一点。但是我已经检查了 Apache Commons 和 Guava,但没有运气。

编辑 1:评论指出了这一点:比较两个通用 Numbers 的值。它有一个解决方案,可以使用toString(). 真的没有更好的方法来做到这一点吗?

编辑 2:我刚刚发布了我自己的版本作为另一个问题的答案。它应该比公认的答案更有效和更健壮。

4

2 回答 2

18

您不能比较 type 的两个任意实例Number,因为这可能是一个无休止的操作。想象两个无理数,唯一的区别是十亿位小数。为此,您必须比较数十亿个小数。

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

于 2012-09-24T09:01:40.890 回答
7

严格来说,数字是无法比较的。您首先需要定义比较的语义。由于您提到它用于库,您可能只想依赖 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 超出 Doubles 值范围或仅超过 53 位尾数精度的差异,它们被错误地检测为equal,但就 Number API 而言这个错误的结果可以被视为“正确”的结果。

于 2012-09-24T12:31:32.093 回答