0

Why does this expression always result in -2,147,483,648 (11111111 11111111 11111111 11111111)? I don't get it. data[] is a byte-Array filled with some values.

(((int)data[29] & 0x00000001) << 31) | (((int)data[30]&0x000000FF)<<12) | (((int)data[31]&0x000000FF)<<4) | (((int)data[32]&0x000000FF)>>>4)

Thanks.

diginoise
  • 7,352
  • 2
  • 31
  • 39
Armai
  • 162
  • 1
  • 1
  • 10
  • 1
    I think to solve this problem we need to know the initial value of `data[29]` thru `data[32]`. – John Wu Dec 19 '17 at 17:20
  • 2
    What language? What is the actual data type of `data`? What platform are you running on? What are you assigning this expression to, and what's its data type? – lurker Dec 19 '17 at 17:22
  • I guess this is Java. And `(int)data[32]&0x000000FF)>>>4` would be equivalent to `(int)data[32]&0x000000F0)>>>4` because the 4 least significant bits will be discarded anyway – phuclv Dec 19 '17 at 17:28
  • These are the fields data[29] to data[32]: 00101001 11111111 11111001 11001111 And yes, it is Java! – Armai Dec 19 '17 at 17:47

1 Answers1

0

I don't think your expression always returns min value of signed int. if all values in data array were zero, it would return zero.

I also don't think this would result in setting all bits to ones.

Following code (Java) where I use Integer.MAX_VALUE:

int max = Integer.MAX_VALUE;    //(2^31 - 1) - all bits apart from the sign are 1
System.out.print(Integer.toBinaryString(((max & 0x00000001) << 31) | ((max&0x000000FF)<<12) | ((max&0x000000FF)<<4) | ((max&0x000000FF)>>>4)));

returns:

10000000000011111111111111111111

using provided values:

System.out.print(Integer.toBinaryString(
        ((0b00101001 & 0x00000001) << 31) |
        ((0b11111111 & 0x000000FF) << 12) |
        ((0b11111001 & 0x000000FF) << 4)  |
        ((0b11001111 & 0x000000FF ) >>> 4))
);

returns:

10000000000011111111111110011100
diginoise
  • 7,352
  • 2
  • 31
  • 39
  • Can you test it with these values? data[29] to data[32]: 00101001 11111111 11111001 11001111 – Armai Dec 19 '17 at 17:51
  • it can't set all bits to one because it doesn't set all the bits in the result – phuclv Dec 20 '17 at 03:09
  • Finally, I found out that ((int)data[29] & 0x00000001) << 31) is always returning Integer-MIN value. When I decrease the number of shifts from 31 to something like 15, this is not happening anymore. Is this a particular runtime behaviour of my device? I am testing on a smartphone with Android 5. – Armai Dec 20 '17 at 10:58
  • Most significant bit encodes a sign in Java. On top of that Java ints are encoded using 2complement encoding where 100...00 is the lowest value. Nothing wrong with the device and it is how Java / JVM encodes integers. See here: https://en.m.wikipedia.org/wiki/Two%27s_complement – diginoise Dec 21 '17 at 00:15