Why does this code for newton's method not work in C (using a while loop)?
#include <stdio.h>
#include <math.h>
int main()
{
// ax^3 + bx^2 + cx + d = 0
float a,b,c,d,guess,derivative;
double functional_value, accuracy;
printf("Please enter values for a,b,c,d respectively :\n");
scanf("%f %f %f %f", &a, &b, &c, &d);
printf("Please enter your best guess for a root:\n");
scanf("%f", &guess);
printf("How close you want the value to be ?\n");
scanf("%f", &accuracy);
while (fabs(functional_value) <= accuracy && derivative != 0)
{
functional_value = a*pow(guess,3) + b*pow(guess,2) + c*(guess) + d ;
// 3ax^2 + 2bx + c
derivative = 3*a* pow(guess,2) + 2*b*(guess) + c ;
guess -= ((functional_value)/(derivative)) ;
}
printf("A root of the equation is approximately equal to %f", guess);
return 0;
}
I am new to programming, I was just learning C in college. And I wanted to make a program that would calculate roots using newton's method for up to cubic polynomials. So I wrote the above code.
But when I run it, the loop seems to run infinitely. I even tried giving the inputs as 0 1 -2 1 (a quadratic equation whose root is 1) but the loop is still running.
I don't notice any mistakes. Can anyone please help me in finding my mistake ? like what's wrong ?
At first I didn't have any parameter for the accuracy i.e. how close one would want the root to be, so I added that as a double.
I have looked at somewhat similar questions but I don't know all the things in C they are using.
Edit#1 : Thanks for the comments and pointing out my foolish syntax mistakes
Edit#2 : Now the program runs but it doesn't calculate a root still. I get the following output
Please enter values for a,b,c,d respectively :
0 1 -2 1
Please enter your best guess for a root:
0.5
How close you want the value to be ?
0.01
A root of the equation is approximately equal to nan
Process finished with exit code 0
Edit#3 : Thanks to Eric Postpichilli now the program does calculate a root after using fabs() and comparing the functional_value to be less than or equal to accuracy. But I still can't understand why will a division by zero occur, I have used an "AND" operator in the loop condition to try and prevent that
Compiling with warnings enabled (using Clang) reveals:
- In line 17,
scanf("%f", &accuracy);
is wrong because%f
is for scanning afloat
, butaccuracy
is adouble
. - In line 48, the compiler reports the
guess
ofb*(guess,2)
is unused. This is because the intendedpow
is missing, soguess,2
forms a comma-operator expression, which ignores its left operand. - In line 19,
while (functional_value != accuracy & derivative != 0)
,functional_value
andderivative
are used without having been initialized.
Always compile with warnings enabled. With Clang, start with -Wmost
. With GCC, start with -Wall
. With MSVC, start with /W3
.
Elevate warnings to errors. With Clang and GCC, use -Werror
. With MSVC, use /WX
.
You may want to make the loop a do … while
instead of a while …
so that functional_value
is given a value before being used. However, the loop test is still wrong. There is no reason to expect functional_value
will ever exactly equal accuracy
. You want some test of whether functional_value
is at least as close as accuracy
, such as fabs(functional_value) <= accuracy
.
Also, by the time derivative != 0
is tested in the loop test, it is too late, because it was already used in (functional_value)/derivative
, so a division by zero will have been executed.