1

For some reason, I'm not sure what, it isn't showing the approx root, the avg which should be printed as a non-zero floating point is rather giving 0 as it's value at the end, I'm also not sure if fabs is necessary here or not. Please help me out, p.s- my first question here.

// C program for bisection method
#include<stdio.h>
#include<math.h>
#define F(x) (x*x*x-9*x+1)



int main(int argc, char const *argv[])
{
    double guess_1, guess_2,func, avg;
    
    printf("Enter values of 1st guess and 2nd guess : ");  //assumes the initial 2 values from user
    scanf("%lf%lf",&guess_1,&guess_2);

    for (int i = 1; fabs(F(avg)) < 0.001; i++)
    {
        avg=(guess_1+guess_2)/2;
        if (F(guess_1)*F(avg)<0)
        {
            guess_2=avg;
        }else
        {
            guess_1=avg;

        }
        
        
    }
    
printf("approximate root is : %lf",avg);

    return 0;
}

  • 1
    Now seems like a very good time to learn how to use a [*debugger*](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) to step through your code line by line while monitoring variables and their values. To help with this, split up complex expressions (like the whole `F` macro invocation) to see intermediate result. That will make it easier to figure out when a calculation goes wrong. – Some programmer dude Sep 19 '22 at 17:19
  • 1
    Not causing your problem but this is a bad idea: `#define F(x) (x*x*x-9*x+1)` You should always enclose each parameter in brackets: `#define F(x) ((x)*(x)*(x)-9*(x)+1)`. Just imagine what happens if you use `F(i+2)` somewhere. – Gerhardh Sep 19 '22 at 17:25
  • `scanf` returns number of values successfully read. Check to make sure your format string is matching what you think it is. I personally would suggest you avoid `scanf` all together and use command line arguments in `argv` but I suppose that's a matter of opinion. – erik258 Sep 19 '22 at 17:25
  • `fabs(F(avg)) < 0.001` Remember: Second field of a `for` loop is the condition to execute the loop. I would assume you want to run the loop as long as your values are too large. – Gerhardh Sep 19 '22 at 17:27
  • 4
    `avg` is uninitiliased so the loop's behaviour first time is undefined. All bets are off whether it will iterate at all. What is the loop's `i` for? I suggest you use a `do ... while` loop here. – Weather Vane Sep 19 '22 at 17:32
  • 1
    Tejas Aggarwal, Note that `#define F(x) (((x)*(x)-9)*(x)+1)` is numerically more stable than `#define F(x) ((x)*(x)*(x)-9*(x)+1)`. `#define F(x) ( (((x)-3) * ((x)+3) * (x) + 1)` is even better. – chux - Reinstate Monica Sep 19 '22 at 21:09

1 Answers1

3

You have 2 main issues:

  1. avg is not initialized as Weather Vane pointed out in comment.

  2. Your condition to terminate to loop is incorrect. You loop until you error gets too large. The opposite should be the case.

A fixed version is below:

// C program for bisection method
#include<stdio.h>
#include<math.h>

#define F(x) ((x)*(x)*(x)-9*(x)+1)

int main(void)
{
    double guess_1, guess_2, avg;
    
    printf("Enter values of 1st guess and 2nd guess : ");  //assumes the initial 2 values from user
    scanf("%lf%lf",&guess_1,&guess_2);
    // TODO: Check if result == 2

    avg=(guess_1+guess_2)/2;
    while (fabs(F(avg)) > 0.001)
    {
        avg=(guess_1+guess_2)/2;
        if (F(guess_1)*F(avg)<0)
        {
            guess_2=avg;
        }else
        {
            guess_1=avg;
        }
    }
    
    printf("approximate root is : %lf",avg);
    return 0;
}

Output:

a)
Enter values of 1st guess and 2nd guess : 2.3 3.5
approximate root is : 2.942810

b)
Enter values of 1st guess and 2nd guess : -1.0 1.0
approximate root is : 0.111328

Further improvements:

  • Removed unused variables
  • Changed for loop to while loop.
  • Wrapped x in brackets in macro definition.
Gerhardh
  • 11,688
  • 4
  • 17
  • 39