Wnd_S 2018-05-07 14:29 采纳率: 100%
浏览 1039
已采纳

求大神帮忙注释c++代码。高精度计算器。

最近在学习制作高精度计算器,前辈给了我一段参考代码,但是我对其中有一部分还是不太懂。
【计算器要求】
实现两个高精度大整数(200位以内的整数)的四则运算,输出这两个大整数的和、差、积、商及余数。
· 请大神如果有空,帮我对几个运算符号代码(主程序不需要)进行注释!越详细越好!十分感谢!
· 如果寻找到可优化的部分或者bug也请进行修改并标注,谢谢!

#include <iostream>
#include <string>
using namespace std;
inline int compare(string str1, string str2) {
    if(str1.size() > str2.size()) //长度长的整数大于长度小的整数
        return 1;
    else if(str1.size() < str2.size())
        return -1;
    else
        return str1.compare(str2); //若长度相等,从头到尾按位比较,compare函数:相等返回0,大于返回1,小于返回-1
}
string ADD_INT(string str1, string str2) {//高精度加法
    string SUB_INT(string str1, string str2);
    int sign = 1; //sign 为符号位
    string str;
    if(str1[0] == '-') {
        if(str2[0] == '-') {
            sign = -1;
            str = ADD_INT(str1.erase(0, 1), str2.erase(0, 1));
        } else {
            str = SUB_INT(str2, str1.erase(0, 1));
        }
    } else {
        if(str2[0] == '-')
            str = SUB_INT(str1, str2.erase(0, 1));
        else {
            //把两个整数对齐,短整数前面加0补齐
            string::size_type l1, l2;
            int i;
            l1 = str1.size(); l2 = str2.size();
            if(l1 < l2) {
                for(i = 1; i <= l2 - l1; i++)
                    str1 = "0" + str1;
            } else {
                for(i = 1; i <= l1 - l2; i++)
                    str2 = "0" + str2;
            }
            int int1 = 0, int2 = 0; //int2 记录进位
            for(i = str1.size() - 1; i >= 0; i--) {
                int1 = (int(str1[i]) - '0' + int(str2[i]) - '0' + int2) % 10;
                int2 = (int(str1[i]) - '0' + int(str2[i]) - '0' +int2) / 10;
                str = char(int1 + '0') + str;
            }
            if(int2 != 0) str = char(int2 + '0') + str;
        }
    }
    //运算后处理符号位
    if((sign == -1) && (str[0] != '0'))
        str = "-" + str;
    return str;
}
string SUB_INT(string str1, string str2) {//高精度减法
    string MUL_INT(string str1, string str2);
    int sign = 1; //sign 为符号位
    string str;
    int i;
    if(str2[0] == '-')
        str = ADD_INT(str1, str2.erase(0, 1));
    else {
        int res = compare(str1, str2);
        if(res == 0) return "0";
        if(res < 0) {
            sign = -1;
            string temp = str1;
            str1 = str2;
            str2 = temp;
        }
        string::size_type tempint;
        tempint = str1.size() - str2.size();
        for(i = str2.size() - 1; i >= 0; i--) {
            if(str1[i + tempint] < str2[i]) {
                str1[i + tempint - 1] = char(int(str1[i + tempint - 1]) - 1);
                str = char(str1[i + tempint] - str2[i] + ':') + str;
            } else
                str = char(str1[i + tempint] - str2[i] + '0') + str;
        }
        for(i = tempint - 1; i >= 0; i--)
            str = str1[i] + str;
    }
    //去除结果中多余的前导0
    str.erase(0, str.find_first_not_of('0'));
    if(str.empty()) str = "0";
    if((sign == -1) && (str[0] != '0'))
        str = "-" + str;
    return str;
}
string MUL_INT(string str1, string str2) {//高精度乘法
    int sign = 1; //sign 为符号位
    string str;
    if(str1[0] == '-') {
        sign *= -1;
        str1 = str1.erase(0, 1);
    }
    if(str2[0] == '-') {
        sign *= -1;
        str2 = str2.erase(0, 1);
    }
    int i, j;
    string::size_type l1, l2;
    l1 = str1.size(); l2 = str2.size();
    for(i = l2 - 1; i >= 0; i --) {  //实现手工乘法
        string tempstr;
        int int1 = 0, int2 = 0, int3 = int(str2[i]) - '0';
        if(int3 != 0) {
            for(j = 1; j <= (int)(l2 - 1 - i); j++)
                tempstr = "0" + tempstr;
            for(j = l1 - 1; j >= 0; j--) {
                int1 = (int3 * (int(str1[j]) - '0') + int2) % 10;
                int2 = (int3 * (int(str1[j]) - '0') + int2) / 10;
                tempstr = char(int1 + '0') + tempstr;
            }
            if(int2 != 0) tempstr = char(int2 + '0') + tempstr;
        }
        str = ADD_INT(str, tempstr);
    }
    //去除结果中的前导0
    str.erase(0, str.find_first_not_of('0'));
    if(str.empty()) str = "0";
    if((sign == -1) && (str[0] != '0'))
        str = "-" + str;
    return str;
}
string DIVIDE_INT(string str1, string str2, int flag) {//高精度除法
    //flag = 1时,返回商; flag = 0时,返回余数
    string quotient, residue; //定义商和余数
    int sign1 = 1, sign2 = 1;
    if(str2 == "0") {  //判断除数是否为0
        quotient = "ERROR!";
        residue = "ERROR!";
        if(flag == 1) return quotient;
        else return residue;
    }
    if(str1 == "0") { //判断被除数是否为0
        quotient = "0";
        residue = "0";
    }
    if(str1[0] == '-') {
        str1 = str1.erase(0, 1);
        sign1 *= -1;
        sign2 = -1;
    }
    if(str2[0] == '-') {
        str2 = str2.erase(0, 1);
        sign1 *= -1;
    }
    int res = compare(str1, str2);
    if(res < 0) {
        quotient = "0";
        residue = str1;
    } else if(res == 0) {
        quotient = "1";
        residue = "0";
    } else {
        string::size_type l1, l2;
        l1 = str1.size(); l2 = str2.size();
        string tempstr;
        tempstr.append(str1, 0, l2 - 1);
        //模拟手工除法
        for(int i = l2 - 1; i < l1; i++) {
            tempstr = tempstr + str1[i];
            for(char ch = '9'; ch >= '0'; ch --) { //试商
                string str;
                str = str + ch;
                if(compare(MUL_INT(str2, str), tempstr) <= 0) {
                    quotient = quotient + ch;
                    tempstr = SUB_INT(tempstr, MUL_INT(str2, str));
                    break;
                }
            }
        }
        residue = tempstr;
    }
    //去除结果中的前导0
    quotient.erase(0, quotient.find_first_not_of('0'));
    if(quotient.empty()) quotient = "0";
    if((sign1 == -1) && (quotient[0] != '0'))
        quotient = "-" + quotient;
    if((sign2 == -1) && (residue[0] != '0'))
        residue = "-" + residue;
    if(flag == 1) return quotient;
    else return residue;
}
string DIV_INT(string str1, string str2) {//高精度除法,返回商
    return DIVIDE_INT(str1, str2, 1);
}
string MOD_INT(string str1, string str2) {//高精度除法,返回余数
    return DIVIDE_INT(str1, str2, 0);
}
int main() {
    char ch;
    string s1, s2, res;
    cout<<"请输入 丨 加法:“+ ” 丨 减法:“- ” 丨 乘法:“* ” 丨 除法:“/ ” 丨 余数:“% ”丨来确定计算类型!" <<endl; 
    while(cin >> ch) 
    {
        cout<<"请输入要计算的数1:" <<endl; 
        cin >> s1;
        cout<<"请输入要计算的数2:" <<endl; 
        cin >> s2;

        switch(ch) {
        case '+':  res = "加法计算的结果是:"+ADD_INT(s1, s2); break;
        case '-':  res = "减法计算的结果是:"+SUB_INT(s1, s2); break;
        case '*':  res = "乘法计算的结果是:"+MUL_INT(s1, s2); break;
        case '/':  res = "除法计算的结果是:"+DIV_INT(s1, s2); break;
        case '%':  res = "除法计算后的余数是:"+MOD_INT(s1, s2); break;
        default :  break;
        }
        cout << res << endl;
    }
    return(0);
}

  • 写回答

2条回答 默认 最新

  • 白色一大坨 2018-05-10 04:58
    关注

    我明白大概意思了,是两个字符串输入后不转换为数据,直接字符串里面按位进行计算的,我大概注释了一下,你看看:

    
    inline int compare(string str1, string str2) {
        if (str1.size() > str2.size()) //长度长的整数大于长度小的整数
            return 1;
        else if (str1.size() < str2.size())
            return -1;
        else
            return str1.compare(str2); //若长度相等,从头到尾按位比较,compare函数:相等返回0,大于返回1,小于返回-1
    }
    string ADD_INT(string str1, string str2) {//高精度加法
        string SUB_INT(string str1, string str2);
        int sign = 1; //sign 为符号位
        string str;//计算结果
        if (str1[0] == '-') {
            if (str2[0] == '-') {
                sign = -1;
                str = ADD_INT(str1.erase(0, 1), str2.erase(0, 1));// 两个数都是负数,sign负值-1表示结果为负
            }
            else {
                str = SUB_INT(str2, str1.erase(0, 1));//1为负2为正,相减
            }
        }
        else {
            if (str2[0] == '-')
                str = SUB_INT(str1, str2.erase(0, 1));//1为正2为负,相减
            else {
                //把两个整数对齐,短整数前面加0补齐
                string::size_type l1, l2;
                int i;
                l1 = str1.size(); l2 = str2.size();//获取输入的两个数长度
                if (l1 < l2) {//数1长度小于数2,在数1前面补零
                    for (i = 1; i <= l2 - l1; i++)
                        str1 = "0" + str1;
                }
                else {//数1长度大于等于数2,在数2前面补零,如果相等则不用补零
                    for (i = 1; i <= l1 - l2; i++)
                        str2 = "0" + str2;
                }
                int int1 = 0, int2 = 0; //int2 记录进位
                for (i = str1.size() - 1; i >= 0; i--) {//从个位开始循环计算,int1是相加结果,int2是进位值
                    int1 = (int(str1[i]) - '0' + int(str2[i]) - '0' + int2) % 10;
                    int2 = (int(str1[i]) - '0' + int(str2[i]) - '0' + int2) / 10;
                    str = char(int1 + '0') + str;
                }
                if (int2 != 0) str = char(int2 + '0') + str;
            }
        }
        //运算后处理符号位
        if ((sign == -1) && (str[0] != '0'))//判断符合变量sign决定数字的正负
            str = "-" + str;
        return str;
    }
    string SUB_INT(string str1, string str2) {//高精度减法
        string MUL_INT(string str1, string str2);
        int sign = 1; //sign 为符号位
        string str;
        int i;
        if (str2[0] == '-')
            str = ADD_INT(str1, str2.erase(0, 1));//数2是负值时,将数2与数1做加法
        else {
            int res = compare(str1, str2);//数2为正,比较两个数长度
            if (res == 0) return "0";//两数相等返回0
            if (res < 0) {//数1小于数2,设置符号为负,交换两个值
                sign = -1;
                string temp = str1;
                str1 = str2;
                str2 = temp;
            }
            string::size_type tempint;
            tempint = str1.size() - str2.size();//两个数的位数差
            for (i = str2.size() - 1; i >= 0; i--) {//逐位计算相减
                if (str1[i + tempint] < str2[i]) {
                    str1[i + tempint - 1] = char(int(str1[i + tempint - 1]) - 1);//数1的当前位小于数2
                    str = char(str1[i + tempint] - str2[i] + ':') + str;
                }
                else
                    str = char(str1[i + tempint] - str2[i] + '0') + str;//数1的当前位大于数2
            }
            for (i = tempint - 1; i >= 0; i--)//将前面未进行计算的的位补上
                str = str1[i] + str;
        }
        //去除结果中多余的前导0
        str.erase(0, str.find_first_not_of('0'));
        if (str.empty()) str = "0";
        if ((sign == -1) && (str[0] != '0'))
            str = "-" + str;
        return str;
    }
    string MUL_INT(string str1, string str2) {//高精度乘法
        int sign = 1; //sign 为符号位
        string str;
        if (str1[0] == '-') {//分别对数1数2进行判断,为负数则符号位修改一次
            sign *= -1;
            str1 = str1.erase(0, 1);
        }
        if (str2[0] == '-') {
            sign *= -1;
            str2 = str2.erase(0, 1);
        }
        int i, j;
        string::size_type l1, l2;
        l1 = str1.size(); l2 = str2.size();
        for (i = l2 - 1; i >= 0; i--) {  //实现手工乘法
            string tempstr;
            int int1 = 0, int2 = 0, int3 = int(str2[i]) - '0';//int1记录结果,int2记录进位
            if (int3 != 0) {
                for (j = 1; j <= (int)(l2 - 1 - i); j++)
                    tempstr = "0" + tempstr;
                for (j = l1 - 1; j >= 0; j--) {
                    int1 = (int3 * (int(str1[j]) - '0') + int2) % 10;
                    int2 = (int3 * (int(str1[j]) - '0') + int2) / 10;
                    tempstr = char(int1 + '0') + tempstr;
                }
                if (int2 != 0) tempstr = char(int2 + '0') + tempstr;
            }
            str = ADD_INT(str, tempstr);//按位累计每次相乘的结果
        }
        //去除结果中的前导0
        str.erase(0, str.find_first_not_of('0'));
        if (str.empty()) str = "0";
        if ((sign == -1) && (str[0] != '0'))
            str = "-" + str;
        return str;
    }
    string DIVIDE_INT(string str1, string str2, int flag) {//高精度除法
        //flag = 1时,返回商; flag = 0时,返回余数
        string quotient, residue; //定义商和余数
        int sign1 = 1, sign2 = 1;
        if (str2 == "0") {  //判断除数是否为0
            quotient = "ERROR!";
            residue = "ERROR!";
            if (flag == 1) return quotient;
            else return residue;
        }
        if (str1 == "0") { //判断被除数是否为0
            quotient = "0";
            residue = "0";
        }
        if (str1[0] == '-') {//根据数1数2正负判断结果正负
            str1 = str1.erase(0, 1);
            sign1 *= -1;
            sign2 = -1;
        }
        if (str2[0] == '-') {
            str2 = str2.erase(0, 1);
            sign1 *= -1;
        }
        int res = compare(str1, str2);
        if (res < 0) {//数1小于数2,商为0,余数为数1
            quotient = "0";
            residue = str1;
        }
        else if (res == 0) {//相等,商为1,余数0
            quotient = "1";
            residue = "0";
        }
        else {//数1大于数2进行除法计算
            string::size_type l1, l2;
            l1 = str1.size(); l2 = str2.size();
            string tempstr;
            tempstr.append(str1, 0, l2 - 1);
            //模拟手工除法
            for (int i = l2 - 1; i < l1; i++) {//逐位计算
                tempstr = tempstr + str1[i];
                for (char ch = '9'; ch >= '0'; ch--) { //试商
                    string str;
                    str = str + ch;
                    if (compare(MUL_INT(str2, str), tempstr) <= 0) {//数2乘以多少小于等于数1
                        quotient = quotient + ch;//商累计
                        tempstr = SUB_INT(tempstr, MUL_INT(str2, str));//余数累计
                        break;
                    }
                }
            }
            residue = tempstr;
        }
        //去除结果中的前导0
        quotient.erase(0, quotient.find_first_not_of('0'));
        if (quotient.empty()) quotient = "0";
        if ((sign1 == -1) && (quotient[0] != '0'))
            quotient = "-" + quotient;
        if ((sign2 == -1) && (residue[0] != '0'))
            residue = "-" + residue;
        if (flag == 1) return quotient;
        else return residue;
    }
    string DIV_INT(string str1, string str2) {//高精度除法,返回商
        return DIVIDE_INT(str1, str2, 1);
    }
    string MOD_INT(string str1, string str2) {//高精度除法,返回余数
        return DIVIDE_INT(str1, str2, 0);
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 使用C#,asp.net读取Excel文件并保存到Oracle数据库
  • ¥15 C# datagridview 单元格显示进度及值
  • ¥15 thinkphp6配合social login单点登录问题
  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配