news 2026/8/14 13:13:05

C语言系列之——(4)原码、反码、补码

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C语言系列之——(4)原码、反码、补码

原码,反码,补码

  • 1.二进制和进制转换
    • 1.1 什么是进制
    • 1.2 进制间的转换
      • a.十进制转二进制
      • b.二进制转八进制
      • c.二进制转十六进制
  • 2.原码、反码、补码
    • 2.1 前置知识准备
      • a.这三个码是什么
      • b. 不同整数三码的区别
        • b.1 负数与非负数之间
        • b.2 signed和unsigned之间
          • b.2.1 计算机存储单位说明
          • b.2.2 signed和unsigned之间三码的区别
    • 2.2 整数与三码间的转换
      • a.整数->原码
      • b.原码->反码
      • c.反码->补码
      • d.补码->反码->原码
    • 2.3 整数在内存中的存储与补码运算
      • a. 先上结论
      • b. 为什么一定要用补码存储整数
      • c. 补码运算

1.二进制和进制转换

1.1 什么是进制

我们常常听到二进制八进制十进制十六进制这样的说法,这些是什么意思呢
其实,它们只是数值的不同表现形式

每种进制下,从右往左分别是个位,十位,百位……只是不同进制下每一位的权重是不一样的

不同进制下从右往左每一位的权重如下
二进制:2 0 2^0202 1 2^1212 2 2^222……
八进制:8 0 8^0808 1 8^1818 2 8^282……
十进制:10 0 10^010010 1 10^110110 2 10^2102……
十六进制:16 0 16^016016 1 16^116116 2 16^2162……

每一位上的数字在等于其进制数时会往下一位进一位,自己这一位变为0
(如10进制下每一位上的数最大只能是9,当某一位上数变为10时,会向其左边的第一位进1,自己变成0,所以9+1=10,79+1=80,78+30=108)
(十六进制下为表示每一位上大于9的数,用字母A代表10,B表示11,以次类推,一直到F表示15)

对应进制下表示的数字等于其每一位上的数字和对应权重之积的和

**以十五这个数在不同进制下的表示为例:
二进制:1111(15 = 1x2 0 2^020+ 1x2 1 2^121+1x2 2 2^222+1x2 3 2^323= 1 + 2 + 4 + 8 )
八进制:17
十进制:15
十六进制:F


1.2 进制间的转换

a.十进制转二进制

十进制转二进制最简方法为:短除法,其规则可以总结为8个字:除 2 取余,逆序排列

以8转二进制为例:
8 ÷ 2 = 4(余0)
4 ÷ 2 = 2(余0)
2 ÷ 2 = 1(余0)
1 ÷ 2 = 0(余1)
最后余数序列0001逆序排列为:1000

b.二进制转八进制

因为八进制下每一位的数字范围为0~7,刚好可以被三位二进制数覆盖(000 ~ 111),所以二进制转八进制的规则是:从二进制序列的右边低位开始,向左每3个二进制位按从右往左2 0 2^0202 1 2^1212 2 2^222的权重换算成一个八进制位,不足3位的直接换算

以1011转八进制为例:
1011从右往左三个三个可分为两段:011,1
从右往左依次换算成八进制位下数,011 -> 3,1 -> 1
得到的八进制数:13

c.二进制转十六进制

和转八进制类似,从二进制序列的右边低位开始,向左每4个二进制位按从右往左2 0 2^0202 1 2^1212 2 2^2222 3 2^323的权重换算成一个十六进制位,不足4位的直接换算

(其他进制下每位数权重再各位求和即得十进制数)


2.原码、反码、补码

2.1 前置知识准备

a.这三个码是什么

整型数据 / 整数的二进制表示方法有三种:原码反码补码


(char类型变量中存的实际是字符对应地ASCLL码值,所以也是整型类型)

b. 不同整数三码的区别

b.1 负数与非负数之间

总结下来就是:
非负整数的原、反、补码三码相同,只要得到其中一个码就得到了所有三码;负整数的三码各不相同,需要分别计算转换

b.2 signed和unsigned之间
b.2.1 计算机存储单位说明

在计算机中,最小的存储单位是比特(bit)1个二进制位=1bit
接下来比比特大的单位为字节(Byte)1字节=8bit
再之后的存储单位关系如下:

1KB = 1024Byte
1MB = 1024KB
1GB = 1024MB
1TB = 1024GB

(这里对存储单位进行说明主要是想补充:一个二进制位=1bit 这个前置知识)

b.2.2 signed和unsigned之间三码的区别

signed
1.有符号整数二进制的这三种表示方法下,二进制序列都有符号位数值位之分
2.最高位的1位(即所有比特位中最左边那位)叫做符号位,其余位叫做数值位

3.有符号整数的正负数之分体现在符号位上,而数字的绝对值大小体现在数值位上
4.符号位上为0表示“正”(当然0是不是正数也不是负数),为1表示“负”

(下面以int为例,因为int的大小为4字节,所以其二进制表示下可以分配到32个比特位)

unsigned
二进制序列没有符号位与数值位之分,全是数值位

正是因为符号位和数值位的差别:
同类型的unsigned整数能够表示的最大值为signed整数可表示的最大值的两倍+1
unsigned只可表示非负数,signed可表示负数,0,正数


2.2 整数与三码间的转换

(因为非负整数三码相同,所以下面的原码->反码->补码只针对负整数而言)

a.整数->原码

直接将整数按照正负数的形式翻译成二进制得到的就是原码

inta=-10;-15的原码为:(为方便观看,下面把32个比特位以一个字节为单位每8个间隔开)10000000000000000000000000001010

b.原码->反码

原码符号位不变(如果有的话),其他位依次按位取反就可以得到反码

(按位取反规则:二进制每一位,0变1,1变0)

inta=-10;-10的原码为:(为方便观看,下面把32个比特位以一个字节为单位每8个间隔开)10000000000000000000000000001010-10的反码为:11111111111111111111111111110101

c.反码->补码

反码+1就得到补码(每一位逢2进1变0,若进位后总位数多出正确位数,则舍去多出的位数)

inta=-10;-10的原码为:(为方便观看,下面把32个比特位以一个字节为单位每8个间隔开)10000000000000000000000000001010-10的反码为:11111111111111111111111111110101-10的补码为:11111111111111111111111111110110若反码为:11111111111111111111111111111111其转补码+1100000000000000000000000000000000,比正确的32位多1位,则舍去多出来的那一位1,得补码:00000000000000000000000000000000

d.补码->反码->原码

将上诉的三种转换倒过来执行即可


2.3 整数在内存中的存储与补码运算

a. 先上结论

计算机只认识二进制0和1,而整数实际是以补码的形式存储在内存中的,所以,所有的整数运算都是用补码进行计算的
原码和反码只是人们用来计算补码的工具,内存中并不存在


b. 为什么一定要用补码存储整数

这是因为不用补码有两个硬伤:

1.原码和反码表示下,0都有两种表示形式

-0+0都是同一个数0但是:(原码)-0->10000000000000000000000000000000+0->00000000000000000000000000000000(反码)-0->11111111111111111111111111111111+0->00000000000000000000000000000000这两种表现方式下,同一个数0都占了两个不同的编码,使得可表示的数少了一个,空间直接浪费了一个 而且还会导致运算逻辑混乱 而补码则能完美解决这个问题:+0=-0->00000000000000000000000000000000

2.若不用补码存储整数,减法运算无法直接用加法实现,硬件成本高

计算机的 CPU 里,天生只有加法器,没有专门的减法器。如果用原码做减法,比如 5 - 3,就需要额外的电路来处理符号位、比较绝对值大小,再做减法,这会让硬件变得非常复杂,成本飙升。

而用补码存储整数进行减法运算,可以自动将减法运算变为加法运算,且结果正确

5-3为例 补码下,5-3->5的补码+(-3的补码)5的补码:00000000000000000000000000000101-3的补码:111111111111111111111111111111015+(-3)100000000000000000000000000000010->舍去多的一位->0000000000000000000000000000001000000000000000000000000000000010恰好就是2的补码,5-3=2

c. 补码运算

上面已经说过,所有的整数运算都是用补码进行计算的

那有哪些整数运算呢?

算数运算
常用的算术运算有 + , - , * , / , %
(因为除±外其他都涉及一些位运算规则,所以这里先不进行讲解,等到讲操作符时就会将其他的这些运算补齐)

(在上面讲用补码存储的第二个原因的例子中已体现±运算,所以不再赘述)

注意:一些不同类型的整型变量在进行算数运算时,会发生整型提升算术转换,此时运算的过程就更复杂些,上面举的例子是同类型整型变量间的运算规则,至于整型提升与算术转换的场景,将在后续文章中解释~

(下面这些运算同样会在讲解操作符时补齐)
位运算:~,&,|,^,<<,>>
复合赋值运算:+=,-=,……
比较运算±号

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/14 13:11:21

Context Ledger:解决AI编程助手长对话失忆问题的关键技术

1. 项目概述&#xff1a;当“长上下文”不再是万能解药最近在折腾各种AI编程助手&#xff08;Coding Agent&#xff09;的时候&#xff0c;我发现一个挺有意思的现象&#xff1a;即便你给模型配置了号称支持“1M Context”&#xff08;百万级上下文&#xff09;的超长窗口&…

作者头像 李华
网站建设 2026/8/14 13:08:44

硬盘安装Ubuntu全攻略:无需U盘,从原理到实战

1. 项目概述&#xff1a;为什么选择硬盘安装Ubuntu&#xff1f;如果你正在考虑给电脑装一个Ubuntu系统&#xff0c;或者想从虚拟机体验转向更真实的物理机使用&#xff0c;那么“硬盘安装”这个方式&#xff0c;大概率是你绕不开的一步。和很多新手朋友一样&#xff0c;我第一次…

作者头像 李华
网站建设 2026/8/14 13:06:24

AI Agent 面试题 430:如何实现Agent的记忆系统的实时同步?

&#x1f525; AI Agent 面试题 430&#xff1a;如何实现Agent的记忆系统的实时同步&#xff1f; 摘要&#xff1a;本文深入解析了「如何实现Agent的记忆系统的实时同步&#xff1f;」这一 AI Agent 领域的核心面试题。文章从 状态持久化 的基本概念出发&#xff0c;系统性地剖…

作者头像 李华
网站建设 2026/8/14 13:05:37

微信防撤回补丁终极指南:RevokeMsgPatcher 让撤回的消息无处遁形

微信防撤回补丁终极指南&#xff1a;RevokeMsgPatcher 让撤回的消息无处遁形 【免费下载链接】RevokeMsgPatcher :trollface: A hex editor for WeChat/QQ/TIM - PC版微信/QQ/TIM防撤回补丁&#xff08;我已经看到了&#xff0c;撤回也没用了&#xff09; 项目地址: https://…

作者头像 李华
网站建设 2026/8/14 13:03:15

NCM转MP3三步搞定:免费开源的ncmdump,把加密歌单还给你

NCM转MP3三步搞定&#xff1a;免费开源的ncmdump&#xff0c;把加密歌单还给你 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 收藏了五年的歌单一夜变灰&#xff0c;换了新车后U盘插进音响&#xff0c;几百首从网易云音乐下载的歌又…

作者头像 李华
网站建设 2026/8/14 12:59:00

告别命令行与传输线:一个开源APK安装器把安卓应用装进Windows

告别命令行与传输线&#xff1a;一个开源APK安装器把安卓应用装进Windows 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你有没有过这样的时刻&#xff1a;手机上下好…

作者头像 李华