1. 简介

是的,Kotlin 也支持位运算。尽管没有像 C 系语言那样使用常见的符号,比如 <<*, *>>, |, &, 和 ^,但 Kotlin 提供了基于 IntLong 类型的函数来完成这些操作。

Kotlin 社区曾就是否支持位运算符进行了长达十年的讨论:KT-1440。支持者认为这是某些底层领域(如音频或视频处理)的刚需;反对者则认为可读性更重要,过多使用位运算会让代码难以理解。

目前,Kotlin 选择通过函数的方式来支持位运算。

2. Kotlin 位运算与 Java 的对比

大多数开发者都接触过位运算。下面对比 Kotlin 与 Java 的语法差异:

操作名称 Java 运算符 Kotlin Int/Long 方法
按位与(AND) a & b a and b
按位或(OR) a | b a or b
异或(XOR) a ^ b a xor b
取反(Inversion) ~a a.inv()
左移(Shift Left) a << b a shl b
有符号右移(Signed Right Shift) a >> b a shr b
无符号右移(Unsigned Right Shift) a >>> b a ushr b

Java 还支持复合赋值操作符,如 |=,但在 Kotlin 中需要手动写成 a = a or b

3. 位运算是如何工作的

了解了 Kotlin 的语法后,我们来看看这些操作到底对数据做了什么。

3.1. 按位与、按位或、取反

这些操作与逻辑运算类似,但作用于每个 bit 上:

val a = 0b10011 // 19
val b = 0b11110 // 30
assert(a and b == 0b10010) // 18

按位或:

val a = 0b101001 // 41
val b = 0b110011 // 51
assert(a or b == 0b111011) // 59

异或:

val a = 0b110101
val b = 0b101010
assert(a xor b == 31) // 11111

取反是最简单的,所有 0 变 1,1 变 0。但注意 Int 是 32 位,Long 是 64 位,所以对短于 32 位的二进制数取反后,需要使用 and 掩码处理高位:

assert(0b101100.inv() and 0b111111 == 0b010011)

3.2. 位移操作

位移操作就是将二进制数整体左移或右移指定位数:

assert(0b110011 shl 2 == 0b11001100)

✅ 左移只有一种,但右移有两种:有符号和无符号。

  • **无符号右移 (ushr)**:左边补 0,结果始终为正。
assert(-0b1100110011 ushr 22 == 0b1111111111)
  • **有符号右移 (shr)**:左边补原最高位,保留符号不变。
assert(0b1100110011 shr 2 == 0b11001100) 
assert(0b11111111111111111111110011001101 shr 2 == 0b111111111111111111111100110011)

4. 位运算的应用场景

虽然位运算看起来简单,但在底层处理中非常高效,很多 CPU 指令只需一个周期即可完成。例如:

  • 左移 = 乘以 2^n
  • 右移 = 除以 2^n
assert(12 shr 2 == 3) // 12 / 4
assert(3 shl 3 == 24) // 3 * 8

相比普通的乘除法,位运算效率更高。

4.1. 位掩码(Bitmask)

位掩码常用于标志位管理。比如判断某个 flag 是否开启:

val SKY_IS_BLUE_MASK = 0b00000000000001000000000000

fun isSkyBlue(worldProperties: Int): Boolean = 
    worldProperties and SKY_IS_BLUE_MASK != 0

assert(isSkyBlue(0b10011100111101011101010101))

4.2. 合并多个标志位

使用 or 可以将多个标志合并:

val SKY_IS_BLUE = 0b00000000000001000000000000
val SUN_IS_SHINING = 0b00000000000000100000000000
val skyIsBlueAndSunShines = SKY_IS_BLUE or SUN_IS_SHINING // 0b00000000000001100000000000

这种方式节省内存,且操作高效,适合嵌入式系统、协议解析、权限控制等场景。

5. 总结

✅ Kotlin 支持完整的位运算功能,虽然语法与 Java 不同,但功能完全一致。这些操作通过 IntLong 类型的扩展函数实现,除了取反使用 inv()

⚠️ 由于没有直接使用符号,初学者可能会觉得不够直观,但对于有经验的开发者来说,这种设计更有利于代码可读性和维护性。

位运算在以下领域非常有用:

  • 高性能计算
  • 信号处理
  • 紧凑数据结构
  • 权限/状态标志管理

所有示例代码可在 GitHub 上找到:GitHub 示例链接


原始标题:Using Bitwise Operators in Kotlin