Saad Mehdaoui
Saad Mehdaoui

Reputation: 51

GMP library in C - How to make the addition more precise?

Trying to create a simple precise calculator using GMP library on C, I came upon a rather unexpected error while testing my program; 2 + 2.22222 = 4.22221999999999999999.

Here is the function I am using from GMP;

mpf_add(res, f1, f2); //with res as result already initilized, f1 and f2 as the values

and as for the printing function;

gmp_printf("%.Ff\n", getExprValue()) //with getExprValue the calculating function that has the line above.

Edit :

Here is the code in its integrity;

    int isValidExpression(const char *str) // to check the input
{
    int res;
    char validOps[6] = {'+', '-', '*', '/', '^', '\0' };

    mpf_init(f1);
    mpf_init(f2);

    // RES = 3 WHEN SYNTAX OK
    res = gmp_sscanf(str, "%Ff %c %Ff", f1, &op, f2);

    // RES = 4 WHEN OPERAND OK
    if(strchr(validOps, op)) res++;

    int exprCounter = 0;
    char* token = strtok(str, " +-*/^");
    while(token != NULL)
    {
        // TOO MANY WORDS IN THE EXPRESSION
        ++exprCounter;
        if(exprCounter > 2) res = 0;

        // TAKE THE NEXT WORD
        token = strtok(NULL, " +-*/^");
    }
    return (res==4);
}
mpf_t* getExprValue() //Working on the operand
{
    static mpf_t res;
    mpf_init(res);


    switch(op)
    {
    case '+':
        mpf_add(res, f1, f2);
        break;

    case '-':
        mpf_sub(res, f1, f2);
        break;

    case '*':
        mpf_mul(res, f1, f2);
        break;

    case '/':
        mpf_sgn(f2) != 0 ? mpf_div(res, f1, f2) : printf("Division by ");
        break;

    case '^':
        mpf_pow_ui(res, f1, mpf_get_si(f2));
        break;
    }
    return res;
}

and as for the main;

char input[MAX_INPUT];
while(gets(input))
{
    if(strcmp(input, "exit") != 0)
    {
        isValidExpression(input) ? gmp_printf("%.Ff\n", getExprValue()) : puts("Expression error");

    }
    else
    {
        puts("Exiting...");
        break;
    }
}

Upvotes: 4

Views: 379

Answers (1)

Dimitris Alexopoulos
Dimitris Alexopoulos

Reputation: 21

The problem is you are trying to decimal arithmetic and using floating point numbers. You need to use a decimal arithmetic library to do exact calculations with decimal numbers.

Upvotes: 2

Related Questions