在用C语言编写程序模拟机器级有符号整数的加减法,1.从屏幕上读取两个整数(数的大小在-128到127之间)并存入int1,int2,这两个数作为被加数和加数或者被减数和减数。2.从屏幕上读取两个整数,这两个整数只能是4或者8,并存入n1,n2,这两个数作为int1和int2的机器数的长度,此处注意n1和n2可以不相等。3先调用valueToMachine,将int1和int2(真值)转换为两个字符串(机器码)。转换时要注意,两个字符串的长度要保持一致,n1和n2不相等时,要按照大的为准。
4 调用addsub计算返回机器码计算结果,并把sf,zf,cf,of的值保存在字符串eflags中。
5调用machineToValue,将结果机器码转换为真值。
6根据eflags输出4个F的值,输出是否发生溢出。
7 return 最终结果的真值。
3.从屏幕上读取0或者1存入sub,sub为0时表示加法,为1时表示减法。
4.计算加减法,并返回结果。
不能分别计算真值,然后做十进制加减法的本题得0分。
不能分别实现加法器和减法器。
目前我已经写好程序了,但是存在bug。
比如,当我输入7 -8 4 4 0时。程序计算得到的值为:
SF值:1
ZF值:0
CF值:1
OF值:0
但是正确的值应该是SF: 1, ZF: 0, CF: 0, OF: 0。
#include <stdio.h>
#include <stdlib.h>
int calculate(int a, int b, int n1, int n2, int operation);
char *convertToBinary(int num, int length);
char *performOperation(char *bin1, char *bin2, int operation, int length, char *flags);
int convertToValue(char *binary, int length);
int main() {
int a, b, n1, n2, operation;
// 从屏幕上读取两个整数
printf("请输入两个整数,范围在-128到127之间,用空格分隔:");
scanf("%d %d", &a, &b);
// 从屏幕上读取两个整数的长度
printf("请输入两个整数的长度(4或者8),用空格分隔:");
scanf("%d %d", &n1, &n2);
// 从屏幕上读取0或者1,表示加法或减法
printf("请输入0或1,0表示加法,1表示减法:");
scanf("%d", &operation);
// 调用calculate函数计算加减法,并输出结果
int result = calculate(a, b, n1, n2, operation);
printf("计算结果:%d\n", result);
return 0;
}
int calculate(int a, int b, int n1, int n2, int operation) {
int length = n1 > n2 ? n1 : n2;
int N=1;
// 将a和b转换为二进制码
char *bin1 = convertToBinary(a, length);
char *bin2 = convertToBinary(b, length);
// 计算加减法并返回二进制结果
char suzhu[8];
char *flags = performOperation(bin1, bin2, operation, length, suzhu);
// 将二进制结果转换为真值
int result = convertToValue(flags, length);
int sf = flags[0] - '0';
printf("SF值:%d\n",sf);
int zf = (result==0) ? 1: 0;
printf("ZF值:%d\n",zf);
int cf = flags[0] - '0'; // 加法时CF为进位,减法时CF为借位
int of=0;
// 在二进制层面上处理进位标志位CF
// 注意:CF的计算依赖于加法最高位的进位或减法最高位的借位
// 在二进制层面上处理进位标志位CF
if (operation == 0) { // 加法
// 如果最后一次进位不为0,则设置CF为1
cf = (flags[0] == '1') ? 1 : 0;
} else { // 减法
// 减法的CF应该取决于最高位的借位,这里略微复杂,因为我们需要判断是否有借位发生
// 如果bin2大于bin1,则会发生借位
cf = (convertToValue(bin2, length) > convertToValue(bin1, length)) ? 1 : 0;
}
printf("CF值:%d\n", cf);
// 在二进制层面上处理溢出标志位OF
if (operation == 0) { // 加法
// 如果最高两位进位不同,则设置OF为1
of = (bin1[0] == bin2[0]) && (bin1[0] != flags[0]) ? 1 : 0;
} else { // 减法
// 如果被减数和减数符号位相同,而结果符号位不同,则设置OF为1
of = (bin1[0] != bin2[0]) && (bin1[0] != flags[0]) ? 1 : 0;
}
printf("OF值:%d\n", of);
if (of == 1) {
printf("发生溢出!\n");
} else {
printf("未发生溢出。\n");
}
return result;
}
char *convertToBinary(int num, int length) {
char *binary = (char *) malloc((length + 1) * sizeof(char));
int mynum = num;
binary[length] = '\0';
for (int i = length - 1; i >= 0; i--) {
binary[i] = (mynum & 1) + '0';
mynum >>= 1;
}
return binary;
}
char *performOperation(char *bin1, char *bin2, int operation, int length, char *flags) {
// 初始化结果数组和进位/借位标志位
char *result = (char *)malloc((length + 1) * sizeof(char));
result[length] = '\0';
int carry_borrow = 0; // 用于加法的进位和减法的借位
// 从最低位开始逐位进行加减法操作
for (int i = length - 1; i >= 0; i--) {
int bit1 = bin1[i] - '0';
int bit2 = bin2[i] - '0';
if (operation == 0) { // 加法
int sum = bit1 + bit2 + carry_borrow;
result[i] = (sum % 2) + '0'; // 计算当前位的结果
carry_borrow = sum / 2; // 计算进位
} else { // 减法
int diff = bit1 - bit2 - carry_borrow;
if (diff < 0) {
diff += 2;
carry_borrow = 1; // 发生借位
} else {
carry_borrow = 0; // 未发生借位
}
result[i] = diff + '0'; // 计算当前位的结果
}
}
// 设置溢出和进位/借位标志位
flags[0] = (carry_borrow != 0) ? '1' : '0';
// 返回二进制结果
return result;
}
int convertToValue(char *binary, int length) {
int num = 0;
for (int i = 0; i < length; i++) {
num <<= 1;
num |= (binary[i] - '0');
}
if(length==4){
int flag = (binary[0] - '0');
if(flag==1)
num = num -16;
}
if(length==8){
int flag = (binary[0] - '0');
if(flag==1)
num = num - 256;
}
return num;
}