-6

I have a function called Bisection method that Accepts 4 parameters , delegate of a function , start and end of interval and user guess of the solution. Here is the function:

  public static double Bisection_method (MyFun fun , double start , double 
    end, double? guess)
    {
        if ( fun(start) * fun(end) > 0 )
        {
            Console.WriteLine("wrong Entry");
            return -1;
        }

        double avg,tolerance,sign;

        avg = (guess.HasValue) ? guess.Value : ( (start + end) / 2 );
        do
        {
            tolerance = Math.Abs ( fun(end) - fun(start) );

            sign = fun(start) * fun(avg);
            if (sign < 0)
                end = avg;
            else if (sign > 0)
                start = avg;
            else
            {
                if (fun(start) == 0)
                    return start;
                else return end;
            }

            avg = (start + end) / 2;
        }
        while ( tolerance > 0.0001 );

        return end;
    }

Now there is some cases I want to handle:

1- Can we enter the start of the interval a negative number ? and if so, how can we handle sqrt ?

2- If the user enters the interval start from zero, and the function I'm passing to the delegate has Ln() or Log(), how can we handle this ?

Ahmad Adel
  • 136
  • 2
  • 11
  • Next, of course, you can handle both cases. Just implement what you already have as textual description. I mean, you also managed to write the existing code, or not? – UninformedUser Oct 09 '17 at 21:32
  • and about the nullable double , it is valid btw and the program is running – Ahmad Adel Oct 09 '17 at 21:34
  • 1
    There are so many things wrong with the design and implementation of this method it is hard to know where to start. If you want good advice on how to improve this, **get it working fully**, improve it as much as you possibly can, and then post it on the code review site. – Eric Lippert Oct 09 '17 at 21:43
  • Yes, I'm talking C# here and double? is nullable double. – Ahmad Adel Oct 09 '17 at 21:44
  • 3
    As for your questions: (1) you designed a method that has a precondition that the function be defined over the entire range. Your question is "what if I have a function that doesn't meet my preconditions?" Well, **you designed the precondition**. If you want a different precondition then *state the precondition and the postconditions which follow*. And (2) same answer; if you want the precondition to be that the function is valid over the *open interval* then change the method so that it only explores the function on the open interval. – Eric Lippert Oct 09 '17 at 21:45
  • @azurefrog Ah, I didn't see the `?` – UninformedUser Oct 10 '17 at 03:13

1 Answers1

2

The problem is: if fun is Math.Sqrt(double) and start is negative, then fun(start) is NaN and so is fun(start) * fun(end), but NaN > 0 evaluates to false.

You need to explicitly check for NaN:

double fstart = fun(start);
double fend = fun(end);
if ( double.IsNaN(fstart) || double.IsNaN(fend) || fstart * fend > 0 )
{
    Console.WriteLine("wrong Entry");
    return -1; // this may not be the best way to report an error
}

In addition, you might want to check double.IsNaN(fun(avg)) inside the loop to handle e.g. fun = x => x * Math.Sqrt(x*x-1) with start < -1 and end > 1.

Henrik
  • 23,186
  • 6
  • 42
  • 92