domdrag
domdrag

Reputation: 601

Rounding up decimals bug in c?

I'm doing a very simple c program which receives the integer n and finds the square root approximation of n.

This is my square root approximation function up to the 5th decimal:

float sqrt_approx(int n){
    float sqrt,how_many_tenths=10,how_many_decimals=0,i;
    for (i=1;i<n;i++){
        if ((i*i)<n) continue;
        if (i*i==n){ sqrt=i; goto return_; }
        else break;
    }
    sqrt=i-1;
    for (i=0;i<10;i++){
        if (i==9){

            sqrt=sqrt+i/how_many_tenths;

            how_many_tenths*=10;
            how_many_decimals++;
            if (how_many_decimals != 5) i=0;
            else break;
        }
        if ((sqrt+i/how_many_tenths)*(sqrt+i/how_many_tenths) < n) continue;
        sqrt=sqrt+(i-1)/how_many_tenths;
        how_many_tenths*=10;
        how_many_decimals++;
        if (how_many_decimals != 5) i=0;
        else break;
    }
    return_:
        return sqrt;
}

Brute force, pretty intuitive I would say. The problem, however, appears when I'm trying to get the approximation up to the 6th decimal. In order to do that, all I need to do is to change this:

if (how_many_decimals != 5)

into:

if (how_many_decimals != 6)

both times in my code. And if I'm to evaluate the square root of $35$ approximation up to the 6th decimal, I get $5.916080$ instead of $5.916079$.

I tried to find the mistake and it appears to me that the 5th decimal gets rounded up. Take a look, I changed only a bit of my code to find out what is going on here:

float sqrt_approx(int n){
    float sqrt,how_many_tenths=10,how_many_decimals=0,i;
    for (i=1;i<n;i++){
        if ((i*i)<n) continue;
        if (i*i==n){ sqrt=i; goto return_; }
        else break;
    }
    sqrt=i-1;
    for (i=0;i<10;i++){
        if (i==9){
            printf("%f + %f equals: ",sqrt,i/how_many_tenths); //NEW
            sqrt=sqrt+i/how_many_tenths; //NEW
            printf("%f\n",sqrt); //NEW
            how_many_tenths*=10;
            how_many_decimals++;
            if (how_many_decimals != 6) i=0; //NEW (6 instead of 5)
            else break;
        }
        if ((sqrt+i/how_many_tenths)*(sqrt+i/how_many_tenths) < n) continue;
        sqrt=sqrt+(i-1)/how_many_tenths;
        how_many_tenths*=10;
        how_many_decimals++;
        if (how_many_decimals != 6) i=0; //NEW (6 instead of 5)
        else break;
    }
    return_:
        return sqrt;
}

results in ( after typing printf("%f,sqrt_approx(35)):

$5.000000 + 0.900000$ equals: $5.900000$ ( which is fine )

$5.916070+0.000009$ equals: $5.916080$ ( which is not fine )

$5.916080$

What seems to be the problem here ?

Upvotes: 0

Views: 316

Answers (1)

domdrag
domdrag

Reputation: 601

Changing float into double fixed it. Thanks for your comments guys.

Upvotes: 1

Related Questions