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

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 位运算符的只能对 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.kt
println(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类型的整数移位a shr b,当b>64时,总是先用b对64求余(因为Long类型是64位),得到的结果才是真正移位的位数。

注意:当进行移位运算时,只要被移位的二进制码没有发生有效位的数字丢失(对于正数而言,通常指被移出的位全部都是 0 ),不难发现左移 n 位就相当于乘以 2 n 次方,右移 n 位则是除以 2 n 次方。不仅如此,进行移位运算不会改变操作数本身,只是得到了一个新的运算结果,而原来的操作数本身是不会改变的。

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


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

往期连载

第一期juejin.im/post/59c0b7…

第二期:juejin.im/post/59c1d6…

第三期:juejin.im/post/59e407…

第四期:juejin.im/post/59ed77…

第五期:juejin.im/post/59eec3…

第六期:juejin.im/post/59effb…

第七期:juejin.im/post/59f153…

第八期:juejin.im/post/59f283…

第九期:juejin.im/post/59f686…

第十期:juejin.im/post/59f7ea…

第十一期:juejin.im/post/59f953…

第十二期:juejin.im/post/59fa7e…

第十三期:juejin.im/post/59fc1e…

第十四期:juejin.im/post/59ffcb…

第十五期:juejin.im/post/5a0162…

第十六期:juejin.im/post/5a0271…


相关书籍《疯狂Android讲义》 item.jd.com/11689014.ht…




你可能感兴趣的:(疯狂kotlin讲义连载之运算符和表达式——位运算符)