补码的原理

在时钟里,时针的最大刻度是 12,超过这个值(称为模)将重新计时。假设现在要把时针从 4 点钟调到 1 点钟,可以逆时针减 3 小时,也可以顺时针加 9 小时,效果是完全一样的。

在这里插入图片描述
于是在时针系统里存在:4-3 = 4+9,在模为 12 的时针系统里 3 和 9 就是一对补数,利用补数形式可将式子写成:4-3 = 4+(12-3)。

这里的12点也可以称为0点,即高位溢出

因为换句话说如果A加上B等于模或者0,那么B就是A的补数

举个例子:
2的二进制是0000 0010
0的二进制是0000 0000
我们知道二进制加法中,正常情况下2加上任何数都不能等于0,只有一种情况,那就是高位溢出。比如2加上某个数变成了1 0000 0000,这个时候计算机会弃掉高位的1.
这就很简单了,把2按位取反,变成1111 1101,它加上2就是1111 1111(全1),这个时候只需要再加1就能溢出,变成1 0000 0000.
所以将2按位取反再加1为 1111 1110,就是2的补码。

所以计算64-16
-》
64的原码 + 16的补码 
-》
64的原码: 0100 0000
16的原码: 0001 0000 取反 1110 1111 加1 等于 1111 0000
-》 
  0100 0000
  1111 0000
----------------
1 0011 0000
-》
48

### 原码、反码和补码的概念 #### 定义与表示方法 原码是最简单的机器数表示法。最高位是符号位,“0”代表正数,“1”代表负数,其余各位则用来表示数值大小[^1]。 对于8位二进制数来说: - 正数的原码就是其对应的二进制数; - 负数的原码则是先写出该数绝对值的二进制形式,在最左边加上“1”。 例如,`+7` 的原码为 `0000 0111`; `-7` 的原码为 `1000 0111`。 #### 反码定义及其特点 当处理的是正整数时,它的反码与其原码相同;而对于负整数而言,除了符号位外,其他各位置上的比特都要取反(即由原来的‘0’变为‘1’, 或者相反),形成所谓的“按位求反”。因此: - 对于上述例子中的 `-7`, 首先得到其原码 `1000 0111`,接着除开首位不变之外对其余部分逐位反转获得最终的结果 `1111 1000` 即为其反码[^2]。 #### 补码概念及优势说明 为了简化加减运算并提高效率,实际应用中更倾向于采用补码来表达带符号的数据。具体做法如下所示: - 如果是一个正数,则直接将其转换成相应的二进制序列作为补码; - 若为负数的话,那么就基于此数的反码再加一即可得出对应补码。 继续以上面提到的例子来看,`-7` 的补码计算过程可以描述为:首先获取到它按照前述规则形成的反码 `1111 1000` ,之后再加上一位变成 `1111 1001` 。值得注意的是,在这种情况下,即使存在溢出也不会影响结果的有效性,因为额外产生的高位会被自动丢弃掉。 ```cpp // C++ code to demonstrate conversion from decimal to binary and then finding one's complement (反码) of a negative number. #include <iostream> using namespace std; string decToBin(int n){ string bin = ""; while(n>0){ int rem=n%2; char ch=rem+'0'; bin+=ch; n/=2; } reverse(bin.begin(),bin.end()); return bin.empty() ? "0":bin; } void findOnesComplement(string &binaryString){ for(char& c : binaryString){ if(c=='0')c='1'; else if(c=='1')c='0'; } } int main(){ int num=-7; unsigned int absNum=(num<0)?(-num):num; string binRep=decToBin(absNum); cout << "Binary Representation: "<<(num>=0?"":"1")<<binRep<<"\n"; if(num<0){ findOnesComplement(binRep); cout<<"One's Complement:"<<'1'+binRep<<"\n"; // Adding '1' before the reversed bits represents sign bit as per ones-complement rule. } } ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值