408CO-补码,移码的计算和原理

由于数据的机器级表示相对抽象,在重温这块内容时,写一下思路,以便重新理解一遍.但是本文并不严谨,一切的目的只是为了方便直观上理解,也为了服务于考试,而不是搞懂它背后的数学逻辑.如有错误,还请批评指正.

补码是什么?

首先我们要先明确,补码只是针对有符号数而言的,对于无符号数,我们不谈补码.(实际上对于有符号的正整数而言,原反补都是一样的).

在转补码时,其实并不费劲,就是负数补码就是取反加一,这也是补码的核心原则.但个人认为,补码的关键在于符号位可以直接参与运算.在计算机内部,我们实现两数相减也就是基于此的.

这里我们以一个简单的例子来看一下, 假设现在有数 A = ( 01 ) 2 , B = ( 10 ) 2 A=(01)_2,B=(10)_2 A=(01)2,B=(10)2,均为补码表示,那么 A + B = ( 11 ) 2 A+B=(11)_2 A+B=(11)2. 实际上最后的结果为 − 1 -1 1.那么我们这里已知 A = 1 , B = − 2 A=1,B=-2 A=1,B=2的情况下,似乎**符号位参与运算的直接结果,就是将符号位直接视为 − 2 n − 1 -2^{n-1} 2n1**来参与运算的.

我们再举一个更加一般的例子: A = 010010 ( 18 ) , B = 100111 ( − 32 + 7 ) A=010010(18),B=100111(-32+7) A=010010(18),B=100111(32+7).这个例子显然 A A A为正数, B B B为负数,那么它们做加法的最后结果 A + B = 111001 ( − 32 + 18 + 7 ) A+B=111001(-32+18+7) A+B=111001(32+18+7).将 B B B分解为 100000 + 000111 ( − 32 + 7 ) 100000+000111(-32+7) 100000+000111(32+7),上面所说的结论就有点显然了.

所以我们可以看到一点端倪,所谓符号位可以参与运算,就是把符号位直接视为 − 2 n − 1 -2^{n-1} 2n1,其他位置按照正数直接计算,就是补码加减的结果.

由此我们也就解释了,为什么补码从 011..111 011..111 011..111 100...000 100...000 100...000,会直接从最大数跳变到最小数,也同样解释了,为什么在补码下, 0 0 0是唯一的.(当然上述的结论并没有严格的数学证明,但实际上可以证明它们是成立的,具体可参见CSAPP相关章节).

怎么样不转原码速算补码?

上述结论给我们提供了一个相当有效的计算方式.

  • 对于一个正数而言,0xxxxx,就是它的原码,直接算就可以了.
  • 对于一个负数而言,1xxxxx,就直接把符号位视为 − 2 n − 1 -2^{n-1} 2n1,后面的数字部分当成一个正数,然后算两者相加即可,比如 100101 → 100000 ( − 32 ) + 000101 ( 5 ) = − 27 100101\rightarrow100000(-32)+000101(5)=-27 100101100000(32)+000101(5)=27.

对于第二种方法的介绍,我们要结合一点符号扩展的内容,首先明确,对于一个 n n n位有符号数,扩展为一个 2 n 2n 2n位的有符号数,我们要把 n n n位全部置为这个数的符号位.对于 1010 1010 1010扩展为八位就是 11111010 11111010 11111010. 0101 0101 0101的扩展就是 00000101 00000101 00000101.从而不改变这个数字的大小.

如此我们考虑 000011 000011 000011其实和 011 011 011是完全一样的, 这里保留一位 0 0 0的目的是看清楚它的符号位.这其实就相当于把一个扩展过的数恢复为原来的数一样.那么考虑 11110101 11110101 11110101,实际也就是等同于 10101 10101 10101.
如此我们便得到了第二种速算补码的方式,即对于形如 11..110... 11..110... 11..110...这样的补码,它的高 m m m位全为 1 1 1,我们可以直接把高 m m m位的 1 1 1省略,保留低 m − n m-n mn位,然后用第一种方法算就可以了.

这里要说明的是,上述的两种计算方法都没有做严格的数学证明,但是从直觉上来看是显然的,实际上从数学上也可以严格证明,这里我们从略.

移码是什么?

所谓移码,就是将数轴上的一段一一映射到另一段.

比如 1 − 10 1-10 110,有一个映射 f ( x ) : x + 10 f(x):x+10 f(x):x+10,那么 1 − 10 1-10 110就会被映射到 11 − 20 11-20 1120.移码只不过是将上述过程放到二进制的视角下看待.

译码的偏移量为 2 m 2^m 2m.即对于 − 2 m ∼ 2 m − 1 -2^m\sim2^m-1 2m2m1,这段数据,就可以被映射到 − 2 m + 2 m ∼ 2 m − 1 + 2 m -2^m+2^m\sim2^m-1+2^m 2m+2m2m1+2m,即 0 ∼ 2 m + 1 − 1 0\sim2^{m+1}-1 02m+11.

各个码的取值范围是多少?

n n n位二进制数为例,对于 n n n位二进制数,最多可以表示 2 n 2^n 2n个数字.

  • 原码
    原码中 0 0 0的表示范围有两种,故原码最多可以表示的数字的数量为 2 n − 1 2^n-1 2n1.最大 011..1 011..1 011..1,最小 111..11 111..11 111..11.故原码的范围 − 2 n − 1 + 1 ∼ 2 n − 1 − 1 -2^{n-1}+1\sim2^{n-1}-1 2n1+12n11.
  • 反码
    反码和原码的区别就是按位取反,其他完全一样,那么显然,表示范围也完全一样.
  • 补码
    补码中 0 0 0的表示唯一,根据前面的分析不难看出,补码最小值为 100..00 100..00 100..00,最大值为 011..11 011..11 011..11.故补码的范围 − 2 n − 1 ∼ 2 n − 1 − 1 -2^{n-1}\sim2^{n-1}-1 2n12n11.
  • 移码
    事实上不难看出,移码是将原来的原码平移了 2 m 2^m 2m,那么对于移码而言,就没有符号位的说法了(当然,如果数据本身是 2 m 2m 2m位的话,这里的第一位仍然可以视为一种形式符号位).基于此,我们可以知道,移码中也不存在 0 0 0占两个位置的情况,所以它的范围和补码是一样的,即 − 2 n − 1 ∼ 2 n − 1 − 1 -2^{n-1}\sim2^{n-1}-1 2n12n11.(这里指的是没有移位的原始数).
  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
计算机中,原码、反码、补码移码都是用来表示带符号的二进制数的编码方式。原码是最直观的表示方式,即符号位加上数值部分的二进制表示。而反码则是在原码的基础上,符号位不变,其他位按位取反。补码是在反码的基础上,末位再加1。移码则是将符号位取反。 在计算机中,实际上只有加法运算,减法运算也要转换为加法运算,乘法转换为加法运算,除法转换为减法运算。因此,在计算机中,对任意一个带有符号的二进制数,都是按其补码的形式进行运算和存储的。补码的使用简化了运算规则,并且将减法运算转换为加法运算。 补码加法公式为[X Y补 = [X补 + [Y补,补码减法公式为[X-Y补 = [X补 - [Y补 = [X补 + [-Y补,其中[-Y补为负补,求负补的方法是对补码的每一位(包括符号位)取反,然后末位加1。 已知补码,如果符号位为0,则表示是一个正数,补码即为该数的原码。如果符号位为1,则表示是一个负数,求原码的操作是将符号位保持为1,其余各位取反,然后整个数加1。 综上所述,原码、反码、补码移码是用来表示带符号的二进制数的编码方式,补码计算机中广泛应用,简化了运算规则,并且方便进行加法和减法运算。<span class="em">1</span><span class="em">2</span> #### 引用[.reference_title] - *1* [原码、反码、补码移码及其运算](https://blog.csdn.net/Chenweidalao/article/details/107582993)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* [原码,反码,补码移码的相关概念](https://blog.csdn.net/lilongfei123321/article/details/84298927)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值