1. 实验要求
用C/C++编程实现两个十进制整数(将其转换成补码)加、减运算结果,提示思想:模4补码进行计算
2. 相关知识点
机器字长全部假设为 8 位,只讨论整数,后不再特殊说明
0. 符号位
之前我们符号位都是用 1 位表示,模 4 补码是用 2 位表示,对应关系如下:
符号位 | 表示 |
---|---|
00 | 正数 |
01 | 上溢 |
10 | 下溢 |
11 | 负数 |
特别提醒:补码运算符号位作为数的一部分参与运算
1. 补码加法
X + Y = [X] 补 _补 补 + [Y] 补 _补 补
- 符号位参与运算
- 如果有多出来的第三个符号位直接丢弃
- 运算结果也是补码
- 最终将运算结果转回真值
2. 补码减法
X - Y = [X] 补 _补 补 + [-Y] 补 _补 补
规则同补码加法
3. 实现思路
0. 准备
包括:
- 检查输入是否合法,即第一个输入为"+“或”-",其后输入为数字
- 确定输入十进制的正负
- 将输入的 string 转换为 int 类型
1. 转二进制
由准备工作准备好的 int 类型的数字直接转换为二进制,不过要注意两点,一是当数字为 0 时,取不到值,这时我们自己手动添个 0 上去,二是当数字为负数时,结果就很迷…解决方法是用其他变量暂存数字的绝对值
2. 转相反数的补码
和转补码类似,转的时候想到它的相反数
3. 实现加法
对于字符串来说,需要先把俩运算的字符串逆序,算出结果了再逆序一次,需要注意的地方就是注意保留进位和进位每次一起运算
3. 补码转真值
生成的结果可能会产生进位,比如 8 位 + 8 位 = 9 位,这种情况下最高位要丢弃,然后判断此时的符号位是 11 10 01 还是 00,10 和 01 的情况是溢出,11 为负,00 为正
但是有特殊情况,比如 [11101010] 补 _补 补 + [11010110] 补 _补 补 = [111000000] 补 _补 补,此时应该为溢出,需要在 11 单独处理
4. 具体实现
#include<iostream>
#include<cmath> //abs
#include<malloc.h> //malloc
#include<algorithm> // reverse
#include<string> // string
#include<sstream> // stringstream
#define PLUS 1 // 正
#define MINUS -1 // 负
#define SYMBOLNUM 2 // 符号位长度
#define WORD_LENGTH 8 // 机器字长
#define MIN (-(1<<(WORD_LENGTH-SYMBOLNUM))) // 最小取值范围
#define MAX ((1<<(WORD_LENGTH-SYMBOLNUM))-1) // 最大取值范围
using namespace std;
typedef struct Integer *Number;
struct Integer{
// 定义一个结构体,把该数的各种码放进去
string input; // 输入的带符号十进制整数
string binary; // 二进制真值 X
string yuan_code; // 原码
string between_bu_code; // 二进制真值的相反数的补码 [-X]补
string bu_code; // 补码 [X]补
string yi_code; // 移码
int symbol; // 符号位
int decimal; // 十进制整数
};
/* 准备工作
1.检查输入是否合法
2.确定输入十进制数的正负
3.将 string 类型转换成 int 类型
4.确定输入十进制数的范围
*/
void prepare(Number num){
// 验证输入合法性,确定该十进制整数的正负
for(int i=0;i<(num->input.size());i++){
if(num->input[0]=='+' && !i)