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:
return
int
s to be size_t
, as an unsigned
type suits better for counters size_t
variable to return number of iterations 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.