代码:
/*
用两个符号位进行修正
正数符号位为 00 , 负数符号位为 11
当两位符号位 为 01, 10时就是溢出,这时取最高位为符号位,其他位为数值位
*/
#include<bits/stdc++.h>
using namespace std;
int binary_x[6];
int binary_y[6];
void BaseConversion(int n, int b, int base[]) { //10进制转换为2进制并求补码
if(n != -16) {
int q = 5;
bool flag = 0;
if(n >= 0) flag = 0; //表示这个数是正数
else {
flag = 1; //表示这个数是负数
n = -n;
}
//然后根据[n]补 求[-n]补 : 连同符号位按位取反末尾 + 1
//先求 [x] 原码
while (n) {
int temp = n % b;
base[q--] = temp;
n /= b;
}
/*
//输出原码
for(int i = 0; i < 6; ++i) cout << base[i];
cout << endl;
*/
//求[n] 的补码 和[-n] 的补码
//正数原反补相同
if (flag) { //负数求补码
//连同符号位按位取反
for(int i = 0; i < 6; ++i){
base[i] = !base[i];
}
//末尾 + 1
int temp = 1; //判断是否进位
for(int i = 5; i > 0; --i) {
if (base[i] == 1 && temp == 1) { //当前相加有进位
base[i] = 0;
temp = 1;
} else { //当前位为0 或者进位为0
base[i] = 1;
temp = 0;
break;
}
}
}
} else { //负16的情况
base[0] = base[1] = 1;
for (int i = 2; i < 6; ++i) {
base[i] = 0;
}
}
//输出补码
for(int i = 0; i < 6; ++i){
cout << base[i];
}
cout << endl;
}
int BtoD (int ans[]) { //二进制转10进制
int temp = 0;
for (int i = 1; i < 6; ++i) {
if (ans[i]) {
temp += pow(2, 6 - i - 1);
}
}
return temp;
}
void Solve(int binary_x[], int binary_y[]){
int temp = 0; //判断是否进位
int ans[6];
memset(ans, 0, sizeof(ans));
for(int i = 5; i >= 0; --i) {
if (binary_x[i] && !(binary_x[i] ^ binary_y[i])) { //两位都为1
if (temp) { //上一位+法有进位
ans[i] = 1;
} else {
ans[i] = 0;
}
temp = 1;
} else if (binary_x[i] ^ binary_y[i]) { //异或结果为 1 其中有一位为1
if (temp) {//上一位+之后 ,有进位
ans[i] = 0;
temp = 1;
} else {
ans[i] = 1;
}
} else { //两都为0
if (temp) {//上一位+之后,有进位
ans[i] = 1;
} else {
ans[i] = 0;
}
temp = 0;
}
}
//判断 最高位是否是 01 或者 10
int flag = ans[0] ^ ans[1];
if (flag) cout << "计算结果溢出。" << endl;
else cout << "计算结果没有溢出。" << endl;
/*
//输出结果的补码
for (int i = 0; i < 6; ++i) cout << ans[i];
cout << endl;
*/
/*
没有溢出 那答案是什么
溢出之后的修正, 最高位为符号位, 其他为数值位
没有溢出和溢出求解都可以看做 ,最高位为符号位,其他为数值位
思路:
1)先判断符号位,
2)然后 从右往左找第一个1,包括这个1在内的所有都是原码部分 (i - n)
3)第一个1的左边除了符号位按位取反(i-1位按位取反)
*/
int result = 0;
flag = 0;
if( ans[0] ) { //负数
//求原码
for(int i = 5; i > 0; --i) {
if(ans[i] == 1 && !flag) { //从右到左找第一个1
flag = 1;
}
else if(flag == 1) { //按位取反 (除符号位)
ans[i] = !ans[i];
}
}
/*
//输出结果的原码
for (int i = 0; i < 6; ++i) cout << ans[i];
cout << endl;
*/
flag = 0; //判断一下是否是 -32
for(int i = 1; i < 6; ++i){
if(ans[i]) {
flag = 1;
break;
}
}
if (!flag) {
result = -32;
}
else {
result = -BtoD(ans); //二进制转换为10进制
}
} else { //正数
result = BtoD(ans);
}
cout << result << endl;
}
int main () {
//输入 2 个10进制数 范围在 -2^4 ~ 2^4 -1 (-16 ~ +15)
while(1) {
int x, y;
cin >> x >> y;
if(x < -16 || x > 15 || y < -16 || y > 15) {
//cout << "请输入正确范围的数字" << endl;
} else {
memset(binary_x, 0, sizeof(binary_x));
memset(binary_y, 0, sizeof(binary_y));
cout << x << " 的补码为 :" << endl;
BaseConversion(x, 2, binary_x);
cout << y << " 的补码为 :" << endl;
BaseConversion(y, 2, binary_y);
//然后补码进行向+判断是否会溢出 和 修正
Solve(binary_x, binary_y);
}
}
return 0;
}
/*
*/
测试数据集:自己跑一个 从 -17 到 +17的所有排列
#include<bits/stdc++.h>
using namespace std;
int main() {
freopen("out.txt", "w", stdout);
int arr[100];
int q = -17;
for(int i = 0; i <= 34; ++i){
arr[i] = q++;
}
for(int i = 0; i <= 34; ++i) {
for (int j = 0; j <= 34; ++j) {
cout << arr[i] << " " << arr[j] << endl;
}
}
return 0;
}