質問

In the following code, I want to replace the termination condition to: if the ratio of guess square and x is close to 1, while loop should terminate. I tried various expressions, but none run the code properly. any suggestion?

# include<stdio.h>
float absolute(float x)
{
     if (x < 0)
         x = -x;
     return x;
}

float square(float x)
{
    float guess = 1;

    while(absolute(guess*guess - x) >= 0.0001 )
        guess = ((x/guess) + guess) / 2;

    return guess;
}

int main(void)
{
    printf("square root of 2 is %f\n", square(2));
    printf("square root of 3 is %f\n", square(3));
    return 0;
}
役に立ちましたか?

解決

hit the answer: while statement should be like this:

 while  ( absoluteValue((guess * guess) / x  - 1.0) >= 0.0001 ) 

他のヒント

# include<stdio.h>

double sq_root(double x)
{
    double rt = 1, ort = 0;
    while(ort!=rt)
    {
        ort = rt;
        rt = ((x/rt) + rt) / 2;
    }
    return rt;
}

int main(void)
{
    int i;
    for(i = 2; i<1001; i++) printf("square root of %d is %f\n",i, sq_root(i));
    return 0;
}

if the ratio of guess square and x is close to 1

Then why are you subtracting? Use ratio operator:

while(absolute( (guess*guess) / x - 1) >= 0.0001 )

It's possible you can't reach that guess*guess will be enough close to x; imagine e.g. sqrt of 2e38 - every approximation will be no closer than ~1e31 and your exit condition won't ever succeed.

The variant good for all cases is that stopping for this method occur when guess stops to change. So you would write something like

prev_guess = 0; // any initial value is ok
while (guess != prev_guess) {
    ...
    prev_guess = guess;
}

at least it shall work for any IEEE754-compatible implementation not reaching overflow or underflow.

Also you can compare guess and prev_guess for difference (as soon as the goal is usually to match enough accuracy of root, not the value squared back).

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top