简体   繁体   中英

How to break out of a loop in C

I'm writing a bisection method algorithm to find the roots of polynomials. The second part of my code where it says if variable FP is equal to zero or absolute value of ba it just breaks the if statement I guess.

I want the program to stop the for loop (iteration) entirely and return p. And at the end I want to print the number of iteration it took to get the solution but apparently using my printf statement it shows that the program keeps executing even thought the root (zero) is obtained.

Any ideas on how to stop the whole mechanism and return both the value of p which is zero and the exact number of iteration it took? Thanks

double computeroots(double a, double b, double epsilon, int MaxIter)
{
    double FA = pow(a,4) -4*a +  1;
    double FB = pow(b,4) - 4*b + 1;
    double FP;
    double p;
    int i;

    for(i=0;i<MaxIter;i++) {
        if(FA * FB < 0) {
            p = a + (b-a)/2;
            FP = pow(p,4) - 4*p +1;
            if(FP == 0 || abs(b-a) < epsilon) {
                return p;
                break;
            } else if (FA * FP >0) {
                a =p;
                FA = FP;
            } else {
                b = p;
                FB = FP;
            }
            i++;
        }
    }

    printf("The number of iterations is: %d\n", i);
}

Your printf statement isn't hit because you have a return p; before the break statement. A return statement immediately exits the function.

You need to move the return statement to after the printf , or move the printf before the return :

        if(FP == 0 || abs(b-a) < epsilon)
        {
            printf("the number of iterations is : %d\n", i);
            return p;
        }
        ...

    printf("failed to converge after %d iterations\n", i);
    return p;
}

If you have a return statement, then your break statement is useless. The return exits the scope of the function and goes back to the caller so no more instructions are executed afterward.

So this:

return p;
break;

should become:

printf("the number of iterations is : %d\n", i);
return p;

If you see that the exit condition is not correctly chosen I'd guess it's more a finite precision problem . You are checking FP == 0 but FP is a double so you have to stop when FP is enough close to 0 not when it is exactly equal. Eg: abs(FP) < epsilon .

When you need to return more than one value, you can do it with out-arguments. Change your function to

double computeroots(double a, double b, double epsilon, int MaxIter, int *numIterations)

call it like this:

int numIter;
soln = computeroots(a, b, epsilon, MaxIter, &numIter);

and in your function, just before returning, add:

*numIterations = i;

To merge all necessary modifications:

double computeroots(
  double a, 
  double b, 
  double epsilon, 
  size_t MaxIter, 
  size_t * pNumIter
) 
{
    double FA = pow(a,4) -4*a +  1;
    double FB = pow(b,4) - 4*b + 1;
    double FP;
    double p = NaN;
    size_t i;

    for(i=0; i<MaxIter; ++i) {
        if(FA * FB < 0) {
            p = a + (b-a)/2;
            FP = pow(p,4) - 4*p +1;
            if(FP == 0 || abs(b-a) < epsilon) {
                break;
            } else if (FA * FP >0) {
                a =p;
                FA = FP;
            } else {
                b = p;
                FB = FP;
            }
        }
    }

    *pNumIter = i;

    printf("the number of iterations is : %z\n", *pNumIter);

    return p;
}

Call it like so:

double a, b, epsilon;
size_t sizeMax, sizeIterations;

... /* some initialisations here */

double d = computeroots(a, b, epsilon, sizeMax, &sizeIterations);

Notes on modifications:

  • removed misplaced return
  • added missing return at the end
  • changed int s to be size_t , as an unsigned type suits better for counters
  • added reference to additional size_t variable to return number of iterations
  • removed second incrementation of i

You can return an array of doubles, where the first element is the result, and the second one is the number of iteration.

Or, you pass the reference to a variable to the function, and assign to it, like this:

double compute_something(int param1, int param2, int* iterations) {
    // your code ...
    // when you want to return, use this:
    *iterations = 5;
    return 1.23;
    // your code ...
}

int iter;
double result = compute_something(1,2, &iter);

After this, result contains the result, and iter the number of iterations that you stored. This solution would likely be better, because you are not returning the number of iterations (which is clearly an integer number) as a double.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM