Kotlin虽然也提供了与Java功能完全相同的位运算符,但这些位运算符都不是以特殊字符给出的,而是以infix函数的形式给出的,因此程序只能用函数名来执行这些位运算符。
Kotlin支持的位运算符同样有如下7个。
1、and(bits):按位与。当两位同时为1时才返回1。
2、or(bits):按位或。只要有一位为1即可返回1。
3、inv(bits):按位非。单目运算符,将操作数的每个位(包括符号位)全部取反。
4、xor(bits):按位异或。当两位相同时返回0,不同时返回1。
5、shl(bits:左移运算符。
6、shr(bits):右移运算符。
7、ushr(bits):无符号右移运算符。
Kotlin位运算符的只能对Int或Long两种数据类型起作用。位运算符的运算法则如表3.10所示。
3.10表
位运算符的运算法则
第一个运算数 | 第二个运算数 | 按位与 | 按位或 | 按位异或 |
0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 | 1 |
1 | 0 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 |
按位非只需要一个操作数,这个运算符将把操作数在计算机底层的二进制码按位(包括符号位)取反。如下代码测试了按位与和按位或运算的运行结果。
程序清单:
codes\03\3.2\BitOperatorTest.ktprintln(5 and 9) //将输出1
println(5 or 9) //将输出13
程序执行的结果是:
5 and 9的结果是1,5 or 9的结果是13。下面介绍运算原理。5的二进制码是00000101(省略了前面的24个0),而9的二进制码是00001001(省略了前面的24个0)。运算过程如图3.1所示。
图3.1按位与和按位或运算过程
下面是按位异或和按位取反的执行代码(程序清单同上)。
println((-5).inv()) //将输出4
println(5 xor 9) //将输出12
程序执行-5按位取反的结果是4,执行5 xor 9的结果是12,下面通过图3.2来介绍运算原理。
图3.2 -5按位取反的运算过程
而5 xor 9的运算过程如图3.3所示。
图3.3 5 xor 9的运算过程
左移运算符是将运算数的二进制码整体左移指定位数,左移后右边空出来的位以0填充。例如如下代码(程序清单同上):
println(5 shl 2) //输出20
println(-5 shl 2) //输出-20
下面以-5为例来介绍左移运算的运算过程,如图3.4所示。
图3.4 -5左移两位的运算过程
在图3.4中,上面的32位数是-5的补码,左移两位后得到一个二进制补码,这个二进制补码的最高位是1,表明是一个负数,换算成十进制数就是-20。
Kotlin的右移运算符有两个:shr和ushr,对于shr
运算符而言,把第一个操作数的二进制码右移指定位数后,左边空出来的位以原来的符号位填充,即如果第一个操作数原来是正数,则左边补0;如果第一个操作数是负数,则左边补1。
ushr是无符号右移运算符,它把第一个操作数的二进制码右移指定位数后,左边空出来的位总是以0填充。
看下面代码(程序清单同上):
//输出-2
println(-5 shr 2)
//输出1073741822
println(-5 ushr 2)
下面用示意图来说明shr和ushr运算符的运算过程。
从图3.5来看,-5右移2位后左边空出2位,空出来的2位以符号位补充。从图中可以看出,右移运算后得到的结果的正负与第一个操作数的正负相同。右移后的结果依然是一个负数,这是一个二进制补码,换算成十进制数就是-2。
图3.5-5右移2位的运算过程
从图3.6来看,-5无符号右移2位后左边空出2位,空出来的2位以0补充。从图中可以看出,无符号右移运算后的结果总是得到一个正数。图3.6中下面的正数是1073741822(230-2)。
图3.6-5无符号右移2位的运算过程
进行移位运算时还要遵循如下规则。
1、对于Int类型的整数移位a shr b,当b>32时,系统先用b对32求余(因为Int类型只有32位),得到的结果才是真正移位的位数。例如,a shr 33和a shr 1的结果完全一样,而a shr 32的结果和a相同。
2、对于Long类型的整数移位ashr b,当b>64时,总是先用b对64求余(因为Long类型是64位),得到的结果才是真正移位的位数。
注意:当进行移位运算时,只要被移位的二进制码没有发生有效位的数字丢失(对于正数而言,通常指被移出的位全部都是0),不难发现左移n位就相当于乘以2的n次方,右移n位则是除以2的n次方。不仅如此,进行移位运算不会改变操作数本身,只是得到了一个新的运算结果,而原来的操作数本身是不会改变的。
以上内容节选自《疯狂Kotlin讲义》:一本让您最直接认识Kotlin的疯狂讲义
往期连载