单符号位的溢出和修正(计算机组成原理)

#include<bits/stdc++.h>
using namespace std;
/*
单符号位的修正算法 
思路:
		1)不溢出就不修正 
		2)溢出就修正 
		判断溢出原理:数值最高位和符号最高位是否进位
		 	a)都进位,不溢出
			b)只有其中一个进位,则溢出 
		根据溢出来修正
			1) 只有符号位溢出, 则是两个负数相加 溢出了 答案 -2^n 
			2)只有最高数值位溢出, 则是两个正数相加溢出了 答案+ 上2 ^ n 

本次使用4位机器码  表示范围 在 -8 ~ +7 之间 
*/
const int MAXN = 4;
int binary_x[MAXN], binary_y[MAXN]; 
int ans[MAXN];	//保存 
int carry[2];	// 0:符号位进位, 1:表示最高位符号位进位 
//十进制转换为2进制
void bToD (int x, int binary[]){
	if(x < 0) binary[0] = 1;
	else binary[0] = 0; 
	int cnt = MAXN - 1;
	x = abs(x);
	while(x) {
		binary[cnt--] = x % 2;
		x /= 2;
	}
} 
//原码转补码, 补码转原码
void oCTC(int binary[]) {
	if (binary[0] == 0) return ; 
	//从前向后找到第一个1,此1左边(不包含此1)除了符号位的全部按位取反,
	int flag = 0; //用来标记是否找到1 
	for (int i = MAXN - 1; i > 0; --i) { //i !=0 就是排除了符号位 
		if(flag == 0 && binary[i]){//还没找到 第一个1, 并且这一位是1 
			flag = 1;
		} else if(flag == 1) {	//这个第一个1左边的数除按位取反 
			binary[i] = !binary[i]; 
		} 
	} 	 
}
//补码的加法运算
void add(int ans[], int binary_x[], int binary_y[]) {
	int temp = 0;
	for(int i = MAXN - 1; i >= 0; --i) {
		if(i == 0) {	//判断数值最高位是否有进位 
			carry[1] = temp;
		} 
		if ( binary_x[i] && binary_y[i] ) {	 
			ans[i] = temp;
			temp = 1;
		} else if(binary_x[i] ^ binary_y[i] && temp){
			ans[i] = 0;
			temp = 1;
		} else if(binary_x[i] ^ binary_y[i] && temp == 0){
			ans[i] = 1;
			temp = 0;
		} else {
			ans[i] = temp;
			temp = 0;
		}
		
	}
	carry[0] = temp; //符号位是否进位 
} 
//将二进制转化为10进制 
int getAns(int binary[]) {
	int result = 0; 
	for (int i = 1; i < MAXN; ++i) {
		if (binary[i]) {
			result += pow(2, MAXN - i - 1);	
		}
	}
	if(binary[0] && result == 0) {	//如果是 
		result = -pow(2, MAXN - 1);
	} else if(binary[0]) result = -result;
	return result;
}
 //检查是否超过机器位 
bool check(int a, int b) {
 	if (a < -8 || a > 7 || b < -8 || b > 7) {
 		return 1;
	} else {
		return 0;
	}
 } 
 void init() {
 	memset(binary_x, 0, sizeof(binary_x));
 	memset(binary_y, 0, sizeof(binary_y));
 	memset(ans, 0, sizeof(ans));
 	memset(carry, 0, sizeof(carry));
 }
int main (){
	while(1) {
		int a, b;
		cout << "请输入两个数字:" << endl;
		cin >> a >> b;
		init(); 
		//检查是否超过机器位 
		if( check(a, b) ){
			cout << "请输入 -8 ~ +7 范围内的数字~" << endl; 
			continue;
		}
		//将a 和 b转换为二进制 原码 
		bToD(a, binary_x);
		bToD(b, binary_y);
		/*
		for (int i = 0; i < MAXN; ++i) cout << binary_x[i];
		cout << endl;
		 for (int i = 0; i < MAXN; ++i) cout << binary_y[i];
		cout << endl;
		*/ 
		// 将a 和 b的二进制原码 转换为 补码
		oCTC(binary_x);
		oCTC(binary_y);
		cout << a << "的补码为:" << endl; 
		for (int i = 0; i < MAXN; ++i) cout << binary_x[i];
		cout << endl;
		cout << b << "的补码为:" << endl; 
		for (int i = 0; i < MAXN; ++i) cout << binary_y[i];
		cout << endl;
		
		//然后 补码进行+法运算
		add(ans, binary_x, binary_y); 
		/*
		for (int i = 0; i < MAXN; ++i) cout << ans[i];
		cout << endl;
		*/ 
		//判断是否溢出
		int mod = pow(2, MAXN);
		int result = 0;
		cout << "计算的答案为:" << endl; 
		if ( carry[0] ^ carry[1] ) {  //溢出需要修正 
			//只有符号位溢出则
			oCTC(ans);
			result = getAns(ans);
			if (carry[0]) {
				result -= mod;
				cout << result << endl;
			}
			else {//只有最高位数值位溢出则
				result += mod;
				cout << result << endl;
			} 
		} else {	//溢出不需要修正 或者没有溢出
			oCTC(ans);
			result = getAns(ans);
			cout << result << endl;
		} 
	} 
	return 0;
} 

 

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值