Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do these two multiplication operations give different results?

Why do I need to add an "L" letter to get the correct long value? And what is the other value?

long oneYearWithL = 1000*60*60*24*365L; long oneYearWithoutL = 1000*60*60*24*365; System.out.println(oneYearWithL);//gives correct calculation result : 31536000000 System.out.println(oneYearWithoutL)//gives incorrect calculation result: 1471228928 
like image 404
fareed Avatar asked Oct 06 '12 09:10

fareed


People also ask

When multiplying 2 things with the different signs the answer is?

Positive x positive = positive When you multiply two integers with different signs, the result is always negative. Just multiply the absolute values and make the answer negative.

What do we call the result of the multiplication of two or more factors?

When two or more numbers are multiplied together, the answer obtained is called the product. In the case of the multiplication of two numbers, the first number in which the other is being multiplied is called the multiplicand. The second number which is being multiplied in the first is called the multiplier.

How are the operations on division and multiplication related to each other?

Multiplication and division are closely related, given that division is the inverse operation of multiplication. When we divide, we look to separate into equal groups, while multiplication involves joining equal groups.


1 Answers

long oneYearWithL = 1000*60*60*24*365L; long oneYearWithoutL = 1000*60*60*24*365; 

Your first value is actually a long (Since 365L is a long, and 1000*60*60*24 is an integer, so the result of multiplying a long value with an integer value is a long value.

But 2nd value is an integer (Since you are mulitplying an integer value with an integer value only. So the result will be a 32-bit integer. Now the result obtained for that multiplication is outside the actual range of integer. So, before getting assigned to the variable, it is truncated to fit into valid integer range.

Take a look at the following print statement: -

System.out.println(1000*60*60*24*365L); System.out.println(1000*60*60*24*365); System.out.println(Integer.MAX_VALUE); 

When you run the above code: -

Output: -

31536000000 1471228928 2147483647 

So, you can see the difference..

011101010111101100010010110000000000 -- Binary equivalent of 1000*60*60*24*365L     01111111111111111111111111111111 -- Binary equivalent of Integer.MAX_VALUE 

So, if you don't add that L at the end of your number, the 4 most significant bit is removed from the first binary string..

So, the string becomes..

(0111)01010111101100010010110000000000 -- Remove the most significant bits..       01010111101100010010110000000000 -- Binary equivalent of 1471228928 

(which you get as output)


UPDATE: - From the above explanation, you can also understand that, even in the first assignment, if the result of your multiplication of integers before multiplying it with 365L goes out of range, then again it will be truncated to fit in integer range, or converted to 2's complement representation if required, and then only it will be multiplied with the long value - 365L.

For e.g: -

long thirtyYearWithL = 1000*60*60*24*30*365L; 

In the above example, consider the first part - 1000*60*60*24*30. The result of this multiplication is: - 2592000000. Now lets' see how it is represented in binary equivalent: -

2592000000 = 10011010011111101100100000000000  -- MSB is `1`, a negative value              01100101100000010011100000000001  -- 2's complement representation 

Decimal representation of the 2's complement representation is 1702967297. So, 2592000000 is converted to -1702967297, before getting multiplied to 365L. Now since, this value fits in the integer range which is : - [-2147483648 to 2147483647], so it will not be truncated further.

So, the actual result will be: -

long thirtyYearWithL = 1000*60*60*24*30*365L;                      = 2592000000 * 365L;                      = -1702967297 * 365L = -621583063040 

So, all these stuffs just considers the actual type of final result on applying the arithmetic operation. And this check is performed on each temporary result of operations moving from left to right(considering operators with left-to-right associativity). If any temporary result is found to be out of range, then that is converted accordingly to fit in the required range, before moving forward with next operation.


UPDATE 2: -

So, instead of: -

long thirtyYearWithL = 1000*60*60*24*30*365L; 

if you move your 365L at the start, then you will get the correct result: -

long thirtyYearWithL = 365L*1000*60*60*24*30; // will give you correct result 

Because, now your temporary result will be of type long, and is capable of holding that value.

like image 149
Rohit Jain Avatar answered Oct 19 '22 23:10

Rohit Jain