编辑这个页面须要登录或更高权限!

Kotlin 按位和移位操作

Kotlin提供了几种函数(以 infix 形式)来执行按位和移位操作。在本文中,您将借助示例学习在Kotlin中执行位级操作。

仅在两种整数类型(Int和Long)上使用按位运算符和位移位运算符来执行位级运算。

为了执行这些操作,Kotlin提供了7个使用中缀符号的函数。

按位或 (or)

or函数比较两个值的相应位。如果两个位中的任何一个为1,则为1。否则为0。例如,

12 = 00001100 (二进制)
25 = 00011001 (二进制)

12和25的按位或运算
   00001100 or
   00011001
   ________
   00011101  = 29 (十进制)

示例:按位或运算

fun main(args: Array<String>) {

    val number1 = 12
    val number2 = 25
    val result: Int

    result = number1 or number2   // result = number1.or(number2)
    println(result)
}

运行该程序时,输出为:

29

按位与(and)

and 函数比较两个值的相应位。如果两个位都为1,则求值为1。如果两个位中的任意一个为0,则求值为0。例如,

12 = 00001100 (二进制)
25 = 00011001 (二进制)

12和25的按位与运算
   00001100 and
   00011001
   ________
   00001000  = 8 (十进制)

示例:按位与运算

fun main(args: Array<String>) {

    val number1 = 12
    val number2 = 25
    val result: Int

    result = number1 and number2   // result = number1.and(number2)
    println(result)
}

运行该程序时,输出为:

8

按位异或(xor)

xor函数比较两个值的相应位。如果相应的位不同,则为1。如果相应的位相同,则为0。例如,

12 = 00001100 (二进制)
25 = 00011001 (二进制)

12和25的按位异或运算
   00001100 xor
   00011001
   ________
   00010101  = 21 (十进制)

示例:按位异或运算

fun main(args: Array<String>) {

    val number1 = 12
    val number2 = 25
    val result: Int

    result = number1 xor number2   // result = number1.xor(number2)
    println(result)
}

运行该程序时,输出为:

21

按位非  inv()

inv()函数按位非。它使每个0 到 1,以及每个 1 到 0。

35 = 00100011 (二进制)

35的按位补码运算
  00100011 
  ________
  11011100  = 220 (十进制)

示例:按位补码

fun main(args: Array<String>) {

    val number = 35
    val result: Int

    result = number.inv()
    println(result)
}

运行该程序时,输出为:

-36

我们为什么要输出 -36 代替 220

这是因为编译器显示了该数字的2的补码。二进制数的负号。

对于任何整数n,n的2的补数将为-(n + 1)。

 Decimal         Binary                      2's complement
---------       ---------          ---------------------------------------  
0             00000000          -(11111111+1) = -00000000 = -0(decimal)
1             00000001          -(11111110+1) = -11111111 = -256(decimal)
12            00001100          -(11110011+1) = -11110100 = -244(decimal)
220           11011100          -(00100011+1) = -00100100 = -36(decimal)

Note: Overflow is ignored while computing 2's complement.

35的按位补码为220(十进制)。220的2的补码是-36。因此,输出是-36而不是220。

左移运算符 (shl)

shl函数将位模式向左移动一定数量的指定位,并且零位被移到低位位置。

212 (二进制: 11010100)

212 shl 1 evaluates to 424 (二进制: 110101000)
212 shl 0 evaluates to 212 (二进制: 11010100)
212 shl 4 evaluates to 3392 (二进制: 110101000000)

示例:按位左移

fun main(args: Array<String>) {
    val number = 212

    println(number shl 1)
    println(number shl 0)
    println(number shl 4)
}

运行该程序时,输出为:

424
212
3392

右移运算符(shr)

shr函数将位模式向右移位指定位数。

212 (二进制: 11010100)

212 shr 1 计算为 106 (二进制: 01101010)
212 shr 0 计算为 212 (二进制: 11010100)
212 shr 8 计算为 0 (二进制: 00000000)

如果该数字是2的补号,则将标志位移到高位位置。

fun main(args: Array<String>) {
    val number = 212

    println(number shr 1)
    println(number shr 0)
    println(number shr 8)
}

当您运行该程序时,输出将是:

106
212
0

无符号右移运算符(ushr)

ushr函数将零移位到最左边的位置。

示例:有符号和无符号右移

fun main(args: Array<String>) {
    val number1 = 5
    val number2 = -5

    //有符号右移
    println(number1 shr 1)

    //无符号右移
    println(number1 ushr 1)

    //有符号右移
    println(number2 shr 1)

    //无符号右移
    println(number2 ushr 1)
}

运行该程序时,输出为:

2
2
-3
2147483645

注意,对于2的补码,有符号右移函数和无符号右移函数的工作方式是不同的。

2147483645的2的补码是3。