位运算符 >>, <<, >>>

因为java比较容易被反编译,上周准备把加密算法通过JNI调用的方式用C/C++实现。在java代码中有一个位运算符”>>>”,一开始不知道什么意思网上找了一些资料说是“忽略符号位右移运算”,看了也是一知半解就自己测试了一下。

0x00 二进制

要想了解位运算必须先清除数的二进制表示方法。
以整数为例正整数的二进制是以原码表示:123456789 -> 0111 0101 1011 1100 1101 0001 0101
负数整数则是以补码表示: -2 -> 1111 1111 1111 1111 1111 1111 1111 1101

0x01 左移<<、右移>>

  • 左移
    左移是将二进制整体向左移动某个位数,如将123456789 << 4得到的结果为:0101 1011 1100 1101 0001 0101 0000,右边空出来的位置会填充0

  • 右移
    在正整数的情况下右移和左移操作是一样的,只不过换了一个反向同样都是填充0,但是当负数的情况下填充的则是1了。所以-2 >> 2的到结果则是1111 1111 1111 1111 1111 1111 1111 1111

0x02 运算符>>>

上面说了右移操作要根据是正数还是负数来判断填充0or1,但是>>>没有这个限制,无论是正数还是负数右移后填充的都是0。所以在正数的情况下>>>>>的效果是一样的。负数的情况下如-2 >>> 2得到的则是 00111 1111 1111 1111 1111 1111 1111 1111

因为>>>这个运算符在C/C++中并没有,所以必须自己实现。其实也很简单举个列子-12345>>>5 == (-12345>>5) & 0x07FFFFFF这里是以int类型为例,具体要根据代码的实际情况来判断&后的数。