带 gmp 的二进制计算器

问题描述 投票:0回答:1

我正在使用 C 中的 GMP 库创建一个具有无限精度的二进制计算器。在评估后缀表达式期间,我在尝试将结果分配给变量时遇到了错误“分配给具有数组类型的表达式”。

我很困惑为什么结果 (

ans
) 被视为数组以及如何正确地将后缀表达式的值分配给
ans
evaluatePostfix
函数应返回单个值,而不是数组。

任何关于为什么会发生此错误的见解以及如何将结果正确分配给变量的指导将不胜感激。

这是我的代码:

mpf_t evaluatePostfix(char* postfix) { //postfix func
    Stack operandStack;
    initializeStack(&operandStack);

    int i;
    mpf_t operand, op1, op2, result;
    mpf_init(operand);
    mpf_init(op1);
    mpf_init(op2);
    mpf_init(result);

    for (i = 0; postfix[i] != '\0'; i++) {
        char token = postfix[i];

        if (isOperand(token)) {
            mpf_set_str(operand, &postfix[i], 10);
            push(&operandStack, operand);
            while (postfix[i] != ' ') {
                i++;
            }
        } else if (token != ' ') {
            mpf_set_ui(op2, pop(&operandStack));
            mpf_set_ui(op1, pop(&operandStack));

            switch (token) {
                case '+':
                    mpf_add(result, op1, op2);
                    break;
                case '-':
                    mpf_sub(result, op1, op2);
                    break;
                case '*':
                    mpf_mul(result, op1, op2);
                    break;
                case '/':
                    if (mpf_cmp_d(op2, 0.0) != 0) {
                        mpf_div(result, op1, op2);
                    } else {
                        fprintf(stderr, "Error: Division by zero\n");
                        exit(EXIT_FAILURE);
                    }
                    break;
                case '%':
                    fprintf(stderr, "Error: Modulo operation not supported for floating-point numbers\n");
                    exit(EXIT_FAILURE);
                case '^':
                    fprintf(stderr, "Error: Exponentiation operation not supported for floating-point numbers\n");
                    exit(EXIT_FAILURE);
                default:
                    fprintf(stderr, "Invalid operator\n");
                    exit(EXIT_FAILURE);
            }

            push(&operandStack, result);
        }
    }

    mpf_clear(operand);
    mpf_clear(op1);
    mpf_clear(op2);

    // Create a new variable to store the result and copy the value
    mpf_t finalResult;
    mpf_init(finalResult);
    mpf_set(finalResult, result);

    // Clear the original result
    mpf_clear(result);

    return finalResult;
}

int main() {//driver
    while (1) {
        struct Num* linked_list = NULL;
        char temp;

        printf("\nEnter infix expression: ");
        while ((temp = getchar()) != '\n') {
            append(&linked_list, temp);
        }

        char* infix = linkedListToString(linked_list);

        char* postfix = (char*)malloc(strlen(infix) + 1);

        infixToPostfix(infix, postfix);
        printf("Postfix expression: %s\n", postfix);

        mpf_t ans;
        mpf_init(ans);
        ans = evaluatePostfix(postfix);
        gmp_printf("\nResult: %.2Ff\n", ans);

        free(postfix);
        free(infix);
        freeLinkedList(linked_list);
        printf("\nCtrl + c to exit\n");
    }

    return 0;
}
c calculator gmp
1个回答
0
投票

来自GMP文档关于类型:

在内部,诸如 mpz_t 之类的 GMP 数据类型被定义为单元素数组,其元素类型是 GMP 内部结构的一部分(请参阅Internals)。

所以你不能像常规变量一样分配它们。该函数应接收

ans
作为参数,并就地更新。

使用

mpf_set()
分配给
mpf_t
值。

void evaluatePostfix(char* postfix, mpf_t finalResult) { //postfix func
    Stack operandStack;
    initializeStack(&operandStack);

    int i;
    mpf_t operand, op1, op2, result;
    mpf_init(operand);
    mpf_init(op1);
    mpf_init(op2);
    mpf_init(result);

    for (i = 0; postfix[i] != '\0'; i++) {
        char token = postfix[i];

        if (isOperand(token)) {
            mpf_set_str(operand, &postfix[i], 10);
            push(&operandStack, operand);
            while (postfix[i] != ' ') {
                i++;
            }
        } else if (token != ' ') {
            mpf_set_ui(op2, pop(&operandStack));
            mpf_set_ui(op1, pop(&operandStack));

            switch (token) {
                case '+':
                    mpf_add(result, op1, op2);
                    break;
                case '-':
                    mpf_sub(result, op1, op2);
                    break;
                case '*':
                    mpf_mul(result, op1, op2);
                    break;
                case '/':
                    if (mpf_cmp_d(op2, 0.0) != 0) {
                        mpf_div(result, op1, op2);
                    } else {
                        fprintf(stderr, "Error: Division by zero\n");
                        exit(EXIT_FAILURE);
                    }
                    break;
                case '%':
                    fprintf(stderr, "Error: Modulo operation not supported for floating-point numbers\n");
                    exit(EXIT_FAILURE);
                case '^':
                    fprintf(stderr, "Error: Exponentiation operation not supported for floating-point numbers\n");
                    exit(EXIT_FAILURE);
                default:
                    fprintf(stderr, "Invalid operator\n");
                    exit(EXIT_FAILURE);
            }

            push(&operandStack, result);
        }
    }

    mpf_clear(operand);
    mpf_clear(op1);
    mpf_clear(op2);

    mpf_set(finalResult, result);

    // Clear the original result
    mpf_clear(result);

    return finalResult;
}

int main() {//driver
    while (1) {
        struct Num* linked_list = NULL;
        char temp;

        printf("\nEnter infix expression: ");
        while ((temp = getchar()) != '\n') {
            append(&linked_list, temp);
        }

        char* infix = linkedListToString(linked_list);

        char* postfix = (char*)malloc(strlen(infix) + 1);

        infixToPostfix(infix, postfix);
        printf("Postfix expression: %s\n", postfix);

        mpf_t ans;
        mpf_init(ans);
        evaluatePostfix(postfix, ans);
        gmp_printf("\nResult: %.2Ff\n", ans);

        free(postfix);
        free(infix);
        freeLinkedList(linked_list);
        printf("\nCtrl + c to exit\n");
    }

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.