快速了解原码、反码、补码和位运算
我们知道计算机使用的是二进制,我们⽤⼀个字节,也就是8个bit 来表示⼆进制数。
原码
十进制 | 原码 |
2 | 0000 0010 |
-2 | 1000 0010 |
原码其实是最容易理解的,只不过需要利⽤⼆进制中的第⼀位来表示符号位,0表示正数,1表示负数,所 以可以看到,⼀个数字⽤⼆进制原码表示的话,取值范围是 -111 1111 ~ +111 1111 ,换成⼗进制就 是 -127 ~ 127 。
反码
对于计算机来说最好只有加法,这样计算机会更加简单⾼效,我们知道在数学中 5-3=2 ,其实可以转换成 5+(-3)=2 ,这就表示减法可以⽤加法表示,⽽乘法是加法的累积,除法是减法的累积,所以在计算机中只要有加法就够了。 ⼀个数字⽤原码表示是容易理解的,但是需要单独的⼀个bit来表示符号位。并且在进⾏加法时,计算机需要先识别某个⼆进制原码是正数还是负数,识别出来之后再进⾏相应的运算。这样效率不⾼,能不能让计 算机在进⾏运算时不⽤去管符号位,也就是说让符号位也参与运算,这就要⽤到反码。
十进制 | 原码 | 反码 |
2 | 0000 0010 | 0000 0010 |
-2 | 1000 0010 | 1111 1101 |
我们可以看到,对于正数,反码等于原码,对于负数就是符号位保持不变,其余各位对原码取反。那么我们来看⼀下,⽤反码直接运算会是什么情况,我们以 5-3 举例。
5 - 3 = 5+(-3)
十进制 | 原码 | 反码 |
5 | 0000 0101 | 0000 0101 |
-3 | 1000 0011 | 1111 1100 |
5-3
= 5+(-3)
= 0000 0101(反码) + 1111 1100(反码)
= 0000 0001(反码)
= 0000 0001(原码)
= 1
计算结果为1,为什么差了1?我们来看⼀个特殊的运算:1-1
1-1
= 1+(-1)
= 0000 0001(反码) + 1111 1110(反码)
= 1111 1111(反码)
= 1000 0000(原码)
= -0
0+0 运算如下:
0+0
= 0000 0000(反码) + 0000 0000(反码)
= 0000 0000(反码)
= 0000 0000(原码)
= 0
从以上的运算中,我们可以看到1000 0000表示-0,0000 0000表示0,虽然-0和0是⼀样的,但是在⽤原码和反码表示时 是不同的,我们可以理解为在⽤⼀个字节表示数字取值范围时,这些数字中多了⼀个-0,所以导致我们在 ⽤反码直接运算时符号位可以直接参加运算,但是结果会不对。
补码
为了解决上面的问题,我们可以采用补码:
十进制 | 原码 | 反码 | 补码 |
2 | 0000 0010 | 0000 0010 | 0000 0010 |
-2 | 1000 0010 | 1111 1101 | 1111 1110 |
也就是说:正数的补码和原码、反码⼀样,负数的补码就是反码+1。
十进制 | 原码 | 反码 | 补码 |
5 | 0000 0101 | 0000 0101 | 0000 0101 |
-3 | 1000 0011 | 1111 1100 | 1111 1101 |
采用补码后,我们在来看5-3的执行过程:
5-3
= 5+(-3)
= 0000 0101(补码) + 1111 1101(补码)
= 0000 0010(补码)
= 0000 0010(原码)
= 2
5-3=2,结果真确。再来看一个特殊的:1-1
1-1
= 1+(-1)
= 0000 0001(补码) + 1111 1111(补码)
= 0000 0000(补码)
= 0000 0000(原码)
= 0
继续:0+0
0+0
= 0000 0000(补码) + 0000 0000(补码)
= 0000 0000(补码)
= 0000 0000(原码)
= 0
所以,我们可以看到补码解决了反码的问题。 所以对于数字,我们可以使⽤补码的形式来进⾏⼆进制表示。
位移运算
java中的位移运算有:
< 左移
> 右移
>>> ⽆符号右移
正数位移运算
System.out.println(2 << 1); // 4
System.out.println(2 >> 1); // 1
System.out.println(2 >>> 1); // 1
System.out.println(-2 << 1); // -4
System.out.println(-2 >> 1); // -1
System.out.println(-2 >>> 1); // 2147483647
乍⼀眼看到上⾯Demo的打印结果,你应该是懵逼的,接下来我来解释⼀下这个结果到底是如何运算出来的。
2<<1 :⼗进制“2”转换成⼆进制为“00000000 00000000 00000000 00000010”,再将⼆进制左移⼀位,⾼位丢弃,低位补0,所以结果为“00000000 00000000 00000000 00000100”,换算 成⼗进制则为“4”。(一个数字左移N位相当于乘以2的N次方)。
2>>1: ⼗进制“2”转换成⼆进制为“00000000 00000000 00000000 00000010”,再将⼆进制 右移⼀位,低位丢弃,⾼位补0,所以结果为“00000000 00000000 00000000 00000001”,换算 成⼗进制则为“1" 。(一个数右移N位相当于除以2的N次方)。
对于这两种情况⾮常好理解,那什么是⽆符号右移,以及负数是怎么运算的呢? 我们先来看 -2 > 1 ,这两个负数的左移与右移操作其实和正数类似,都是先将⼗进制 数转换成⼆进制数,再将⼆进制数进⾏移动,所以现在的关键是负数如何⽤⼆进制数进⾏表示。
负数位移运算
我们再来看 -2 > 1 。 -2⽤原码表示为 10000000 00000000 00000000 00000010 -2⽤反码表示为 11111111 11111111 11111111 11111101 -2⽤补码表示为 11111111 11111111 11111111 11111110 -2 << 1 ,表示-2的补码左移⼀位后为 11111111 11111111 11111111 11111100 ,该补码对应 的反码为:
11111111 11111111 11111111 11111100
- 1
= 11111111 11111111 11111111 11111011
该反码对应的原码为:符号位不变,其他位取反,为 10000000 00000000 00000000 00000100 , 表示-4。 所以 -2 > 1 是⼀样的计算⽅法,这⾥就不演示了。
⽆符号右移
上⾯在进⾏左移和右移时,有一点需要注意,就是在对补码进⾏移动时,符号位是固定不动的,⽽⽆符号 右移是指在进⾏移动时,符号位也会跟着⼀起移动。 ⽐如 -2 >>> 1 。 -2⽤原码表示为 10000000 00000000 00000000 00000010 -2⽤反码表示为 11111111 11111111 11111111 11111101 -2⽤补码表示为 11111111 11111111 11111111 11111110 -2的补码右移1位为: 01111111 11111111 11111111 11111111 右移后的补码对应的反码、原码为: 01111111 11111111 11111111 11111111 (因为现在的符号 位为0,表示正数,正数的原、反、补码都相同) 所以,对应的⼗进制为2147483647。 也就是 -2 >>> 1 = 2147483647
总结
这⾥总结⼀下,我们可以发现: 2 << 1 = 4 = 2*2
2 << 2 = 8 = 2*2*2
2 << n = 2*2 m << n = m * 2 右移则相反,所以⼤家以后在源码中再看到位运算时,可以参考上⾯的公式。
相关文章:
快速了解原码、反码、补码和位运算
我们知道计算机使用的是二进制,我们⽤⼀个字节,也就是8个bit 来表示⼆进制数。 原码 十进制 原码20000 0010-21000 0010 原码其实是最容易理解的,只不过需要利⽤⼆进制中的第⼀位来表示符号位,0表示正数,1表示…...
算法的复杂度介绍
算法的复杂度介绍 算法(Algorithm)是指用来操作数据、解决程序问题的一组方法。对于同一个问题,使用不同的算法,也许最终得到的结果是一样的,但在过程中消耗的资源和时间却会有很大的区别。 为什么要进行算法分析&…...

教你如何搭建店铺—收支管理系统,demo可分享
1、简介1.1、案例简介本文将介绍,如何搭建店铺-收支管理。1.2、应用场景以店铺收支管理为核心,维度数据分析,智能指导门店经营,账目清晰一目了然,店铺经营更高效。2、设置方法2.1、表单搭建1)新建表单【客户…...
java性能分析-堆内存最佳实践-堆分析
堆内存最佳实践 优化垃圾回收器标志参数很重要但是采用更好的编程实践获得更大的性能提升 1.谨慎的创建对象并尽快的丢弃,是更好的内存是提高gc更好的方法 2.频繁创建某种类型的对象会导致整体的性能变差 对象复用设计 线程局部变量 每个线程中创建一个局部变量…...

3月8号作业
题目:题目一:vmlinux可执行文件如何产生题目二:整理内核编译流程:uImage,zImage,Image,vmlinux之间的关系答案一:在内核源码目录下vi Makefile,搜索vmlinux目标,vmlinux: scripts/li…...

Flink相关介绍
简介 Flink的定位是:Apache Flink是一个框架和分布式处理引擎,如图所示,用于对无界和有界数据流进行有状态计算。Flink被设计在所有常见的集群环境运行,以内存执行速度和任意规模来执行计算。 Flink 框架处理流程应用场景 1、电…...

Java 8 排序
今天分享 Java 8 进行排序的 10 个姿势,其实就是把 Java 8 中的 Lambda、Stream、方法引用等知识点串起来 传统排序 现在有一个 List 集合: public static List<User> LIST new ArrayList() {{add(new User("Lisa", 23));add(new Us…...

Blazor_WASM之4:路由
Blazor_WASM之4:路由 路由模板 通过 Router组件可在 Blazor 应用中路由到 Razor 组件。 Router 组件在 Blazor 应用的 App 组件中使用。App组件模板如下 <Router AppAssembly"typeof(Program).Assembly"><Found Context"routeData"…...
对Vue响应式的理解
1. 啥是响应式? (1).所谓的数据响应式就是能够使数据变化可以被检测到并且对这种变化做出响应式的机制 2. 为什么vue需要响应式? (1).MVVM框架中要解决的核心问题数据驱动视图,数据的改变引起视图的更新ÿ…...

磁盘阵列Raid探讨
最近公司买服务器,顺便了解一下服务器配置方面的问题 以下讨论的都是入门级服务器配置,全部是主观意见,没有任何科学依据,欢迎大家讨论 Raid0,Raid1,Raid10,Raid5,Raid6(Raid5热备)…...

基于MyBatis依次、批量、分页增删改查
我们知道处理数据有三种思路:依次、批量、分页,对应方法如下 依次处理:在 Java 里面写 for 循环,依次使用 SQL 语句,频繁连接断开数据库批量处理:在 MyBatis 里面用 <foreach> 拼接成一条长 SQL 语句…...
Tomcat源码分析-Session源码解析
tomcat session 设计分析 tomcat session 组件图如下所示,其中 Context 对应一个 webapp 应用,每个 webapp 有多个 HttpSessionListener, 并且每个应用的 session 是独立管理的,而 session 的创建、销毁由 Manager 组件完成&…...

常见数据模型
目录 1.1两类数据模型 1.2概念模型 1.3数据模型的组成要素 1.4常见数据模型 层次模型 网状模型 关系模型 数据模型是对现实世界数据特征的抽象,也就是说数据模型是用来描述数据、组织数据和对数据进行操作的。数据模型是数据库系统的核心和基础。 1.1两类数…...

Lesson 8.3 ID3、C4.5 决策树的建模流程 Lesson 8.4 CART 回归树的建模流程与 sklearn 参数详解
文章目录一、ID3 决策树的基本建模流程二、C4.5 决策树的基本建模流程1. 信息值(information value)2. C4.5 的连续变量处理方法三、CART 回归树的基本建模流程1. 数据准备2. 生成备选规则3. 挑选规则4. 进行多轮迭代5. 回归树的预测过程四、CART 回归树…...

阿里云手机短信登录
阿里云短信服务介绍阿里云短信服务(Short Message Service)是广大企业客户快速触达手机用户所优选使用的通信能力。调用API或用群发助手,即可发送验证码、通知类和营销类短信;国内验证短信秒级触达,到达率最高可达99%&…...

Android Camera SDK NDK NDK_vendor介绍
Android Camera JNI NDK NDK_vendor介绍前言主要有哪几种interface?Android SDKCamera API 1Camera API 2小结Android NDKNDK InterfaceNDK Vendor Interface小结Camera VTS Testcase总结Reference前言 本篇博客是想介绍Android camera从application layer到camera…...

SQL基础语句小结
🍎道阻且长,行则将至。🍓 目录 一、SQL概述 1.简介 2.格式语法 3.SQL分类 二、DDL操作数据库 1.创建数据库 2.查询与使用 3.删除数据库 三、DDL:操作表 (1)数据类型 (2)创建表 (3)查询当前数据库的表 (4)删除表 (5)修改表 四、DML…...

管理类书籍推荐
管理类书籍对于每一位想要获得管理能力提升或者实现职业生涯更上一层楼的企业管理者或领导者而言,都是不可或缺的一项重要学习工具。作为管理工作从事者的职场必需品,一本出色的管理类书籍可以为我们提供大量宝贵的经验与专业建议,从而让管理…...

win10 mingw 调用python
ubuntu调用pythonhttps://blog.csdn.net/qq_39942341/article/details/129333969 我这里mingw是用msys2的 opencv也是msys2装的 安装msys2和opencv可以参考这个https://blog.csdn.net/qq_39942341/article/details/129380197?spm1001.2014.3001.5502 环境变量里加入python路…...
教你使用三种方式写一个最基本的spark程序
当需要处理大规模数据并且需要进行复杂的数据处理时,通常会使用Hadoop生态系统中的Hive和Spark来完成任务。在下面的例子中,我将说明如何使用Spark编写一个程序来处理Hive中的数据,以满足某个特定需求。假设我们有一个Hive表,其中…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...