tags:

views:

312

answers:

6

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).

+3  A: 

java.lang.Numbers is just the superclass of all wrapper classes of primitive types (see java doc). Use the appropriate primitive type (float, int, etc.) for your purpose, or the respective wrapper class (Float, Integer, etc.).

Consider this:

Number a = 1.5; // Actually java creates a float and boxes it into a Float 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 float that is boxed into a Float object
Number d = a.floatValue() + (float)b.intValue();
Philip Daubmeier
I understand this. But strange that it is not directly supported on Number class itself.
@amit.dev 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. And Short.add(Long) is also bound to give trouble.
extraneon
@amit.dev: why should it be directly supported? That makes no sense, because it would demand java to support weird implicit casts or operator overloads for every permutation of types to add. I added an example code to my answer. Maybe that makes it more clear.
Philip Daubmeier
Note: The wrapper class for `int` is actually `Integer`.
Cam
@incrediman: thanks, youre right of course. I'm using c# most of the time, where they are named `Int32`, `Int64`, ... :)
Philip Daubmeier
@Philip The `Number a = 1.5;` is a double. `1.5f` is a float.
Christian Semrau
+2  A: 

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;
Elie
intValue() will not work too well on Double, or Long, or BigDecimal and so on...
Thilo
+6  A: 

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.

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.

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()));
Lord Torgamus
A: 

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.

fastcodejava
A: 

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.

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:

First, member methods in Java cannot be operators. It's not C++. At best, they could provide an 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.

Uri
Wrong, you cannot create an instance of an abstract class.
Cam
@incrediman: Where did I indicate that I am generating instances of an abstract class? I explicitly indicated that an integer is created and then assigned into the Number reference.
Uri
@incrediman, actually, it is legal to declare a reference to an abstract class and point it at an existing object; you just can't declare a new instance of an abstract class.
Lord Torgamus
@incrediman : Wrong, you cannot say Uri said that when he actually begin with the line: *...be aware that Number is an abstract class...* :) :) :)
OscarRyz
+1  A: 

I think there are 2 sides to your question.

Why is operator+ not supported on Number?

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.

Why are basic arithmic operations not supported on 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.

Also, a method add would be trouble if you try to add a Long to a Short.

extraneon