Optimus Prime
Optimus Prime

Reputation: 6907

Long getting treated as 32 bits in Java?

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

Answers (3)

Stephen C
Stephen C

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

MeFisto94
MeFisto94

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

Tim Biegeleisen
Tim Biegeleisen

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

Demo

Upvotes: 4

Related Questions