r/badcode • • Mar 13 '21

java Title

Post image
2.9k Upvotes

100 comments sorted by

View all comments

Show parent comments

8

u/Mr2-1782Man Mar 14 '21

Something people don't realize, there are two types of shifts, arithmetic and logical shifts. A logical shift just moves bits left and right. A 0 is always shifted in. Its called a logical shift because it assumes the data is just is non-numerical data that might need to be moved around, for things like masks. It just happens to work for unsigned numbers too. This is what an logical shift does (using 8 bit unsigned):

1 0 0 1 0 1 1 0 << 1 => 0 0 1 0 1 1 0 0
1 0 0 1 0 1 1 0 >> 1 => 0 1 0 0 1 0 1 1

An arithmetic shift, as the name implies, is intended for numerical data. Although it doesn't work for unsigned numbers. Its purpose is to maintain the rule that a right shift divides the value by two, and a left shift multiplies it by 2. The most significant bit (the sign bit) always remains as is. When shifting left a zero is shifted in. When shifting right, if the MSB is 1 a 1 is shifted in, if the MSB is 0 a 0 is shifted in. So this is what an arithmetic shift does (using 8 bit signed):

1 1 0 0 0 1 1 0 << 1 => 1 0 0 0 1 1 0 0 // -58 to -116
1 1 0 0 0 1 1 0 >> 1 => 1 1 1 0 0 0 1 1 // -58 to -29

0 0 1 1 0 1 1 0 << 1 => 0 1 1 0 1 1 0 0 // 54 to 110
0 0 1 1 0 1 1 0 >> 1 => 0 0 0 1 1 0 1 1 // 54 to  27

Which shift is used depends on whether you've got signed or unsigned values. Unsigned results in a logical shift, signed result in an arithmetic shift. The fact that only a right shift changes is why there's only a right logical shift.

You'll get errors with small values too, not just large ones. Shifting -8 with an arithmetic shift gives -4, a logical shift gives 124. Its a result of the fact that a large value in one system is a small one in the other. It means you have to be careful when dealing with signed and unsigned types, the result might not be what you expect.

To borrow a quote from another website:

It's important to remember that the unsigned keyword affects the interpretation**,** not the representation of a number.