Code
输入一个原码,可以得到其对应的反码和补码的值。
#include <iostream>
#include <string>
using namespace std;
int main(){
while(1){
cout<<"输入原码,整数的符号位一定要写0"<<endl;
string s;
cin>>s;
if(s[0]=='0'){
cout<<"原码,反码,补码都是:"<<s<<endl;
}
else{
cout<<"原码:"<<s<<endl;
cout<<"反码:";
cout<<"1"; //符号位
for(int i=1;i<s.length();i++){
if(s[i]=='.') cout<<s[i];
else if(s[i]=='1') cout<<'0';
else cout<<'1';
}
cout<<endl<<"补码:";
for(int i=s.length();i>=0;i--){
if(s[i]=='1'){
cout<<"1"; //符号位
for(int m=1;m<i;m++){
if(s[m]=='.') cout<<s[m];
else if(s[m]=='1') cout<<'0';
else cout<<'1';
}
for(int m=i;m<s.length();m++){
cout<<s[m];
}
break;
}
else{
cout<<"ERROR"<<endl;
break;
}
}
cout<<endl;
}
}
}
特别的几个样例测试
测试样例:-1
输入原码,整数的符号位一定要写0
10000001
原码:10000001
反码:11111110
补码:ERROR(1111 1111:-127)
//同时可以发现,-1在负数中是最大的,此处不矛盾。
测试样例:+1
输入原码,整数的符号位一定要写0
00000001
原码,反码,补码都是:00000001
测试样例:+0
输入原码,整数的符号位一定要写0
00000000
原码,反码,补码都是:00000000
测试样例:-0
输入原码,整数的符号位一定要写0
10000000
原码:10000000
反码:11111111
补码:ERROR(0000 0000)
原反补的范围问题
类型 | 范围 |
---|---|
原码 | -127 ~ +127 |
反码 | -127 ~ +127 |
补码 | -128 ~ +127 |
其实可以发现补码多了一个 -128。
注意:-128没有原码,也没有反码,但是可以有补码。我们人为规定-128为1000 0000。
+ 0 | - 0 |
---|---|
原码 = 0000 0000 | 原码 = 1000 0000 |
反码 = 0000 0000 | 反码 = 1111 1111 |
补码 = 0000 0000 | 补码 = 0000 0000 |
在这里会发现,对于原码而言,0有 +0 和 -0 之分。但是对于补码而言,这个地方是一致的。
Q1:为什么人们规定-128是1000 0000?
1.从补码本身出发。-128的反码表示应该是256(也就是 2^8) - | -128 | = 128,所以就干脆给了它了。
2.计算机角度出发。对于补码而言,2^8次意味着共有256种情况。127(负数情况) + 127(正数情况) + 1(±0的补码都只有一种情况) = 255种情况,-0的那个又没有办法,干脆给了-128正好补齐256种情况吧。
Q2:为什么要引入补码?
为了方便计算,不需要再考虑加减法而直接视为加法进行计算即可。
定点数的运算
定点数的移位
数字 | 码制 | 填补码 |
---|---|---|
正数 | 原反补 | 0 |
负数 | 原码 | 0 |
负数 | 补码 | 左0右1 |
负数 | 反码 | 1 |
逻辑移位
逻辑移位操作数为无符号数,左移高位丢,低位补0;右移低位丢,高位补0。