Lua
语言从 5.3
版本开始提供了针对数值类型的一组标准位运算符。与算术运算符不同的是,位运算符只能用于整型数。位运算符包括:
- 按位与:
&
- 按位或:
|
- 按位异或:
~
- 逻辑右移:
>>
- 逻辑左移:
<<
- 按位取反:
~
提示
按位取反( ~
)为一元运算符;在其他语言中,异或运算符为 ^
,而在 Lua
语言中 ^
表示幂运算。
> string.format("%x", 0xff & 0xabcd) --> cd > string.format("%x", 0xff | 0xadcd) --> abff > string.format("%x", 0xaaaa ~ -1) --> ffffffffffff5555 > string.format("%x", ~0) --> ffffffffffffffff
所有的位运算都针对构成一个整型数的所有位。在标准 Lua
中,也就是 64
位。这对于使用 32
位整型数的算法可能会称为问题(例如, SHA-2
密码散列算法)。不过,要操作 32
位整数也不难。除了右移操作外,只要忽略高 32
位,那么所有针对 64
位整型数的操作与针对 32
位整型数的操作都一样。这对于加法、减法和乘法都有效。因此,在操作 32
位整型数时,只需要在进行右移前抹去高 32
位即可(对于这类计算很少会做除法)。
两个移位操作都会用 0
填充空出的位,这种行为通常被称为逻辑移位。 Lua
语言没有提供算术右移,即使用符号位填充空出的位。我们可以通过向下取整除法( floor
除法),除以合适的 2
的整数次幂来实现算术右移。
Note
x // 16
与算术右移 4
位等价。
移位数是负数表示向相反的方向移位,即 x>>n
与 a<<-n
等价:
> string.format("%x", 0xff << 12) --> ff000 > string.format("%x", 0xff >> -12) --> ff000
如果移位数等于或大于整型表示的位数(标准 Lua
为 64
位,精简 Lua
为 32
位),由于所有的位数都被从结果中移出了,所以结果是 0
:
> string.format("%x", -1 << 80) --> 0