mr-element 2023-11-27 19:03 采纳率: 60%
浏览 25
已结题

C语言模拟机器级有符号整数的加减法

在用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;
}

  • 写回答

3条回答 默认 最新

  • 社区专家-Monster-XH 2023-11-27 19:12
    关注

    img

    
    #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;
        
        // 将a和b转换为二进制码
        char *bin1 = convertToBinary(a, length);
        char *bin2 = convertToBinary(b, length);
        
        // 计算加减法并返回二进制结果
        char flags[2]; // 用于存放进位或借位标志
        char *result = performOperation(bin1, bin2, operation, length, flags);
     
        // 将二进制结果转换为真值
        int resultValue = convertToValue(result, length);
        
        // 计算SF, ZF, CF, OF
        int sf = result[0] - '0';
        int zf = (resultValue == 0) ? 1 : 0;
        int cf, of;
        
        if (operation == 0) { // 加法
            cf = (flags[0] == '1') ? 1 : 0;
            of = (bin1[0] == bin2[0] && result[0] != bin1[0]) ? 1 : 0;
        } else { // 减法
            cf = (convertToValue(bin2, length) > convertToValue(bin1, length)) ? 1 : 0;
            of = (bin1[0] != bin2[0] && result[0] != bin1[0]) ? 1 : 0;
        }
        
        // 打印标志位
        printf("SF值:%d\nZF值:%d\nCF值:%d\nOF值:%d\n", sf, zf, cf, of);
        if (of == 1) {
            printf("发生溢出!\n");
        } else {
            printf("未发生溢出。\n");
        }
     
        // 释放内存
        free(bin1);
        free(bin2);
        free(result);
    
        return resultValue;
    }
     
    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;
    }
    
    

    溢出标志位OF的计算:你的代码中OF的计算逻辑似乎不太准确。对于加法,当两个操作数的符号位相同,但是结果的符号位与操作数的符号位不同,才会发生溢出。对于减法,当被减数和减数的符号位不同,并且结果的符号位与被减数的符号位不同时,才会发生溢出。

    进位标志位CF的计算:对于加法,CF应该是最高位的进位。对于减法,CF应当在bin2大于bin1时为1,否则为0。

    零标志位ZF的计算:ZF的计算应该是在转换为真值后进行,如果结果为0,则ZF为1,否则为0。

    符号标志位SF的计算:SF应该是结果的最高位。

    performOperation函数中的返回值处理:这个函数应该返回计算后的二进制字符串,但目前看起来你是返回了flags数组。

    修改:
    调整OF的计算逻辑。
    调整CF的计算逻辑。
    修正ZF的计算位置和逻辑。
    修正SF的计算逻辑。
    确保performOperation函数正确返回计算结果。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 12月5日
  • 已采纳回答 11月27日
  • 创建了问题 11月27日

悬赏问题

  • ¥15 livecharts wpf piechart 属性
  • ¥20 数学建模,尽量用matlab回答,论文格式
  • ¥15 昨天挂载了一下u盘,然后拔了
  • ¥30 win from 窗口最大最小化,控件放大缩小,闪烁问题
  • ¥20 易康econgnition精度验证
  • ¥15 msix packaging tool打包问题
  • ¥28 微信小程序开发页面布局没问题,真机调试的时候页面布局就乱了
  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置