如何添加两个java.lang.Numbers?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2721390/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add two java.lang.Numbers?
提问by amit
I have two Numbers. Eg:
我有两个数字。例如:
Number a = 2;
Number b = 3;
//Following is an error:
Number c = a + b;
Why arithmetic operations are not supported on Numbers? Anyway how would I add these two numbers in java? (Of course I'm getting them from somewhere and I don't know if they are Integer or float etc).
为什么数字不支持算术运算?无论如何,我将如何在 Java 中添加这两个数字?(当然,我是从某个地方获取它们的,我不知道它们是整数还是浮点数等)。
采纳答案by Pops
You say you don't know if your numbers are integer or float... when you use the Number
class, the compiler also doesn't know if your numbers are integers, floats or some other thing. As a result, the basic math operators like + and - don't work; the computer wouldn't know how to handle the values.
你说你不知道你的数字是整数还是浮点数……当你使用这个Number
类时,编译器也不知道你的数字是整数、浮点数还是其他东西。因此,像 + 和 - 这样的基本数学运算符不起作用;计算机不知道如何处理这些值。
START EDIT
开始编辑
Based on the discussion, I thought an example might help. Computers store floating point numbers as two parts, a coefficient and an exponent. So, in a theoretical system, 001110 might be broken up as 0011 10, or 32= 9. But positive integers store numbers as binary, so 001110 could also mean 2 + 4 + 8 = 14. When you use the class Number
, you're telling the computer you don't know if the number is a float or an int or what, so it knows it has 001110 but it doesn't know if that means 9 or 14 or some other value.
基于讨论,我认为一个例子可能会有所帮助。计算机将浮点数存储为两部分,系数和指数。因此,在理论系统中,001110 可能被分解为 0011 10,或 3 2= 9。但是正整数将数字存储为二进制,因此 001110 也可能意味着 2 + 4 + 8 = 14。当您使用 class 时Number
,您告诉计算机你不知道数字是浮点数还是整数或什么,所以它知道它有 001110 但它不知道这是否意味着 9 或 14 或其他一些值。
END EDIT
结束编辑
What you can do is make a little assumption and convert to one of the types to do the math. So you could have
您可以做的是做一些假设并转换为其中一种类型来进行数学计算。所以你可以有
Number c = a.intValue() + b.intValue();
which you might as well turn into
你也可以变成
Integer c = a.intValue() + b.intValue();
if you're willing to suffer some rounding error, or
如果您愿意接受一些舍入误差,或者
Float c = a.floatValue() + b.floatValue();
if you suspect that you're not dealing with integers and are okay with possible minor precision issues. Or, if you'd rather take a small performance blow instead of that error,
如果您怀疑自己不是在处理整数,并且可以解决可能的小精度问题。或者,如果你宁愿承受小的性能打击而不是那个错误,
BigDecimal c = new BigDecimal(a.floatValue()).add(new BigDecimal(b.floatValue()));
回答by Philip Daubmeier
java.lang.Number
is just the superclass of all wrapper classes of primitive types (see java doc). Use the appropriate primitive type (double
, int
, etc.) for your purpose, or the respective wrapper class (Double
, Integer
, etc.).
java.lang.Number
只是原始类型的所有包装类的超类(请参阅java doc)。使用适当的基本类型(double
,int
你的目的,等等),或相应的包装类(Double
,Integer
,等)。
Consider this:
考虑一下:
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();
回答by Elie
Use the following:
使用以下内容:
Number c = a.intValue() + b.intValue(); // Number is an object and not a primitive data type.
Or:
或者:
int a = 2;
int b = 3;
int c = 2 + 3;
回答by fastcodejava
Number
is an abstract
class which you cannot make an instance of. Provided you have a correct instance of it, you can get number.longValue()
or number.intValue()
and add them.
Number
是一个abstract
不能创建实例的类。如果您有一个正确的实例,您可以获取number.longValue()
或number.intValue()
添加它们。
回答by Uri
First of all, you should be aware that Number is an abstract class. What happens here is that when you create your 2 and 3, they are interpreted as primitives and a subtype is created (I think an Integer) in that case. Because an Integer is a subtype of Number, you can assign the newly created Integer into a Number reference.
首先,您应该知道 Number 是一个抽象类。这里发生的情况是,当您创建 2 和 3 时,它们被解释为基元,并在这种情况下创建了一个子类型(我认为是一个整数)。由于 Integer 是 Number 的子类型,因此您可以将新创建的 Integer 分配给 Number 引用。
However, a number is just an abstraction. It could be integer, it could be floating point, etc., so the semantics of math operations would be ambiguous.
然而,数字只是一个抽象。它可以是整数,也可以是浮点数等,因此数学运算的语义会不明确。
Number does not provide the classic map operations for two reasons:
Number 不提供经典的 map 操作有两个原因:
First, member methods in Java cannot be operators. It's not C++. At best, they could provide an add()
首先,Java 中的成员方法不能是运算符。这不是 C++。充其量,他们可以提供一个 add()
Second, figuring out what type of operation to do when you have two inputs (e.g., a division of a float by an int) is quite tricky.
其次,当您有两个输入(例如,一个浮点数除以一个整数)时,弄清楚要执行什么类型的操作是相当棘手的。
So instead, it is your responsibility to make the conversion back to the specific primitive type you are interested in it and apply the mathematical operators.
因此,您有责任将转换回您感兴趣的特定原始类型并应用数学运算符。
回答by extraneon
I think there are 2 sides to your question.
我认为你的问题有两个方面。
Why is operator+ not supported on Number?
为什么 Number 不支持 operator+?
Because the Java language spec. does not specify this, and there is no operator overloading. There is also not a compile-time natural way to cast the Number to some fundamental type, and there is no natural add to define for some type of operations.
因为 Java 语言规范。没有指定这一点,并且没有运算符重载。也没有编译时自然的方式将 Number 转换为某种基本类型,并且没有自然添加来定义某些类型的操作。
Why are basic arithmic operations not supported on Number?
为什么 Number 不支持基本算术运算?
(Copied from my comment:)
(复制自我的评论:)
Not all subclasses can implement this in a way you would expect. Especially with the Atomic types it's hard to define a usefull contract for e.g. add.
并非所有子类都能以您期望的方式实现这一点。特别是对于 Atomic 类型,很难定义一个有用的契约,例如 add。
Also, a method add would be trouble if you try to add a Long to a Short.
此外,如果您尝试将 Long 添加到 Short,则方法 add 会很麻烦。
回答by SkidRunner
It would also work to make a method to handle the adding for you. Now I do not know the performance impact this will cause but I assume it will be less than using BigDecimal.
它也可以制定一种方法来为您处理添加。现在我不知道这会导致性能影响,但我认为它会小于使用 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();
}
}
回答by Fritz Mock
The only way to correctly add any two types of java.lang.Number is:
正确添加任意两种类型的 java.lang.Number 的唯一方法是:
Number a = 2f; // Foat
Number b = 3d; // Double
Number c = new BigDecimal( a.toString() ).add( new BigDecimal( b.toString() ) );
This works even for two arguments with a different number-type. It will (should?) not produce any sideeffects like overflows or loosing precision, as far as the toString() of the number-type does not reduce precision.
这甚至适用于具有不同数字类型的两个参数。只要数字类型的 toString() 不会降低精度,它就(应该?)不会产生任何副作用,如溢出或精度下降。
回答by azis.mrazish
The best answer would be to make util with double dispatch drilling down to most known types (take a look at Smalltalk addtition implementation)
最好的答案是使 util 具有双重调度深入到大多数已知类型(看看 Smalltalk addtition implementation)