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

2022-09-02 10:10:13

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

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

  1. 数字不实现可比性
  2. 无法使用,因为 BigDecimals 或 BigIntegers 可能会损失精度。doubleValue()

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

编辑 1:评论指出了这一点:比较两个通用数字的值。它有一个解决方案,可以使用将所有内容转换为大十进制。真的没有更好的方法来做到这一点吗?toString()

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


答案 1

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

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


答案 2

严格来说,数量是无法比拟的。首先需要定义比较的语义。由于您提到了它供库使用,因此您可能只想依赖数字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());
}

其他一切都是超出数字API提供的猜测游戏。对于标准用法,上面的代码应该工作得很好。是的,如果您传递它(例如)BigIntegers或BigDecimals,它们超出了Doubles值范围,或者其差异仅超过53位的尾数精度,则它们被错误地检测为相等,但就数字API而言,这个错误的结果可以被视为“正确”的结果。