秋天树下的太阳 2024-02-24 11:52 采纳率: 62.5%
浏览 7

GMP库浮点数计算有误


#include <iostream>
#include <string>
#include <algorithm>
#include <stack>
#include <windows.h>
#include <math.h>
#include <iomanip>
#include <gmpxx.h>
using namespace std;
stack<char> bracket;

bool legitimacy(const string &input) {
    //没有问题,省略
}

bool is_negative(const string &s) {
    return s[0] == '-';
}//判断正负

int compare(const string &a, const string &b) {
    if (is_negative(a)) {
        if (is_negative(b)) {
            return compare(a.substr(1), b.substr(1));
        } else {
            return -1;
        }
    } else {
        if (is_negative(b)) {
            return 1;
        } else {
            if (a.size() != b.size()) {
                return a.size() - b.size();
            } else {
                for (int i = 0; i < a.size(); ++i) {
                    if (a[i] != b[i]) {
                        return a[i] - b[i];
                    }
                }
                return 0;
            }
        }
    }
}//比较两数

mpf_class add(mpf_class a, mpf_class b) {
    return a + b;
}//加法

mpf_class subtract(mpf_class a, mpf_class b) {
    return a - b;
}//减法

mpf_class multiply(mpf_class a, mpf_class b) {
    return a * b;
}//乘法

mpf_class divide(mpf_class a, mpf_class b) {
    return a / b;
}//除法

mpf_class calculate(const string &input) {
    stack<char> op_stack;
    stack<mpf_class> num_stack;
    for (int i = 0; i < input.size(); ++i) {
        if (isdigit(input[i])) {
            mpf_class num = 0;
            mpf_class decimal = 0.1;
            bool is_decimal = false;
            while (i < input.size() && (isdigit(input[i]) || input[i] == '.')) {
                if (input[i] == '.') {
                    is_decimal = true;
                } else {
                    if (is_decimal) {
                        decimal /= 10;
                        num += (input[i] - '0') * decimal;
                    } else {
                        num = num * 10 + (input[i] - '0');
                    }
                }
                ++i;
            }
            --i;
            num_stack.push(num);
        } else if (input[i] == '(') {
            op_stack.push(input[i]);
        } else if (input[i] == ')') {
            while (!op_stack.empty() && op_stack.top() != '(') {
                mpf_class s2 = num_stack.top();
                num_stack.pop();
                mpf_class s1 = num_stack.top();
                num_stack.pop();
                char op = op_stack.top();
                op_stack.pop();
                mpf_class res;
                if (op == '+')
                    res = add(s1, s2);
                if (op == '-')
                    res = subtract(s1, s2);
                if (op == '*')
                    res = multiply(s1, s2);
                if (op == '/')
                    res = divide(s1, s2);
                num_stack.push(res);
            }
            op_stack.pop();
        } else if (input[i] == '+' || input[i] == '-' || input[i] == '*' || input[i] == '/') {
            while (!op_stack.empty() && (input[i] == '+' || input[i] == '-') && (op_stack.top() == '*' || op_stack.top() == '/')) {
                mpf_class s2 = num_stack.top();
                num_stack.pop();
                mpf_class s1 = num_stack.top();
                num_stack.pop();
                char op = op_stack.top();
                op_stack.pop();
                mpf_class res;
                if (op == '+')
                    res = add(s1, s2);
                if (op == '-')
                    res = subtract(s1, s2);
                if (op == '*')
                    res = multiply(s1, s2);
                if (op == '/')
                    res = divide(s1, s2);
                num_stack.push(res);
            }
            op_stack.push(input[i]);
        } else {
            continue;
        }
    }
    while (!op_stack.empty()) {
        mpf_class s2 = num_stack.top();
        num_stack.pop();
        mpf_class s1 = num_stack.top();
        num_stack.pop();
        char op = op_stack.top();
        op_stack.pop();
        mpf_class res;
        if (op == '+')
            res = add(s1, s2);
        if (op == '-')
            res = subtract(s1, s2);
        if (op == '*')
            res = multiply(s1, s2);
        if (op == '/')
            res = divide(s1, s2);
        num_stack.push(res);
    }
    return num_stack.top();
}//逻辑计算

void print_result(const mpf_class &input) {
    mpf_class num;
    mp_exp_t expo;
    string str = num.get_str(expo, 10, 0);
    int len = str.length();
    char *output = new char[len + 1];
    mp_exp_t exp;
    mpf_get_str(output, &exp, 10, 0, input.get_mpf_t());
    for (size_t i = 0; i < strlen(output); ++i) {
        if (output[i] == 'e') {
            output[i] = 'E';
        }
    }
    cout << "结果为:" << setprecision(20) << output << endl;
    delete[] output;
    return;
}//将科学计数法转换为普通数字

int main() {
    system("color A");
    string input;
    do {
        cout << "请输入表达式(输入0结束):";
        cin >> input;
        if (input == "0") {
            break;
        }
        if (!legitimacy(input)) {
            cout << "输入不合法,请重新输入:";
            continue;
        }
        mpf_class result = calculate(input);
        print_result(result);
    } while (true);
    return 0;
}

上述代码通过g++编译后,在处理浮点数运算时计算有误,还有可能异常退出,怎么解决

  • 写回答

3条回答 默认 最新

  • 码农阿豪@新空间代码工作室 Java领域优质创作者 2024-02-24 11:52
    关注
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如需一对一服务私聊我哦
    问题:这段代码是用来做什么的?请详细解释其主要功能和实现方法,并给出代码中的关键函数解释。 答:这段代码是一个计算器程序,可以进行基本的加减乘除运算,同时支持带括号的复杂表达式。具体实现方法是使用两个栈,一个用于存放运算符,一个用于存放运算数,并按照算数优先级依次计算表达式的值。 其中,关键函数包括:
    1. bool legitimacy(const string &input) 该函数用于判断输入的表达式是否合法,即是否符合括号匹配规则等。这里省略了具体实现代码。
    2. bool is_negative(const string &s) 该函数用于判断一个字符串代表的数是否为负数,通过判断首字母是否为负号来判断。
    3. int compare(const string &a, const string &b) 该函数用于比较两个字符串代表的数的大小关系,通过判断正负和位数大小来逐位比较。
    4. mpf_class add(mpf_class a, mpf_class b)
    5. mpf_class subtract(mpf_class a, mpf_class b)
    6. mpf_class multiply(mpf_class a, mpf_class b)
    7. mpf_class divide(mpf_class a, mpf_class b) 以上四个函数分别代表加、减、乘、除运算。由于涉及大数运算,使用GMP库的mpf_class类型来存储结果。
    8. mpf_class calculate(const string &input) 该函数是主要的计算函数,依次扫描表达式中的每个元素(数字、运算符或括号),根据算数优先级进行运算并将结果存入栈中,最终得到总的运算结果。具体实现过程中,需要注意小数的处理、负数的判断、括号的处理等多个方面。
    评论

报告相同问题?

问题事件

  • 创建了问题 2月24日

悬赏问题

  • ¥15 pyqt怎么把滑块和输入框相互绑定,求解决!
  • ¥20 wpf datagrid单元闪烁效果失灵
  • ¥15 券商软件上市公司信息获取问题
  • ¥100 ensp启动设备蓝屏,代码clock_watchdog_timeout
  • ¥15 Android studio AVD启动不了
  • ¥15 陆空双模式无人机怎么做
  • ¥15 想咨询点问题,与算法转换,负荷预测,数字孪生有关
  • ¥15 C#中的编译平台的区别影响
  • ¥15 软件供应链安全是跟可靠性有关还是跟安全性有关?
  • ¥15 电脑蓝屏logfilessrtsrttrail问题