4 ms·
One of my favorites; guess the difference between the output of that code: byte a1 = 0x40; byte a2 = (byte) 0x80; a1 >>= 1; a2 >>= 1; System.out.printf("0x%02X
by asksomeoneelse 4y ago
One of my favorites; guess the difference between the output of that code:
byte a1 = 0x40;
byte a2 = (byte) 0x80;
a1 >>= 1;
a2 >>= 1;
System.out.printf("0x%02X\n", a1);
System.out.printf("0x%02X\n", a2);
And that code (note the operator ">>>" instead of ">>"):
byte a1 = 0x40;
byte a2 = (byte) 0x80;
a1 >>>= 1;
a2 >>>= 1;
System.out.printf("0x%02X\n", a1);
System.out.printf("0x%02X\n", a2);
Congrats if you guessed right on your first try, because I certainly did not.
- jrpelkonen 4y agoI don’t know if this classifies as a party trick. If one is aware of the existence of “>>>”, I would presume one would solve this problem without guesswork.
- asksomeoneelse 4y agoSo obvious it's not even fun, right ? And yet... there is a twist ! I don't want to spoil the ending. I encourage people to run the code on their own after they made their guess to compare.
- benmmurphy 4y agoheh. if you know what is happening its guessable. my model which might not be correct is: this `byte a2 = (byte) 0x80` is a cast from the integer 0x80 to a byte and when there is a cast from integer to byte it just truncates the bits. when printing out this value it interprets it as 2s compliment so its 'value' is -128. so it just takes 8 bits starting from the least significant bit. so you end up with the bits 1_000_0000. then when you do this `>>=` operator that promotes to an integer and then it does the right shift then casts back to a byte. the promotion from integer to byte is just done by sign extending the byte to 32 bits. so you get 25 1's followed by 7 0's. the shift is a signed shift so you get 26 1's followed by 6 0's. then the cast back to byte leaves you with 11_000_000 which is why you get the 'weird' result of 0xC0 which is larger than 0x80. and the unsigned shift works in a similar way except the intermediate result is 0 followed by 25 1's followed by 6 0s. but this values in the high bits have no effect after the truncation which is why you get the same result. you need to do `a2 & 0xFF` to clear out the sign bits outside the byte range before applying the shift in order to do the unsigned byte to unsigned int (or signed int?) promotion correctly. but using unsigned types in java is super dangerous.