当前位置: 首页 > news >正文

Kotlin位运算

Kotlin 提供了几种用于操作整数各个位(bit) 的运算符。这些操作是由处理器直接支持的,速度快且操作简单。在底层编程中非常重要,比如设备驱动、低级图形处理、网络通信、加密和压缩等。

尽管计算机通常都有高效的硬件指令来执行算术和逻辑操作,但所有这些操作也都可以通过组合按位操作符位移操作符判断 0 操作来实现。


位运算符(Bitwise Operators)

共有四种位运算符:

  • inv():按位非(NOT),即取反或补码

  • or:按位或(OR)

  • and:按位与(AND)

  • xor:按位异或(XOR)

这些运算符会一位一位地处理操作数的每一位,并生成一个新的数值。

  • inv() 是一元运算符,它会将每一位的 0 变为 1,1 变为 0(包括符号位也会改变)。

  • or 是二元运算符,按位“或”:只要任意一个操作数为 1,结果就是 1,否则是 0。

  • and 是按位“与”:只有两个操作数都为 1,结果才是 1,否则是 0。

  • xor 是按位“异或”:当两个操作数中正好一个为 1 时,结果是 1,否则是 0。

这些运算符不仅可以作用于整数,也可以作用于布尔类型。如果是整数,进行的是位运算;如果是布尔值,进行的是逻辑运算(除了 inv() 不能用于布尔类型)。


示例:按位与、或、异或

val first = 15  // 二进制:1111
val second = 10 // 二进制:1010val bitwiseAnd = first and second // 1111 & 1010 = 1010,结果是 10
val bitwiseOr = first or second   // 1111 | 1010 = 1111,结果是 15
val bitwiseXor = first xor second // 1111 ^ 1010 = 0101,结果是 5

示例:按位取反(inv)

val first = 35   // 二进制:0..00100011
val second = -35 // 二进制:1..11011101(补码)val inverseFirst = first.inv()     // ~35 = -36
val inverseSecond = second.inv()   // ~-35 = 34

为什么 ~35 = -36?这是因为 Kotlin 使用**补码(two’s complement)**来表示整数。

  • 对任意正整数 n,其按位取反是 -(n + 1)

  • 对负数 -n,其按位取反是 n - 1


检查一个数是否能被 2 整除(使用 and

val a = 5
val b = 4val bitwiseAndA = a and 1 // 101 & 001 = 001,结果是 1 => 有余数,不能整除
val bitwiseAndB = b and 1 // 100 & 001 = 000,结果是 0 => 没有余数,可以整除

位移操作符(Bit-shift Operators)

Kotlin 还提供了三种位移操作符:

  • shl:左移(乘法),低位补零;

  • shr:带符号右移,高位填符号位(保留正负号);

  • ushr:无符号右移,高位补零(结果永远为正)。

示例:通过位移实现快速乘除法

var value = 25   // 二进制:0001 1001value = value shl 1 // 左移1位:0011 0010 => 50
value = value shl 2 // 再左移2位:1100 1000 => 200var anotherVal = 14
anotherVal = anotherVal shr 1 // 右移1位:0111 => 7

我们可以总结出:

var newVal = 25newVal = newVal shl 1 // 25 * 2^1 = 50
newVal = newVal shl 3 // 50 * 2^3 = 400
newVal = newVal shr 2 // 400 / 2^2 = 100

示例:使用位移求区间中点

val left = 10
val right = 20val mid = (left + right) shr 1 // 结果是 15

(left + right) / 2 相同,但位移方式更快。


示例:shrushr 的区别

val number1 = 5
val number2 = -5val shrNumber1 = number1 shr 1     // 0101 → 0010,结果是 2
val ushrNumber1 = number1 ushr 1   // 同上,结果是 2
val shrNumber2 = number2 shr 1     // 保留符号,结果是 -3
val ushrNumber2 = number2 ushr 1   // 补零,结果是 2147483645
  • shr 会根据符号保留符号位。

  • ushr 总是左边补 0,所以负数也变为正数。


Kotlin 1.6 新增:位旋转

val a = 4val shiftRight = a.rotateRight(1) // 0100 → 0010,结果是 2
val shiftLeft = a.rotateLeft(1)   // 0100 → 1000,结果是 8
val b = 3val shiftLeft = b.rotateLeft(1)   // 0011 → 0110,结果是 6
val shiftRight = b.rotateRight(1) // 0011 → 1..0001,结果是 -2147483647

rotateRight 会把最高位 1 移到符号位(第 31 位),结果变成负数。


运算优先级

Kotlin 中,位运算符和位移运算符的优先级低于加减乘除:

优先级(从高到低)运算符例子
括号(expr)
后缀自增自减expr++, expr--
前缀正负、自增自减-expr, ++expr, --expr
乘、除、模*, /, %
加减+, -
赋值及其组合=, +=, -=, *=
位运算和位移and, or, xor, shl, shr, ushr
位运算符之间是从左到右执行的。

例如:

val mid = left + right shr 1

无需加括号,是因为 + 的优先级高于 shr,相当于:

val mid = (left + right) shr 1

总结

在本节中,我们学习了如何对整数的进行操作,理解了位运算与一些算术运算之间的对应关系:

  • 位运算符:逐位处理。

  • 位移运算符:可以整体左移或右移一整串位。
    虽然位运算看起来稍显复杂,但这是理解底层编程和高效计算的基础。

http://www.dtcms.com/a/300541.html

相关文章:

  • EMCCD相机与电可调变焦透镜的同步控制系统设计与实现
  • Kotlin递归
  • MYSQL:索引
  • golang设置http代理
  • Flink2.0学习笔记:Stream API 常用转换算子
  • maven <dependencyManagement>标签的作用
  • 基于开源AI智能名片链动2+1模式S2B2C商城小程序的人格品牌化实现路径研究
  • 常用git命令集锦
  • conda和pip安装包时的注意细节,以及下载慢时如何配置镜像地址
  • 积分兑换小程序Java
  • Megatron 中的 TensorParallel, PipelineParallel, ContextParallel,ExpertParallel
  • PHP框架之Laravel框架教程:3. 数据库操作(简要)
  • PowerDesigner 画ER图并生成sql 教程
  • 【学习笔记】MimicGen: 基于人类演示的可扩展机器人学习数据生成系统
  • GIt学习——分布式版本控制工具
  • STL——list
  • 金融科技中的虚拟助手
  • 15.7 DeepSpeed实战:单卡38GB到多卡12GB,3倍效率提升的ZeRO-3配置全解
  • 【专题十五】BFS 解决 FloodFill
  • 多智能体系统设计:协作、竞争与涌现行为
  • 2025年7月25日-7月26日 · AI 今日头条
  • 【第六节】方法与事件处理器
  • 【计算机网络架构】网状型架构简介
  • C++ 多线程(一)
  • 详解力扣高频SQL50题之610. 判断三角形【简单】
  • Vscode的常用快捷键(摆脱鼠标计划)
  • [N1盒子] 斐讯盒子N1 T1通用刷机包(可救砖)
  • 金字塔降低采样
  • C语言:顺序表(上)
  • K8S 九 安全认证 TLS