C++基础-原码、反码及补码

以下内容均以8bit值为例进行叙述。

原码

  • 最高位为符号位,0为正,1为负,其余位为数字位
    如: 127的原码为0111 1111
    -127的原码为1111 1111

反码

  • 正数的反码与原码一致;
  • 负数的反码是保留负数原码的最高位不变,其余位取反,即最高位始终为1
    127的反码为0111 1111
    -127的反码为1000 0000

补码

  • 正数的补码与原码一致;
  • 负数的补码是该数的反码加1(只是表示,不是定义);
    127的补码为0111 1111
    -127的补码为1000 0001

总结

  • 正数的原码、反码、补码相同;
  • 计算机中,数值一律使用补码来表示和存储;


关于为什么计算机表示和存储数值要用补码

资料说是为了方便计算机将减法转换为加法,计算机中只有加法运算器,但是为什么使用补码可以进行转换?这一步的意义是什么,以二进制讲解比较抽象,以圆为例进行讲解。

其实补码可以用数学中的补数或相反数类比。

如下图所示圆,原点在圆心,往右为x轴正方向,以圆心为端点的射线与x轴夹角为θ,角度逆时针为负,顺时针为正。

设当前角度∠XOA=30°,要转到∠XOA’=90°,有两种方式:

  1. 顺时针转300°,即30°-300°=-270°=90°
  2. 逆时针转60°,即30°+60°=90°
    在这里插入图片描述

在一个圆中,为什么减300°等于加60°,为什么-270°等于90°,搞清楚了这个问题就知道补码的作用了。

一个圆周360°,即360°是一个循环,最小值是0,最大值是359,再增加1又回到0(360),(对比于8位二进制,最小值为0000 0000,最大值为1111 1111,再增加1又回到0000 0000),抛开符号位(对比于反码不考虑符号位),旋转到同一个位置,逆时针转的度数+顺时针转的度数=359+1(对比于去除符号位,其余各位取反再加1,如0101 1101,取反1010 0010,二者相加再加1:0101 1101+1010 0010 +1 = 10000 0000)。更详细的讲解可参考文末的文章链接。


参考
https://www.imooc.com/article/16813?block_id=tuijian_wz

10进制转原码反码补码的方法如下: 1. 原码:将10进制数的绝对值转换成二进制数,然后在最高位上加上符号位(0表示正数,1表示负数)即可得到原码。 2. 反码:正数的反码原码相同,负数的反码是将其原码中除符号位以外的所有位取反。 3. 补码:正数的补码原码相同,负数的补码是将其反码加1。 C++代码实现: ```c++ #include <iostream> using namespace std; // 将10进制数转换为二进制数 void decToBin(int n, int bin[]) { int i = 0; while (n > 0) { bin[i++] = n % 2; n /= 2; } } // 将二进制数转换为10进制数 int binToDec(int bin[], int len) { int dec = 0; for (int i = len - 1; i >= 0; i--) { dec += bin[i] * pow(2, len - i - 1); } return dec; } // 将原码转换为反码 void oriToRev(int ori[], int len) { for (int i = 0; i < len; i++) { if (ori[i] == 1) { ori[i] = 0; } else { ori[i] = 1; } } } // 将反码转换为补码 void revToCom(int rev[], int len) { int carry = 1; for (int i = len - 1; i >= 0; i--) { if (rev[i] == 1 && carry == 1) { rev[i] = 0; } else if (rev[i] == 0 && carry == 1) { rev[i] = 1; carry = 0; } } } int main() { int n = -10; // 待转换的10进制数 int len = 32; // 二进制数的位数 int bin[len] = {0}; // 存放二进制数的数组 int ori[len] = {0}; // 存放原码的数组 int rev[len] = {0}; // 存放反码的数组 int com[len] = {0}; // 存放补码的数组 // 将10进制数转换为二进制数 decToBin(abs(n), bin); // 将二进制数转换为原码 if (n >= 0) { ori[0] = 0; for (int i = 0; i < len - 1; i++) { ori[i + 1] = bin[i]; } } else { ori[0] = 1; for (int i = 0; i < len - 1; i++) { ori[i + 1] = bin[i]; } } // 将原码转换为反码 if (n < 0) { oriToRev(ori, len); } // 将反码转换为补码 if (n < 0) { revToCom(ori, len); } // 输出结果 cout << "原码:"; for (int i = 0; i < len; i++) { cout << ori[i]; } cout << endl; if (n < 0) { cout << "反码:"; for (int i = 0; i < len; i++) { cout << ori[i]; } cout << endl; cout << "补码:"; for (int i = 0; i < len; i++) { cout << com[i]; } cout << endl; } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值