当前位置: 首页 > 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.lryc.cn/news/601570.html

相关文章:

  • rust-模块树中引用项的路径
  • Python调用大模型api并部署到前端的主流技术栈以及具体框架对比
  • SecureCRT连接密钥交换失败
  • 问津集 #2:High Compression and Fast Search on Semi-Structured Logs
  • CPA全国青少年编程能力等级测评试卷及答案 Python编程(二级)
  • 第六章 JavaScript 互操(3)JS调用.NET
  • 攻击者可能会试图从bd.tao234窃取您的信息
  • 2024-2025华为ICT大赛中国区 实践赛网络赛道(高教组)全国总决赛 理论部分真题+解析
  • Sklearn 机器学习 数值指标 混淆矩阵confusion matrix
  • RS485转Profinet网关与JRT激光测距传感器在S7-1200 PLC系统中的技术解析与应用
  • 29.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--单体转微服务--用户配置服务
  • GitHub 趋势日报 (2025年07月25日)
  • 9.SpringBoot Web请求参数绑定方法
  • 设计模式(九)结构型:组合模式详解
  • 设计模式(四)创建型:生成器模式详解
  • 第四科学范式(数据密集型科学):科学发现的新范式
  • NLP学习开始01-线性回归
  • 多租户Kubernetes集群架构设计实践——隔离、安全与弹性扩缩容
  • Vue基础(25)_组件与Vue的内置关系(原型链)
  • 马尔可夫链
  • MYSQL-- 行锁在索引命中与覆盖情况下的加锁行为
  • 随机密码生成
  • RTSP|RTMP播放器 in Unity:开源不够用?从工程视角重新定义播放器选型
  • Tkinter美化 - 告别土味Python GUI
  • 设计模式(二)创建型:工厂方法模式详解
  • 哈希表应用(map,set共同作用)
  • ubuntu18.04解压大的tar.gz文件失败
  • MySQL 全详解:从入门到精通的实战指南
  • vulhub-red靶机攻略
  • 优化Linux高并发:文件描述符与端口范围的协同调优