ccalculatorgmp

Binary calculator with gmp


I am working on creating a binary calculator with infinite precision using the GMP library in C. During the evaluation of a postfix expression, I encountered the error "assignment to expression with array type" when trying to assign the result to a variable.

I am confused about why the result (ans) is being treated as an array and how to correctly assign the value of the postfix expression to ans. The evaluatePostfix function is expected to return a single value, not an array.

Any insights into why this error is occurring and guidance on properly assigning the result to the variable would be greatly appreciated.

Here is my code:

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

Solution

  • From the GMP documentation on types:

    Internally, GMP data types such as mpz_t are defined as one-element arrays, whose element type is part of the GMP internals (see Internals).

    So you can't assign them like regular variables. The function should receive ans as a parameter which it updates in place.

    Use mpf_set() to assign to an mpf_t value.

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