qq_39677327 2022-05-09 15:00 采纳率: 94.9%
浏览 135
已结题

用c++编写整数加减法器(二进制)

编写整数加减法器:
设在main中有如下数组:
char int1[n+1];
char int2[n+1];
编写函数
Char * addsub(char int1[],char int2[],int flag, int n);
当flag为0时表示加法运算,当flag为1时表示减法运算,做n位的加减法运算,将运算结果保存至int2中,在main函数中输出运算结果。m和n分别是int1和int2的长度。在函数中必须要计算OF,CF,SF,ZF,将4个F作为返回值返回,并在main函数中输出4个值,判定是否产生了溢出,是哪一种溢出。

  • 写回答

2条回答 默认 最新

  • 关注

    思路:
    根据符合位、flag,将计算分为加法和减法运算。
    (1)如果两个数中有负数,先计算出负数的二进制补码,把负数二进制转成正数二进制,然后两个数都作为正数进行计算。
    (2)比较两个数的大小,根据两个数的符号位和运算符,决定进行加法运算还是减法运算,运算结果如果是负数,在计算结果的补码。

    代码如下:

    #define _CRT_SECURE_NO_WARNINGS 1
    #include <iostream>
    #include <string>
    using namespace std;
    
    //判断2个数的大小
    int isbig(char p1[], char p2[], int n)
    {
        //第一个位置表示符号位,从第2个位置开始判断
        int i = 1;
        for (; i < n; i++)
        {
            if (p1[i] > p2[i])
                return 1;
            else if (p1[i] < p2[i])
                return -1;
        }
        return 0;
    }
    
    //负数二进制转正数:取反+1
    char* transRes(char buf[], int n)
    {
        int i, jw = 1;
        char* out = new char[n+1]; //增加1位来表示是否有溢出
    
        out[0] = buf[0]; //符号位
        //取反
        for ( i = 1; i < n; i++) //首位符号位,先不用管
        {
            if (buf[i] == '1')
                out[i+1] = '0';
            else
                out[i+1] = '1';
        }
        //+1
        for (i = n ; i > 0; i--)
        {
            if (out[i] == '0')
            {
                if (jw == 1)
                {
                    out[i] = '1';
                    jw = 0;
                }
                else
                {
                    out[i] = '0';
                    jw = 0;
                }
            }
            else
            {
                if (jw == 1)
                {
                    out[i] = '0';
                    jw = 1;
                }
                else
                {
                    out[i] = '1';
                    jw = 0;
                }
            }
        }
        if (jw == 1)
            out[1] = '1';
        else
            out[1] = '0';
        return out;
    }
    
    //增加位数,保证与负数位数相同
    char* trans(char buf[], int n)
    {
        char* p = new char[n + 1];
        p[0] = '0';
        for (int i = 0; i < n; i++)
            p[i + 1] = buf[i];
        return p;
    }
    //计算两个数的加法,结果放在p2中
    int add(char p1[], char p2[], int n)
    {
        int i = n - 1;
        int jw = 0;
        for (; i > 0; i--)
        {
            int t = (p1[i] - '0') + (p2[i] - '0');
            p2[i] = '0' + t % 2;
            jw = t / 2;
        }
        return jw; //返回是否有进位
    }
    //计算两个数的减法
    int sub(char p1[], char p2[], int n)
    {
        int i = n - 1;
        int jw = 0;
        char ch;
        for (; i > 0; i--)
        {
            if (jw == 1)
            {
                if (p1[i] == '0')
                    ch = '1';
                else
                    ch = '0';
            }
            else
                ch = p1[i];
    
            
            if (ch == p2[i])
                p2[i] = '0';
            else
            {
                p2[i] = '1';
                if (ch > p2[i])
                    jw = 0;
                else
                    jw = 1;
            }
        }
        return jw;
    }
    
    //复制
    void copyt(char dst[], char src[], int n)
    {
        dst[0] = src[0]; //符号位
        for (int i = 1; i < n-1; i++)
        {
            dst[i] = src[i + 1];
        }
    }
    
    
    void show(char p[], int n)
    {
        for (int i = 0; i < n; i++)
            cout << (char)p[i];
        cout << endl;
    }
    //
    char* addsub(char int1[], char int2[], int flag, int n)
    {
        //初始化标志位
        char* ff = new char[5];
        for (int j = 0; j < 4; j++)
            ff[j] = '0';
        ff[4] = 0;
    
        char *p1, *p2;
        if (int1[0] == '0')
            p1 = trans(int1, n);
        else
            p1 = transRes(int1, n);
    
        if (int2[0] == '0')
            p2 = trans(int2, n);
        else
            p2 = transRes(int2, n);
    
    
        /*cout << "p1=";
        show(p1,n+1);
        cout << "p2=";
        show(p2,n+1);*/
    
        if (flag == 0) //加法
        {
            if (p1[0] == p2[0]) //符号相同
            {
                int res = add(p1, p2, n + 1);
                if (res == 1)
                    ff[1] = '1';//最高位进位,CF=1,不进位为0
    
                //如果是负数,取补码
                if (p1[0] == '1')
                {
                    char* p3 = transRes(p2, n + 1);
                    //结果放在int2中
                    copyt(int2, p3, n + 1);
                    delete[] p3; p3 = 0;
                }
                else
                {
                    copyt(int2, p2, n + 1);
                }
                
            }
            else
            {
                int bb = isbig(p1, p2, n + 1);
                if (bb == 1)
                {
                    sub(p1, p2, n + 1);
                    if (p1[0] == '1')
                        ff[2] = '1';//结果为负,即符号位为1时SF=1,否则为0.
    
                    p2[0] = p1[0];//跟大数保持符号一致
    
                    if (p2[0] == '1')
                    {
                        char* p3 = transRes(p2, n + 1);
                        copyt(int2, p3, n + 1);
                        delete[] p3; p3 = 0;
                    }
                    else
                    {
                        //结果放在int2中
                        copyt(int2, p2, n + 1);
                    }
    
                    
                }
                else if (bb == -1)
                {
                    sub(p2, p1, n + 1);
                    if (p2[0] == '1')
                        ff[2] = '1';//结果为负,即符号位为1时SF=1,否则为0.
    
                    //ff[1] = '1';//最高位进位,CF=1,不进位为0 最高位有借位
                    p1[0] = p2[0]; //跟大数保持符号一致
    
                    if (p1[0] == '1')
                    {
                        char* p3 = transRes(p1, n + 1);
                        copyt(int2, p3, n + 1);
                        delete[] p3; p3 = 0;
                    }else
                        //结果放在int2中
                        copyt(int2, p1, n + 1);
                }
                else
                {
                    sub(p1, p2, n + 1);
                    ff[3] = '1';//结果为0,ZF=1,否则为0
                    p2[0] = '0';
                    //结果放在int2中
                    copyt(int2, p2, n + 1);
                }
                
            }
        }
        else
        {
            if (p1[0] == '0' && p2[0] == '0')
            {
                int bb = isbig(p1, p2, n + 1);
                if (bb == 1)
                {
                    sub(p1, p2, n + 1);
                    //结果放在int2中
                    copyt(int2, p2, n + 1);
                }
                else if (bb == -1)
                {
                    sub(p2, p1, n + 1);
                    ff[0] = '1';//两操作数符号相同但结果与符号位相反,OF=1
                    ff[2] = '1';//结果为负,即符号位为1时SF=1,否则为0.
                    p1[0] = '1';
                    char* p3 = transRes(p1, n + 1);
                    //结果放在int2中
                    copyt(int2, p3, n + 1);
                    delete[] p3; p3 = 0;
                }
                else
                {
                    sub(p1, p2, n + 1);
                    ff[3] = '1';//结果为0,ZF=1,否则为0
                    //结果放在int2中
                    copyt(int2, p2, n + 1);
                }
            }
            else if (p1[0] == '0' && p2[0] == '1')
            {
                p2[0] = '0';
                int ret = add(p1, p2, n + 1);
                if (ret == 1)
                    ff[1] = '1';//最高位进位,CF=1,不进位为0
    
                //结果放在int2中
                p2[0] = '0';
                copyt(int2, p2, n + 1);
            }
            else if (p1[0] == '1' && p2[0] == '0')
            {
                p2[0] = '1';
                int ret = add(p1, p2, n + 1);
                if (ret == 1)
                    ff[1] = '1';//最高位进位,CF=1,不进位为0
                p2[0] = '1';
                char* p3 = transRes(p2, n + 1);
                //结果放在int2中
                copyt(int2, p3, n + 1);
                delete[] p3; p3 = 0;
            }
            else
            {
                p2[0] = '0';
                int bb = isbig(p1, p2,n+1);
                if (bb==1)
                {
                    sub(p1, p2, n + 1);
                    ff[2] = '1';//结果为负,即符号位为1时SF=1,否则为0.
                    p2[0] = '1';
                    char* p3 = transRes(p2, n + 1);
                    //结果放在int2中
                    copyt(int2, p3, n + 1);
                    delete[] p3; p3 = 0;
                }
                else if (bb == -1)
                {
                    sub(p2, p1, n + 1);
                    p1[0] = '0';
                    //结果放在int2中
                    copyt(int2, p1, n + 1);
                }
                else
                {
                    sub(p1, p2, n + 1);
                    ff[3] = '1';//结果为0,ZF=1,否则为0
                    //结果放在int2中
                    copyt(int2, p2, n + 1);
                }
    
            }
        }
    
        delete[] p1; p1 = 0;
        delete[] p2; p2 = 0;
    
        return ff;
    
    }
    
    int main()
    {
        char int1[100], int2[100];
        int n;
        cin >> n;
        cin >> int1;
        cin >> int2;
        char* p = addsub(int1, int2, 0, n);
        //输出结果
        for (int i = 0; i < 7; i++)
            cout << (char)int2[i];
        cout << endl;
        cout << p;
        return 0;
    }
    
    /* 
    //这种写法在部分编译器中不能用
    int n;
    cin >> n;
    char int1[n + 1], int2[n + 1];
    cin >> int1;
    cin >> int2;
    */
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

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

悬赏问题

  • ¥15 根据以下文字信息,做EA模型图
  • ¥15 删除虚拟显示器驱动 删除所有 Xorg 配置文件 删除显示器缓存文件 重启系统 可是依旧无法退出虚拟显示器
  • ¥15 vscode程序一直报同样的错,如何解决?
  • ¥15 关于使用unity中遇到的问题
  • ¥15 开放世界如何写线性关卡的用例(类似原神)
  • ¥15 关于并联谐振电磁感应加热
  • ¥60 请查询全国几个煤炭大省近十年的煤炭铁路及公路的货物周转量
  • ¥15 请帮我看看我这道c语言题到底漏了哪种情况吧!
  • ¥60 关机时蓝屏并显示KMODE_EXCEPTION_NOT_HANDLED,怎么修?
  • ¥66 如何制作支付宝扫码跳转到发红包界面