Reputation: 6907
I am trying to run the following code,
public class MyClass {
public static void main(String args[]) {
long x = 1 << 39;
long l = 537150415L;
l = l | x;
System.out.println(x);
System.out.println(l);
}
}
This outputs,
128
537150415
I was expecting x
to be a large number. 128
looks like 2^7
, which is 2^(39-32)
. But I thought long is 64 bits.
I am trying to make a bitset of numbers present in set. The numbers can be between 1-60.
JDoodle link - [https://www.jdoodle.com/online-java-compiler#&togetherjs=uH49U5c4Ej]
Upvotes: 1
Views: 954
Reputation: 719596
The problem is that 1 << 39
is a 32 bit expression. So
long x = 1 << 39;
first calculates a 32 bit value, then sign extends that to a 64 bit value for the assignment.
If you want to create a 64 bit mask, use 1L << 39
.
Upvotes: 4
Reputation: 157
The problem with java is, that int
is what would be int32_t
in c++ and long
is int64_t
, there are no unsigned types.
That means you have to take the two's complement into consideration, so when the upper bit is set, you have -2^64.
If you only care for a bitset, you shouldn't print the long's directly however. Do something like this:
for (int i = 0; i < 64; i++) {
System.out.println((l & (1 << i)) != 0 ? "Bit " + i + " is set" : "Bit " + i + " is not set");
}
Edit: Okay, while it's not the problem here, I'll leave the answer for the sake of completeness (because those indeed are pitfalls to consider)
Upvotes: -1
Reputation: 522741
You need to use 1L
instead of 1
to represent 1 as a literal long
:
long x = 1L << 39;
long l = 537150415L;
l = l | x;
System.out.println(x);
System.out.println(l);
Upvotes: 4