如何添加两个java.lang.Numbers?

ami*_*mit 42 java

我有两个号码.例如:

Number a = 2;
Number b = 3;
//Following is an error:
Number c = a + b;
Run Code Online (Sandbox Code Playgroud)

为什么Numbers不支持算术运算?无论如何,我如何在java中添加这两个数字?(当然我从某个地方得到它们,我不知道它们是Integer还是float等).

Pop*_*ops 23

你说你不知道你的数字是整数还是浮点数...当你使用这个Number类时,编译器也不知道你的数字是整数,浮点数还是其他东西.结果,像+和 - 这样的基本数学运算符不起作用; 计算机不知道如何处理这些值.

开始编辑

根据讨论,我认为一个例子可能有所帮助.计算机将浮点数存储为两部分,即系数和指数.因此,在理论系统中,001110可能被分解为0011 10或3 2 = 9.但正整数将数字存储为二进制,因此001110也可能意味着2 + 4 + 8 = 14.当您使用该类时Number, '告诉计算机你不知道数字是浮点数还是int数或者是什么,所以它知道它有001110但它不知道这是否意味着9或14或其他值.

结束编辑

你可以做的是做一点假设并转换成其中一种类型进行数学运算.所以你可以拥有

Number c = a.intValue() + b.intValue();
Run Code Online (Sandbox Code Playgroud)

你可能会变成

Integer c = a.intValue() + b.intValue();
Run Code Online (Sandbox Code Playgroud)

如果你愿意遭受一些舍入错误,或者

Float c = a.floatValue() + b.floatValue();
Run Code Online (Sandbox Code Playgroud)

如果您怀疑自己没有处理整数,并且可能会出现轻微的精确问题.或者,如果你宁愿采取一点性能打击而不是那个错误,

BigDecimal c = new BigDecimal(a.floatValue()).add(new BigDecimal(b.floatValue()));
Run Code Online (Sandbox Code Playgroud)

  • 你几乎是对的.但我不同意"......所以它知道它有001110,但它不知道这是否意味着9或14或其他一些价值." Java HAS运行时类型信息.Java将知道Number对象的运行时类型是Integer还是Double或其他内容.从理论上讲,你可以开始区分类型并开始编程公共号加(数字a,数字b){if(一个实例为Integer && b instanceof Integer){return new Integer(a.intValue + b.intValue();} .. . 等等... (2认同)

Ski*_*ner 16

它也可以用来为你处理添加的方法.现在我不知道这将导致的性能影响,但我认为它将比使用BigDecimal少.

public static Number addNumbers(Number a, Number b) {
    if(a instanceof Double || b instanceof Double) {
        return a.doubleValue() + b.doubleValue();
    } else if(a instanceof Float || b instanceof Float) {
        return a.floatValue() + b.floatValue();
    } else if(a instanceof Long || b instanceof Long) {
        return a.longValue() + b.longValue();
    } else {
        return a.intValue() + b.intValue();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @ ndm13“在调用具有相同类型的两个方法时,只需要检查一种类型”,但这不是事实。这就是重点。您的签名允许以与原始类型完全相同的方式传递不同的类型。 (3认同)
  • 您可以使用`<N extended Number>`来避免重复,因此您只需要检查`Na'的类型即可。 (2认同)
  • 所以我同意使用泛型是一种更好的方法.但是你仍然需要检查a和b的类型.`number number = addNumbers(new Double(1.275),new Long(14));`只检查a返回正确的Double.`number number = addNumbers(new Long(14),new Double(1.275));`只检查a返回不正确的Long. (2认同)

小智 9

正确添加任何两种类型的java.lang.Number的唯一方法是:

Number a = 2f; // Foat
Number b = 3d; // Double
Number c = new BigDecimal( a.toString() ).add( new BigDecimal( b.toString() ) );
Run Code Online (Sandbox Code Playgroud)

这甚至适用于具有不同数字类型的两个参数.只要number-type的toString()不降低精度,它(应该?)不会产生任何副作用,如溢出或失去精度.

  • 如果我们可以让 Class<?> BigDecimal.getPrimitiveType() 返回 int.class 或 double.class 或其他任何东西 (2认同)

Phi*_*ier 8

java.lang.Number只是原始类型的所有包装类的超类(参见java doc).使用适当的基本类型(double,int,等),你的目的,或者相应的包装类(Double,Integer,等).

考虑一下:

Number a = 1.5; // Actually Java creates a double and boxes it into a Double object
Number b = 1; // Same here for int -> Integer boxed

// What should the result be? If Number would do implicit casts,
// it would behave different from what Java usually does.
Number c = a + b; 

// Now that works, and you know at first glance what that code does.
// Nice explicit casts like you usually use in Java.
// The result is of course again a double that is boxed into a Double object
Number d = a.doubleValue() + (double)b.intValue();
Run Code Online (Sandbox Code Playgroud)

  • @Philip`Number a = 1.5;`是双精度数.`1.5f`是一个浮点数. (5认同)
  • 我理解这一点.但奇怪的是,它没有直接支持Number类本身. (2认同)