用Java比较数字
在Java中,所有数字类型都从Java.lang.Number扩展而来。采用以下方法是否是一个好主意:用Java比较数字,java,comparison,numbers,Java,Comparison,Numbers,在Java中,所有数字类型都从Java.lang.Number扩展而来。采用以下方法是否是一个好主意: public boolean areEqual(Number first, Number second) { if (first != null && second != null) { return first.equals(second); } } private static final double EPSILON = 0.000000
public boolean areEqual(Number first, Number second) {
if (first != null && second != null) {
return first.equals(second);
}
}
private static final double EPSILON = 0.000000000000001d;
public static boolean areEquivalentNumbers(Number a, Number b)
{
if (a == null)
{
return b == null;
}
else if (b == null)
{
return false;
}
else
{
return Math.abs(a.doubleValue() - b.doubleValue()) < EPSILON;
}
}
我关心的是双精度2.00000不等于整数2的情况。这些都是由内置的equals处理的吗?如果没有,有没有办法用java编写一个简单的数字比较函数?(外部库,如apache commons是可以的)A
Double
是从不等于整数
。此外,double
与double
不同
Java有基元类型和引用类型。Java中真正的数字类型不是从Number
扩展而来的,因为它们是原语
您可能想考虑一个不混合类型的系统,因为这通常会导致隐式/显式转换(可能会丢失信息等)的大量麻烦。
相关问题
在
int
vsInteger
上:
关于编号比较:
另见
-
数值类型为整数类型和浮点类型。
整数类型有
byte
、short
、int
和long
和char
。
浮点类型是float
和double
关于混合型计算
混合型计算是计算机中至少4个难题的主题
以下是各种摘录:
通常最好避免混合类型的计算[…],因为它们本身就容易混淆[…]这一点在条件表达式中最为明显。混合类型比较总是令人困惑,因为系统被迫升级一个操作数以匹配另一个操作数的类型。转换是不可见的,可能不会产生预期的结果
处方:避免混合整数和浮点类型的计算。喜欢整数运算而不是浮点运算
您建议的特定方法将失败,因为它使用从对象继承的equals()
。也就是说,它将检查Number
对象是否相同,而不是它们的值是否相同
如果这只是一个说明性的例子,我将更新我的答案
polygene的答案实际上几乎涵盖了我想要的领域。您可能还对这个问题感兴趣:。您不能打电话
number.equals(number2);
因为,如果number是一个Double,number2是一个整数,它们将不属于同一个类,您将得到一个异常,告诉您这一事实
您可以自己编写一个接受Number对象的比较类,但是您必须考虑Number的不同子类。如果您想知道对象引用是否相同,那么现有的方法符合要求。表示2.0
的Double
和表示2
的Integer
绝对是不同的对象,在一般意义上肯定不能互换
如果您只想知道数值是否相同,可以使用该方法将两个数字转换为双精度,然后将这些数字一起比较(可能允许较小的公差,因为大多数数字表示不准确,例如1.9999996583表示应为2的数字,具体取决于中间计算步骤)。如下所示:
public boolean areEqual(Number first, Number second) {
if (first != null && second != null) {
return first.equals(second);
}
}
private static final double EPSILON = 0.000000000000001d;
public static boolean areEquivalentNumbers(Number a, Number b)
{
if (a == null)
{
return b == null;
}
else if (b == null)
{
return false;
}
else
{
return Math.abs(a.doubleValue() - b.doubleValue()) < EPSILON;
}
}
private static final double EPSILON=0.000000000000001d;
公共静态布尔值AreequivalentNumber(数字a、数字b)
{
如果(a==null)
{
返回b==null;
}
else如果(b==null)
{
返回false;
}
其他的
{
返回Math.abs(a.doubleValue()-b.doubleValue())
比较整数和浮点之间的数字几乎永远不会得到你想要的结果。但是,如果这是一个简单的练习,则可以通过比较值的字符串表示形式来实现比较,如中所示:
public boolean areEqual(Number first, Number second) {
if (first == null) {
return second == null;
}
if (second == null) {
return false;
}
return first.toString().equals(second.toString());
}
关于一些回答,我是否可以建议不要写这样的东西:
boolean compare(Object o1, Object o2)
{
if (o1==null)
return o2==null;
if (o2==null)
return false;
return o1.equals(o2);
}
这样写更简洁,而且我相信更有效:
boolean compare(Object o1, Object o2)
{
return o1==o2 || o1!=null && o2!=null && o1.equals(o2);
}
如果两者都为null,则o1==o2将返回true。如果它们不是但它们是同一个物体,那也没关系
从技术上讲,氧气=对于大多数equals的实现来说,null不是必需的,但是如果您真的像上面的示例那样对对象执行此操作,那么您当然不知道每个重写是如何编写的。我知道这是一个老话题,但是。。。。
要在Java中比较两个数字,可以使用BigDecimal中的compareTo方法。BigDecimal可以保存从short到double或BigInteger的所有内容,因此它是实现此功能的完美类
所以你可以试着这样写:
public int compareTo(Number n1, Number n2) {
// ignoring null handling
BigDecimal b1 = new BigDecimal(n1.doubleValue());
BigDecimal b2 = new BigDecimal(n2.doubleValue());
return b1.compareTo(b2);
}
这肯定不是关于性能的最佳方法。
到目前为止,至少在JDK7中,以下测试起到了作用:
assertTrue(compareTo(new Integer(1), new Integer(2)) == -1);
assertTrue(compareTo(new Integer(1), new Double(2.0)) == -1);
assertTrue(compareTo(new Integer(1), new Double(Double.MAX_VALUE)) == -1);
assertTrue(compareTo(new Integer(1), new Double(Double.MIN_VALUE)) == 1);
assertTrue(compareTo(new Integer(1), new Double(1.000001)) == -1);
assertTrue(compareTo(new Integer(1), new Double(1.000)) == 0);
assertTrue(compareTo(new Integer(1), new Double(0.25*4)) == 0);
assertTrue(compareTo(new Integer(1), new AtomicLong(1)) == 0);
System.out.println(新的Double(0).equals(新的Long(0))代码>打印<代码>错误
;它不会抛出任何异常
。有趣的方法!由于String
操作效率低下,可能不适合进行大量比较。不起作用。((Number)0.0f).toString().equals(((Number)0).toString())==>False对于所有Number
实现,首选Type.valueOf(value)
到新类型(value)
。它们都提供缓存,这将在大规模应用程序中节省内存。我刚刚否决了你的答案,因为使用doubleValue()将Long.MAX_值转换为BigDecimal会得到9223372036854775808,而不是9223372036854775807。从BigInteger到BigDecimal的转换更糟糕。为了正确起见,请遵循pickypg的建议,而不是调用BigDecimal.valueOf(long)和new BigDecimal(BigInteger)