0

I'm am using java longs to store bit sequences, and I want to edit them with a given position. Firstly, here is how I declare and initialize my bits.

long singleBit = 0b0000000000000000000000000000000000000000000000000000000000000000L;

First of all, is there any easier way to initialize a 64bit in java? Anyways, I then use the shift left operator to try and edit the bit sequence.

System.out.println(Long.toBinaryString( singleBit | 1 << 62));

Basically what I want is to insert a 1 on the 62nd index of this sequence, but when I print it out, it gives me this:

1000000000000000000000000000000

Clearly lacking a lot of trailing 0s. It also malfunctions for the 63rd index, and many others towards the end of the sequence. Is there any reason for this? I am fairly comfortable with bit operations but this has me puzzled. If, instead of using just "1" in the shift statement, I use something like this in its place :

long oneBit = 0b0000000000000000000000000000000000000000000000000000000000000001L;

then it works, but it throws off my OR statement. Is there a reason that this one is not behaving correctly? Thanks.

6
  • Please show a complete code example that we can copy/paste and run ourselves. Commented Mar 3, 2021 at 0:27
  • You should double check the types of your values. For example 1 is an int, not a long. Commented Mar 3, 2021 at 0:27
  • "but it throws off my OR statement" What does this mean? A complete example that doesn't leave us guessing what code you are running will make your question much more clear. Commented Mar 3, 2021 at 0:30
  • The bitwise shift << has a higher operator precedence than the bitwise OR |, so 1 << 62 runs first. There's a problem here though: 1 and 62 are both 32-bit integers, so when you shift left 62 bits, it has to roll over when it runs out of bits. So it does shift over 62 bits, it just went over all 32 bits, wrapped around, and went another 30 bits, so when you print it, you get the appropriate 30 trailing zeroes. Commented Mar 3, 2021 at 0:31
  • 1
    As for an easier way to initialize a 64-bit, 0b0000000000000000000000000000000000000000000000000000000000000000L is equivalent to 0L in Java. There's no reason to type out all those zeroes, both ways will compile to the exact same byte code. Commented Mar 3, 2021 at 0:33

3 Answers 3

1

First of all, is there any easier way to initialize a 64bit in java?

Yes, use hex instead:

long singleBit = 0x00000000;

If you want to explicitly set the first bit without any bit operations, you can do

long singleBit = 0x80000000;

Basically what I want is to insert a 1 on the 62nd index of this sequence, but when I print it out, it gives me this:

This is because 1 is an int. Use 1L for a long literal.

Sign up to request clarification or add additional context in comments.

2 Comments

I get what you are saying. Is the 0b in front of the long still needed when using just "1L"?
@nick17 You can specify the value in binary or hex if you wish. Doing so is primarily for humans reading your code. If you think that 0x0000001L or 0b000000001 (I'm not going to type 63 zeros) makes your intent more clear, then go for it.
1

The problem is 1 << 62

1 is an int (32 bits), not a long. Surprisingly, on many architectures, when you shift an int, only the lower 5 bits of the shift are used.

The shift you specified as 62 ends up being (62%32) = 30.

Comments

0

You should check out BitSet. It is used primarily for manipulating arbitrarily large bit strings but you can work with any size. It has many methods that are very useful. Here is how one might do what you were trying.

BitSet b = new BitSet();
b.set(62);
System.out.println(Long.toBinaryString(b.toLongArray()[0]));
// or
b.set(10,23);
System.out.println(b.toString()); // shows just the bits that are set
System.out.println(Long.toBinaryString(b.toLongArray()[0]));

Prints

100000000000000000000000000000000000000000000000000000000000000
{10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 62}
100000000000000000000000000000000000000011111111111110000000000

Comments