双符号位补码(用于修正单符号位补码+法溢出)

 

代码:

/*
	用两个符号位进行修正
	正数符号位为 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;
} 

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值