计算机组成原理——对有符号数溢出的修正

想着学期结束公开代码,想着想着就忘了哈哈 

第六组:yll,gss,wmk,ljh,zy

(第六组是最棒的!!!!!666)

/*
1.选择加法还是减法
2.输入真值(本程序不处理小数,机器字长默认为8位,含1位符号位)
3.将真值转换成二进制 -->原码 
4.求补码
5.处理相加/相减
6.判断数值最高位和符号位有没有进位
7.判断是否溢出
8.修正(符号位有进位 最高位无进位->-2^n, 符号位无进位 最高位有进位 -> +2^n)
9.对修正的结果求原码->换成真值最后输出结果
*/
#include <bits/stdc++.h>
using namespace std;
const int MACHINELEN = 8;//机器字长 8位,含 1 位符号位
const int NUMERIC = MACHINELEN - 1;  //数值位 7 位
//有符号数
struct SignedNumber {
	int ch;//符号位
	int num[9]; //数
	SignedNumber() {
		ch = 0;
		memset(num, 0, sizeof(num));
	}
} num1, num2, ans;
void output(SignedNumber num) {
	cout << num.ch << ",";
	for(int i = 0; i < NUMERIC; i++) {
		cout << num.num[i];
	}
	cout << endl;
}

//真值->原码
SignedNumber numToSourceCode(int a) {

	SignedNumber temp;
	temp.ch = a < 0 ? 1:0;

	int c = abs(a),ind = NUMERIC - 1;
	while(c) {
		temp.num[ind--] = c%2;
		c /= 2;
	}
	return temp;
}
//原码 <-> 补码 (sourceCodeToComplementCode)
SignedNumber sCToCC(SignedNumber temp1) {
//	cout <<"coming ---- 》 " ;
//	output(temp1);
	if(temp1.ch == 0 ) return temp1;
	int flag = 0; //是否碰到第一个1
	for(int i = NUMERIC - 1; i >= 0; i--) {
		if(flag == 1) {
			temp1.num[i] = !temp1.num[i];
			continue;
		}
		if(temp1.num[i] == 1) {
			flag = 1;
		}
	}
	return temp1;
}
//补码相加 --->返回string 代表符号位,最高位进位信息 1进位 0无进位
string add(SignedNumber num1,SignedNumber num2) {
	string key = "";
	int ind = 0; //进位信息
	for(int i = NUMERIC - 1; i >= 0; i--) {
		int c = num1.num[i] + num2.num[i] + ind;
		ans.num[i] = c % 2;
		ind = c / 2;
		//第一位
		if(i == 0) {
			if(ind != 0) key += "1"; //进位
			else key += "0"; //无
		}
	}
	int c = num1.ch + num2.ch + ind;
	ans.ch = c % 2;
	ind = c / 2;
	if(ind != 0) key += "1"; //进
	else key += "0"; //无
	return key;
}
//binary -> 10进制
int getAns(SignedNumber a) {
	int ans1 = 0;
	for(int i = 0; i < NUMERIC; i++) {
		ans1 += a.num[i] * pow(2,NUMERIC - i - 1);
	}
	if(a.ch == 1) ans1 = -ans1;
	return ans1;
}
// 求-b的补码
SignedNumber allChange(SignedNumber a) {
	a.ch = !a.ch;
	for(int i = 0; i < NUMERIC; i++) {
		a.num[i] = !a.num[i];
	}
	int ind = 0;
	a.num[NUMERIC - 1] ++;
	for(int i = NUMERIC - 1; i >= 0; i--) {
		int c = a.num[i] + 0 + ind;
		a.num[i] = c%2;
		ind = c / 2;
	}
	return a;
}
int main() {

	int a, b;
	int op = 0, modify = pow(2,MACHINELEN);
	cout << "加(0)or减(1)?" << endl;
	cin >> op ;
	if(op != 0 && op != 1) {
		cout << "输入非法字符,程序自动退出" << endl;
		return 0;
	}
	cout << "输入两个操作数:" << endl;
	cin >> a >> b;
	SignedNumber bnum1 ,bnum2; 
	num1 = numToSourceCode(a);//真值->原码
    bnum1 = sCToCC(num1);//原码->补码

	num2 = numToSourceCode(b); //原码 
	if(op == 1) {
		bnum2 = sCToCC(num2); //补码 
		bnum2 = allChange(num2); // - 
	}else{
		bnum2 = sCToCC(num2); //补码 
	} 

	cout << "num1bu码:";
	output(bnum1);
	cout << "num2bu码:";
	output(bnum2);

	string key = add(bnum1,bnum2);
	cout << "结果:";
	output(ans);
//	cout << key << endl;
	if(key[0] == key[1]) {
		cout << "无溢出,结果为:";
		ans = sCToCC(ans);
		cout << getAns(ans);
	} else {
		//key 0 是最高位
		cout << "有溢出,修正后:";
		ans = sCToCC(ans);
		if(key[0] == '0' && key[1] == '1') {
			cout << getAns(ans) - modify << endl;
		} else if(key[0] == '1' && key[1] == '0') {
			cout << getAns(ans) + modify << endl;
		}
	}
	return 0;
}
// -93 45
// -9 -5

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值