疯狂kotlin讲义连载之运算符和表达式——位运算符

2,545 阅读5分钟
3.2位运算符


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位运算符的只能对IntLong两种数据类型起作用。位运算符的运算法则如表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.kt
println(5 and 9) //将输出1

println(5 or 9) //将输出13


程序执行的结果是:
5 and 9的结果是15 or 9的结果是13。下面介绍运算原理。



5的二进制码是00000101(省略了前面的240),而9的二进制码是00001001(省略了前面的240)。运算过程如图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的右移运算符有两个:shrushr,对于shr
运算符而言,把第一个操作数的二进制码右移指定位数后,左边空出来的位以原来的符号位填充,即如果第一个操作数原来是正数,则左边补0;如果第一个操作数是负数,则左边补1
ushr是无符号右移运算符,它把第一个操作数的二进制码右移指定位数后,左边空出来的位总是以0填充。



看下面代码(程序清单同上):

//输出-2

println(-5 shr 2)


//输出1073741822

println(-5 ushr 2)


下面用示意图来说明shrushr运算符的运算过程。


从图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位就相当于乘以2n次方,右移n位则是除以2n次方。不仅如此,进行移位运算不会改变操作数本身,只是得到了一个新的运算结果,而原来的操作数本身是不会改变的。

以上内容节选自《疯狂Kotlin讲义》:一本让您最直接认识Kotlin的疯狂讲义


本书即将于2017年11月发售 敬请期待

往期连载