FEATURED · 精选文章

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

发布时间 / 2026/8/14 13:13:16
来源 / 创域科博编辑部
栏目 / 资讯中心
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所以9110791807830108十六进制下为表示每一位上大于9的数用字母A代表10B表示11以次类推一直到F表示15对应进制下表示的数字等于其每一位上的数字和对应权重之积的和**以十五这个数在不同进制下的表示为例二进制111115 1x2 0 2^020 1x2 1 2^1211x2 2 2^2221x2 3 2^323 1 2 4 8 八进制17十进制15十六进制F1.2 进制间的转换a.十进制转二进制十进制转二进制最简方法为短除法其规则可以总结为8个字除 2 取余逆序排列以8转二进制为例8 ÷ 2 4余04 ÷ 2 2余02 ÷ 2 1余01 ÷ 2 0余1最后余数序列0001逆序排列为1000b.二进制转八进制因为八进制下每一位的数字范围为0~7刚好可以被三位二进制数覆盖000 ~ 111所以二进制转八进制的规则是从二进制序列的右边低位开始向左每3个二进制位按从右往左2 0 2^0202 1 2^1212 2 2^222的权重换算成一个八进制位不足3位的直接换算以1011转八进制为例1011从右往左三个三个可分为两段0111从右往左依次换算成八进制位下数011 - 31 - 1得到的八进制数13c.二进制转十六进制和转八进制类似从二进制序列的右边低位开始向左每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 计算机存储单位说明在计算机中最小的存储单位是比特bit1个二进制位1bit接下来比比特大的单位为字节Byte1字节8bit再之后的存储单位关系如下1KB 1024Byte1MB 1024KB1GB 1024MB1TB 1024GB这里对存储单位进行说明主要是想补充一个二进制位1bit 这个前置知识b.2.2 signed和unsigned之间三码的区别signed1.有符号整数二进制的这三种表示方法下二进制序列都有符号位和数值位之分2.最高位的1位即所有比特位中最左边那位)叫做符号位其余位叫做数值位3.有符号整数的正负数之分体现在符号位上而数字的绝对值大小体现在数值位上4.符号位上为0表示“正”当然0是不是正数也不是负数为1表示“负”下面以int为例因为int的大小为4字节所以其二进制表示下可以分配到32个比特位unsigned二进制序列没有符号位与数值位之分全是数值位正是因为符号位和数值位的差别同类型的unsigned整数能够表示的最大值为signed整数可表示的最大值的两倍1unsigned只可表示非负数signed可表示负数0正数2.2 整数与三码间的转换因为非负整数三码相同所以下面的原码-反码-补码只针对负整数而言a.整数-原码直接将整数按照正负数的形式翻译成二进制得到的就是原码inta-10;-15的原码为为方便观看下面把32个比特位以一个字节为单位每8个间隔开10000000000000000000000000001010b.原码-反码原码符号位不变如果有的话其他位依次按位取反就可以得到反码(按位取反规则二进制每一位0变11变0)inta-10;-10的原码为为方便观看下面把32个比特位以一个字节为单位每8个间隔开10000000000000000000000000001010-10的反码为11111111111111111111111111110101c.反码-补码反码1就得到补码(每一位逢2进1变0若进位后总位数多出正确位数则舍去多出的位数)inta-10;-10的原码为为方便观看下面把32个比特位以一个字节为单位每8个间隔开10000000000000000000000000001010-10的反码为11111111111111111111111111110101-10的补码为11111111111111111111111111110110若反码为11111111111111111111111111111111其转补码1得100000000000000000000000000000000比正确的32位多1位则舍去多出来的那一位1得补码00000000000000000000000000000000d.补码-反码-原码将上诉的三种转换倒过来执行即可2.3 整数在内存中的存储与补码运算a. 先上结论计算机只认识二进制0和1而整数实际是以补码的形式存储在内存中的所以所有的整数运算都是用补码进行计算的原码和反码只是人们用来计算补码的工具内存中并不存在b. 为什么一定要用补码存储整数这是因为不用补码有两个硬伤1.原码和反码表示下0都有两种表示形式-0和0都是同一个数0但是(原码)-0-100000000000000000000000000000000-00000000000000000000000000000000(反码)-0-111111111111111111111111111111110-00000000000000000000000000000000这两种表现方式下同一个数0都占了两个不同的编码使得可表示的数少了一个空间直接浪费了一个 而且还会导致运算逻辑混乱 而补码则能完美解决这个问题0-0-000000000000000000000000000000002.若不用补码存储整数减法运算无法直接用加法实现硬件成本高计算机的 CPU 里天生只有加法器没有专门的减法器。如果用原码做减法比如 5 - 3就需要额外的电路来处理符号位、比较绝对值大小再做减法这会让硬件变得非常复杂成本飙升。而用补码存储整数进行减法运算可以自动将减法运算变为加法运算且结果正确以5-3为例 补码下5-3-5的补码(-3的补码)5的补码00000000000000000000000000000101-3的补码111111111111111111111111111111015(-3)100000000000000000000000000000010-舍去多的一位-0000000000000000000000000000001000000000000000000000000000000010恰好就是2的补码5-32c. 补码运算上面已经说过所有的整数运算都是用补码进行计算的那有哪些整数运算呢算数运算常用的算术运算有 , - , * , / , %因为除±外其他都涉及一些位运算规则所以这里先不进行讲解等到讲操作符时就会将其他的这些运算补齐(在上面讲用补码存储的第二个原因的例子中已体现±运算所以不再赘述)注意一些不同类型的整型变量在进行算数运算时会发生整型提升或算术转换此时运算的过程就更复杂些上面举的例子是同类型整型变量间的运算规则至于整型提升与算术转换的场景将在后续文章中解释~下面这些运算同样会在讲解操作符时补齐位运算~,,|,^,,复合赋值运算:,-,……比较运算±号
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻