概述
#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;
}
最后
以上就是曾经酒窝为你收集整理的单符号位的溢出和修正(计算机组成原理)的全部内容,希望文章能够帮你解决单符号位的溢出和修正(计算机组成原理)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复