October 17, 2017 by LanceShi
Arithmetic shift and logical shift in Apex
In this post, we are going to talk about the differences between arithmetic shift and logical shift in Apex. Before reading this post, I hope you have a basic understanding about how bitwise operators work in Apex. If you don’t, you can refer to Patrick’s wonderful post here.
You may have noticed that in Apex, there is only one left shift operator: <<. But there are two operators >> and >>>. Why? What’s the difference between them.
In order to understand this, let’s do a sample code first.
Integer i = 1000; System.debug(i >> 3); System.debug(i >>> 3); i = -1000; System.debug(i >> 3); System.debug(i >>> 3);
Try to run it yourself! And you will get a result similar to this:
Does it surprise you?
How data is presented in the computer system.
As you can see, there is no difference between two operators when the number is positive. It works exactly as what we would expect from a right shift – moving 3 digits to the right means divided by 8. However, two operators work very differently with negative numbers. Why? That comes down to how we present numbers in my machine.
As we all know, all the numbers are presented as 1s and 0s in the computer machine. In Apex, all the integers are presented as a 32-bit number. But to make things easier, let’s suppose they present the integers in 8 bits in this tutorial, just to make it a bit easier to understand.
All the numbers are presented as a binary number in the system. So it is easy to understand how positive numbers is presented in the system. For example, 2 is presented as 00000010 and 10 is presented as 00001010.
However, how do we present a negative number 0s and 1s? The answer is, for the most significant digit, which is the left most digit, it represents -2^n instead of 2^n. In the 8 digit example, 10000000 means -128 (2^8) in the system, not 128. And in real world 32-digit environment, 100…000 means -2^32.
So what about other negative numbers other than -128? Easy, all the other digits still work the same way as in the positive number. For example, 10000001 simply means -128 + 1 which is -127. And 10001010 means -128 + 10 which is -118.
Explanation about arithmetic shift and logical shift
Now let’s come back to the differences between logical shift and arithmetic shift.
The difference is simple: when doing right shift, logical shift fills the leftmost digits with 0s while arithmetic shift fills with the original left most digits. So for positive numbers, they are doing exactly the same thing – filling with 0s. For a negative number, logical shift still fills the leftmost digits with 0s and arithmetic shift fills with 1s.
For i = 10001000 which is -120. i >> 2 (arithmetic shift) will become 11100010(-30). And i >>> 2 (logical shift) will become 00100010(34). Try to calculate by yourself!
Since the actual Apex world is 32-digits, the logical shift number will be significantly larger.
Hope that makes you better understand how arithmetic and logical shift works in Apex.