0

Let's say you have two large integers and you want to multiply them.

int a = 150000;
int b = 200000;

Operation 1: [Incorrect] ( Overflows )    
long result = a * b;
Operation 2: [Correct]
long result = (long)a*b;

Why is a cast required even though the assignment is to a variable of a type that can accomodate the result?

  • because Java will first multiply the values and than it will assign the value. It doesn't look like the assigned type – Jens Mar 08 '17 at 12:44
  • Because the implicit conversion happens *after* the multiplication. If you multiply the two `int`s the result will overflow an `int` and that would then be converted to `long` – UnholySheep Mar 08 '17 at 12:44

6 Answers6

4

Yes, a cast is required.

If you don't cast one or both of the int arguments to long, the multiplication will be performed as a 32 bit operation. If multiplication overflows, the value ultimately assigned to result will be incorrect.

As the JLS states (15.7.1):

If an integer multiplication overflows, then the result is the low-order bits of the mathematical product as represented in some sufficiently large two's-complement format. As a result, if overflow occurs, then the sign of the result may not be the same as the sign of the mathematical product of the two operand values.

If you cast one or both operands to long, then the multiplication will be performed as a 64 bit operation, and the operation won't overflow.

(There are other ways to cause the operation to be performed using long arithmetic, but a type cast is the most idiomatic.)

Stephen C
  • 632,615
  • 86
  • 730
  • 1,096
1

In your case, you first cast a into long then you do the multiplication.

You can update the operation to be sure this will result in a long like this long result = 1L * a * b, the numeric result of operation will be a long because it use a long in the beginning (be careful to the operator priority of course).

But this won't work

long result = a * b * 1L

because the integer multiplication will be first done and store in an integer.

See my answer here for a explanation about priority

Community
  • 1
  • 1
AxelH
  • 13,322
  • 2
  • 21
  • 50
  • Casting either of the operands to long is enough. No need to introduce 1L as new operand. Refer here for more details: https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2 – Namrata Bagerwal Mar 21 '18 at 13:43
  • Thanks for your input @NamrataBagerwal. Note that I am aware of that, if you check my linked answer, it refer to a more "specific" JLS for Integer and Floating point operation. FYI: I prefer promotion (`1L * a * b`) to casting (`(long) a * b`). That's my appreciation of course. – AxelH Mar 21 '18 at 14:10
0

This is because a and b in your case are integers, you need to first convert them to long(casting) else you are conflicting. Since long can accommodate your result because it has more bits(i.e 64 bits) then simple int datatype.

Ramesh Kumar
  • 1,223
  • 12
  • 16
0

When you do any arithmetic operation you must know the operators precedence. The assignment operator has the least precedence, hence the result is first computed and then assigned to the given variable, So while computing JAVA allocates the memory bytes of the variable type which has highest byte storage. For E.g.

  • int*int the computed result will be stored in int
  • int*float the computed result will be stored in float
  • float*double the computed result will be stored in double
  • int* float*double the computed result will be stored in double

So in your example the computed result will be stored in int and then only assignment happens.

Shoban Sundar
  • 493
  • 1
  • 9
  • 11
  • `float * double` will store the result in `double`: https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2 *"If either operand is of type double, the other is converted to double."* – UnholySheep Mar 08 '17 at 12:52
-1

I think becuase of the sequence. First multiplication Second assignment.

Cheers.

LakiGeri
  • 1,587
  • 3
  • 22
  • 49
-2

The range of int type in java is –2,147,483,648 to 2,147,483,647 and the result we get is 30000000000 can't be hold by int so long required.

AG_
  • 44
  • 3