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.pswp.cn/news/916514.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/916514.shtml
英文地址,请注明出处:http://en.pswp.cn/news/916514.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

墨者:通过手工解决SQL手工注入漏洞测试(MongoDB数据库)

一、SQL手工注入漏洞测试(MongoDB数据库) 本文以墨者学院靶场为例,演示MongoDB数据库的手工SQL注入全过程。靶场以自己的地址为准:http://124.70.71.251:42286/new_list.php?id1 二、注入原理说明 MongoDB作为NoSQL数据库,其注入方式与传…

Kafka——CommitFailedException异常处理深度解析

引言在分布式消息系统Kafka的生态中,消费者组(Consumer Group)机制是实现高吞吐量和负载均衡的核心设计。然而,消费过程中位移提交(Offset Commit)的稳定性始终是开发者面临的最大挑战之一。当消费者尝试提…

kafka的部署和jmeter连接kafka

zookeeper的安装 kafka依赖Zookeeper所以要先安装Zookeeper kafka的安装文章引用来源:Kafka下载和使用(linux版)-CSDN博客 通过wget命令安装 # 安装wget https://downloads.apache.org/zookeeper/stable/apache-zookeeper-3.7.1-bin.tar.gz# 解压tar…

Android UI 组件系列(八):ListView 基础用法与适配器详解

博客专栏:Android初级入门UI组件与布局 源码:通过网盘分享的文件:Android入门布局及UI相关案例 链接: https://pan.baidu.com/s/1EOuDUKJndMISolieFSvXXg?pwd4k9n 提取码: 4k9n 一、引言 在上一篇文章《Android UI 组件系列(…

Android学习专题目录(持续更新)

1.Android 调试 1.1:Logcat日志分析 2.Android编译 2.1:android编译过程中的mk文件和bp文件的扫描机制 2.2:Android 构建系统中常见的 .mk 文件及其作用 2.3:Android构建系统中的mk文件语法函数 2.4:安卓中定…

c#Lambda 表达式与事件核心知识点整理

一、Lambda 表达式1. 概念 Lambda 表达式是一种匿名函数(无名称的函数),简化了委托和匿名方法的写法,格式为: (参数列表) > 表达式或语句块 它可以作为参数传递,或赋值给委托类型变量。2. 基本语法与简写…

Springboot+Layui英语单词学习系统的设计与实现

文章目录前言详细视频演示具体实现截图后端框架SpringBootLayUI框架持久层框架MyBaits成功系统案例:参考代码数据库源码获取前言 博主介绍:CSDN特邀作者、985高校计算机专业毕业、现任某互联网大厂高级全栈开发工程师、Gitee/掘金/华为云/阿里云/GitHub等平台持续输…

主要分布于内侧内嗅皮层的层Ⅲ的边界向量细胞(BVCs)对NLP中的深层语义分析的积极影响和启示

边界向量细胞(Boundary Vector Cells, BVCs)主要分布于内侧内嗅皮层(MEC)层Ⅲ,通过编码环境边界(如墙壁、障碍物)的距离和方向信息,为空间导航提供几何参考框架。这一神经机制对自然…

Selenium是解决了什么问题的技术?

Selenium 是一种用于自动化浏览器操作的技术,主要解决了以下问题:1. 自动化测试 Selenium 最初是为了解决 Web 应用程序的自动化测试 问题而设计的。它可以帮助开发者和测试人员: 模拟用户操作:如点击按钮、填写表单、选择下拉菜单…

JavaSE知识点(2)

目录 访问修饰符的区别 this关键字的作用 抽象类和接口有什么区别 抽象类可以定义构造方法吗 但是接口不可以定义构造方法 Java支持多继承吗 接口可以多继承吗 继承和抽象的区别? 抽象类和普通类的区别 成员变量和局部变量的区别? staic关键字…

(实用教程)Linux操作系统(二)

centos配置静态ip 注意: 1.系统中的网关要与虚拟机编辑器中的网关保持一致 2.如果配置虚拟机编辑器后发现ping不通外网的时候,就要还原默认设置再进行配置 总结: 虚拟机编辑器需要配置ip,网关,其中ip网段以及最后一…

ThinkPHP8集成RabbitMQ的完整案例实现

ThinkPHP8集成RabbitMQ的完整案例实现一、安装依赖:需通过Composer安装php-amqplib库‌二、配置RabbitMQ三、生产者1、发送一个邮件,将任务发送到RabbitMQ队列中。2、运行结果展示四、启动消费者:命令行执行php think rabbitmq:consumer1&…

解密负载均衡:如何轻松提升业务性能

什么是负载均衡 负载均衡:Load Balance,简称LB,是一种服务或基于硬件设备等实现的高可用反向代理技术,负载均衡将特定的业务(web服务、网络流量等)分担给指定的一个或多个后端特定的服务器或设备,从而提高了 公司业务的…

mac neo4j install verifcation

本文使用conda环境安装,neo4j所依赖jdk也采用conda install的方式安装。 1 neo4j下载 点击如下链接,选择community, Linux/Mac Executor,点击Download Community。 本文下载的安装包是 neo4j-community-2025.06.2-unix.tar.gz 2 安装neo4j …

【Oracle】Oracle分区表“排雷“指南:当ORA-14400错误找上门时如何优雅应对

引言:分区表里的"定时炸弹"凌晨三点的机房,你盯着屏幕上刺眼的ORA-14400: 插入的分区键值超出所有分区范围错误,后背发凉。这个错误就像埋在分区表里的定时炸弹,一旦触发就会让整个应用瘫痪。但别慌!本文将带…

设计模式(十四)行为型:职责链模式详解

设计模式(十四)行为型:职责链模式详解职责链模式(Chain of Responsibility Pattern)是 GoF 23 种设计模式中的行为型模式之一,其核心价值在于将多个处理对象(处理器)连接成一条链&am…

WAIC 2025 热点解读:如何构建 AI 时代的“视频神经中枢”?

一、🌐 WAIC 2025 大会看点:AI 正在“长出眼睛与身体” 在 2025 年的人工智能大会(WAIC 2025)上,“大模型退幕后,具身智能登场”成为最具共识的趋势转向。从展区到主论坛,再到各大企业发布的新…

OpenCV+Python

安装 OpenCV: Python:直接 pip install opencv-python(核心库)和 opencv-contrib-python(扩展功能)。 pip install opencv-python pip install opencv-contrib-python 验证安装: import cv2…

现代C++的一般编程规范

一般情况下不要使用std::endl,尤其是在循环中,因为可能一开始你只是想要打印一个换行符,但是"endl"做的更多,其还会刷新缓冲区,这会额外花费很多时间,相反,只需要使用“\n"&…

38.安卓逆向2-frida hook技术-过firda检测(三)(通过SO文件过检测原理)

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于:图灵Python学院 工具下载: 链接:https://pan.baidu.com/s/1bb8NhJc9eTuLzQr39lF55Q?pwdzy89 提取码&#xff1…