0

For a programm, i need to shift the bits from the first to the last bit. So i would need to:

long a = 0;
a |= 1L<<64;

Since the long isn't unsigned, it doesn't work. Is there a possibility to shift a 1 to this last Bit? I'm taking a long and not a BigInt, because i'm tried to use as few memory than possible.

WhileTrueSleep
  • 1,524
  • 1
  • 19
  • 32
cortesis
  • 1
  • 2
  • 4
    Try shifting by 63. Since long has 64 bits shifting 1 by 64 will result in 1 since Java actually shifts by `your_value % sizeof(type)` which means in your case it shifts by `64 % 64 = 0`. – Thomas May 03 '17 at 15:02
  • Did you mean 63 instead? Because unless I'm mistaken, shifting it 64 would shirt it out of the length of the variable. – AntonH May 03 '17 at 15:03
  • In fact `a |= 1L << 63` gives the result `-9223372036854775808` which is probably the correct answer – JeremyP May 03 '17 at 15:07
  • of course i thought 63, i need the long as a kind of "array" of bool values. But since the last bit is thought to "sign" the number, i can't reach it.. – cortesis May 03 '17 at 15:07
  • 1
    Signedness is irrelevant. A `long` does have 64 bits, and the 64th bit is "reached" with `1L << 63`. That that bit "is the sign" doesn't matter, it's still a bit. – harold May 03 '17 at 15:10
  • 1
    This question is not a duplicate of the one it is marked a duplicate of. The right answer to this question is "to get to the most significant bit of a long shift by 63, not 64". – JeremyP May 03 '17 at 15:12
  • 1
    Oh, i've got it.. My fault, sorry Thank you all guys :) – cortesis May 03 '17 at 15:15
  • @ruakh ok ok ;) – Thomas May 15 '17 at 06:57

3 Answers3

4

Java will shift by num % sizeof(datatype) only, i.e. if you shift an int by 32 it will effectively be no shift at all. If you shift by 33 the effective shift will be 33 % 32 = 1.

The same is true for long just that the size of long is 64 and thus shifting by 64 is effectively no shift. The highest shift possible with long thus is 63 and that's what you need to get the last bit to position 64 (it already is at position 1 so you just need to shift by 63 places).

Thomas
  • 87,414
  • 12
  • 119
  • 157
1

Shifting by 64 bits will have the effect of not shifting. Shifting by 63 bits will have desired output. Shift on long v << b shifts by b%64 bits. so 1L<<64 shifts by nothing.

public static void main (String[] args) throws java.lang.Exception
{
    long a=1L<<63;
    long b=1L<<64;
    System.out.println(Long.toBinaryString(a));
    System.out.println(Long.toBinaryString(b));
}

Expected output:

1000000000000000000000000000000000000000000000000000000000000000
1
Persixty
  • 8,165
  • 2
  • 13
  • 35
0

First of all, your code doesn't make a lot of sense. If you shift a long variable 64 places to the left, you should end up with zero, since you've shifted away all of the long's original bits.

Second, as you've correctly mentioned, Java treats all ints and longs as singed (as stated here). So it considers a 64 bit shift on a long to be equal to a 0 shift. That's why instead of getting zero, you're left with the original value, which is 1. If you want to initialize a to 1 followed by 63 zeroes I suggest avoiding shifts, and just using something like this:

long a = 0x8000_0000_0000_0000L;

It's readable by anyone who understands binary, and there's not Java bit shift magic involved.

If you want to keep using shift, just use a 63 shift instead:

long a|=1L<<63;
Malt
  • 28,965
  • 9
  • 65
  • 105