Reputation: 7277
Why does this java code
long a4 = 1L;
long a3 = 1;
long a2 = 100L * 1024 * 1024 * 1024;
long a1 = 100 * 1024 * 1024 * 1024;
System.out.println(a4);
System.out.println(a3);
System.out.println(a2);
System.out.println(a1);
when run, output
1
1
107374182400
0
instead of the expected
1
1
107374182400
107374182400
output?
Upvotes: 2
Views: 4592
Reputation: 6276
As per the documentation of Lexical Literals it is mentioned that,
The type of a literal is determined as follows:
- The type of an integer literal (§3.10.1) that ends with L or l is long (§4.2.1).
- The type of any other integer literal is int (§4.2.1).
Thus your expression, 100 * 1024 * 1024 * 1024
is evaluated as int
primitive data type because l
or L
is not mentioned in any numeric value. and the result is 107374182400
i.e. in Binary it is 1 1001 0000 0000 0000 0000 0000 0000 0000 0000
and int
is 32-bit so low 32-bit are taken as mentioned in Example 4.2.2-1. Integer Operations which results to 0
It is also mentioned in same documentation that,
If an integer operator other than a shift operator has at least one operand of type long, then the operation is carried out using 64-bit precision, and the result of the numerical operator is of type long. If the other operand is not long, it is first widened (§5.1.5) to type long by numeric promotion
It means any value in expression contains l
or L
then all the int
values will be expanded to 64 bit.
EDIT In the comment it is also asked
Why doesn't it go negative?
I think it also answers the above question
Upvotes: 2
Reputation: 15408
long a2 = 100L * 1024 * 1024 * 1024;
In this operation however at least one operand is long
. hence the operation is carried out using 64-bit precision, and the result of the numerical operator is of type long
. The other non-long operand are
widened to type long
by numeric promotion and resulted value gets stored to to variable a2
.
long a1 = 100 * 1024 * 1024 * 1024;
The constant expression of plain integer, the result of the expression was computed as a type int
. The computed value however too large to fit in an integer and hence overflowed, resulting in 0
and gets stored to a1
variable.
Edit: As is asked in the following comment:
Why doesn't it go negative?
Because while in integer computation the second computation is equivalent to 25 * 2^32
where ^
has the power meaning and 2^32
integer value is 0
. However, to explain why it's value is 0
: In binary:
100 * 1024 * 1024 * 1024 == 25 * 2^32;
Integer.MAX_VALUE = 2 ^ 31 -1 = 0 11111111 11111111 11111111 1111111
Integer.MAX_VALUE + 1 = 2 ^ 31 = 1 00000000 00000000 00000000 0000000
2 ^ 31
is a negative integer(-2147483648
) as the sign bit is 1
And hence 2 ^ 32
is just a multiplication of 2
to 2 ^ 31
: a left shift and the sign bit will become 0
and hence the result is 0
.
Check out the java language specification: 4.2.2: Integer operation
for details.
Upvotes: 6
Reputation: 17226
107374182400 is exactly 25 times the full range of an integer (2^32), which means that if you try to fit it into an integer it will overflow. And because it would fit exactly 25 times it ends up precisely on 0 (this is a coincidence and other huge multiplications may end up either positive or negative). And you are using an integer right up to the point you cast to long
long a1 = 100 * 1024 * 1024 * 1024;
is equivalent to
int temp = 100 * 1024 * 1024 * 1024;
long a1 = (long)temp;
If you put a single long in the expression, it is forced to use long maths not integer maths which removes the problem
Upvotes: 5
Reputation: 497
Number 3 worked because you specified a long type which is 100L. Thats why it is a long multiplication and could be stored. On the other hand number 4 is an integer multiplication with max value 2^32-1 thats why you got an overflow and the zero default valued appeared.
Upvotes: 0
Reputation: 1432
In Java, if you have int * int, it will compute the output as an int. It only gives the result as a long if you do int * long. In your case, the 100 * 1024 * 1024 * 1024 has a result that overflows int.
So, adding a "L" makes the operand to be a long, and the computation stores the values in long. And of course, no overflow occurs and a correct result can be outputed (i.e. a2).
Upvotes: 0
Reputation: 7890
reason is integer overflow
as output of 100 * 1024 * 1024 * 1024;
is an integer(int
) not long
and in long a2 = 100L * 1024 * 1024 * 1024;
you are specifying that one of the value is long
(here 100L
) and multiplication with that value results in long
value which gets correctly stored in a2
Upvotes: 0
Reputation: 4900
Here's what you did :
You assigned 100 * 1024 * 1024 * 1024
to a long data type but you didn' said that 100 * 1024 * 1024 * 1024
is a long value
By default java compiler thinks that its an integer. Since integer cannot hold that much value, it will show wrong result. Hope it helps !
Upvotes: 0
Reputation: 4262
long a4 = 1L;
//No problem in this
long a3 = 1;
//here left side primitive is considered as integer and at the time of assignment it will be casted to long so again result is as expected
long a2 = 100L * 1024 * 1024 * 1024;
(here you have used 100L so others will be type casted to Long so expected output)
long a1 = 100 * 1024 * 1024 * 1024;
(as by default any primitive digit is considered as int in java, it will consider this as integer multiplication so it goes out of range and results in 0)
Upvotes: 1
Reputation: 227
It might be that the expression on the right of a1
is first calculated as an int
and later on converted to long
. If it equals 0
as an int
it'll stay 0
as a long
Upvotes: 4