【问题标题】:How to Compare Two Numbers in Java? [duplicate]如何在 Java 中比较两个数字? [复制]
【发布时间】:2012-09-15 16:53:01
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 将任何内容转换为BigDecimal?
  • 查看此答案和其中的链接:stackoverflow.com/a/3214469/44522
  • 为什么要比较任意 Number 类?为什么它们不都是同一类型?
  • 好问题,一定要看@MicSim提供的链接
  • 我同意 SJuan76。我也最终找到了一种将任何 Number 转换为 BigDecimal 然后进行比较的方法。

标签: java numbers compare


【解决方案1】:

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

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

【讨论】:

  • 有趣的 cmets,谢谢。但由于这是一个图书馆,我不能决定何时何地四舍五入。
  • 那么你应该让图书馆的用户定义使用什么样的舍入和所需的精度。
【解决方案2】:

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

所以它归结为比较 longValue() 或 doubleValue() 的值。我建议首先使用 longValue() 进行比较,如果结果是 equal,也比较 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 而言,这个错误的结果可以看作是“正确的”结果。

【讨论】:

  • 我认为应该先比较double的值;否则我认为 NaN 将在 -1 和下一个更大的值之间排序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-24
  • 2019-09-08
  • 2016-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-19
相关资源
最近更新 更多