我想比较Number的两个任意实例,以找出哪个更大。如您所知,这些可能是整数,长整数或双数,但也可能是BigIntegers或BigDecimals。那该怎么办?
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。它应该比公认的答案更有效和更强大。
答案 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而言,这个错误的结果可以被视为“正确的”。