0

Here's the prompt for this particular assignment: Let x be any real number. Write a program which calculates the square root of x by using Bisection method (https://docs.python.org/3/library/functions.html#format). Note that you should reduce this problem to the bisection method with a natural choice for a and b (i.e., the user does not need to provide a and b). Note that Math.powand Math.sqrt are not allowed.

The problem is that I'm not getting the right answers when I input whole numbers like 100 (which the root of is "10.0" but instead the console returns "9.999997615814209") or 36 ("6.0" but the console returns "5.999997138977051"). I think it may have to do with the fact I'm rounding the numbers or just the fact that I'm using doubles in general but I don't really understand mathematics in programming well. Thanks for helping me.

import java.text.DecimalFormat;
import java.util.Scanner;

public class BisectionMethod {

    public double a = 0;
    public double b;
    public double userInput;
    public int iteration = 0;
    public double midpoint;

    public static void main(String[] args) {
        BisectionMethod testClass = new BisectionMethod();
        System.out.println("Answer: " + testClass.FindAnswer(testClass.FindInput(), testClass.a, testClass.FindInterval()));
    }

    public double FindInput() {
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter the number to find the root for: ");
        userInput = sc.nextDouble();
        while (userInput < 0) {
            System.out.println("Please enter a number bigger than 0: ");
            userInput = sc.nextDouble();
        }
        sc.close();
        return userInput;
    }

    public double FindInterval() {
        while (b * b < userInput) {
            b = b + 1;
        }
        return b;
    }

    public double RoundNumber(double number) {
        //Rounds number to 4 decimal places.
        String pattern = "#.####";
        DecimalFormat formatNumber = new DecimalFormat(pattern);
        double rounded = Double.valueOf(formatNumber.format(number));
        return rounded;
    }

    public double FindAnswer(double number, double interval1, double interval2) {

        midpoint = (interval1 + interval2) / 2;
        double difference = (midpoint * midpoint) - number;

        while (RoundNumber(difference) != 0) {
            midpoint = (interval1 + interval2) / 2;
            difference = (midpoint * midpoint) - number;
            if (midpoint * midpoint < number) {
                interval1 = midpoint;
            } else {
                interval2 = midpoint;
            }
            iteration = iteration + 1;
        }
        System.out.println("Iterations: " + iteration);
        return midpoint;
    }
}
Harrison
  • 653
  • 3
  • 6
  • 17
  • Since calculation is rounded to 4 decimal places, try rounding the result to 4 decimal places. – Andreas Jun 04 '18 at 03:39
  • @Andreas wow thanks it worked! But I don't really understand why lol – Harrison Jun 04 '18 at 03:42
  • Your code is narrowing in on the solution, each iteration getting closer and closer. You made the code stop trying once `difference` is less than `0.00005` *(round to 4 decimals == 0)*, so why are you confused that result is only accurate to 4+ decimal places? – Andreas Jun 04 '18 at 04:16

2 Answers2

0

Work toward understanding mathematics in programming well, is worth the effort. Check this post out as it might provide some elucidation why you are getting some unexpected values - maybe a little more complicated than you were aware. Programming problems only take tenacity to solve them, just keep plugging away.

Double vs. BigDecimal?

cogitoboy
  • 114
  • 1
  • 4
0

Change

while (RoundNumber(difference) != 0) {

To:

while (difference != 0) {

Or compare against a small epsilon:

while (Math.abs(difference) > 0.0000001) {
jspcal
  • 50,847
  • 7
  • 72
  • 76
  • I wanted to use the `RoundNumber` function so that I can also deal with numbers whose roots aren't integers though. For example the root of 5 is 2.23606... but if I didn't have the `RoundNumber` function the console wouldn't return anything. – Harrison Jun 04 '18 at 03:51
  • Use an epsilon value. For instance: `while (Math.abs(difference) > 0.0000001) {` You can make it as small as you like. – jspcal Jun 04 '18 at 04:05
  • @jspcal That is the effect of `RoundNumber`. Changing from `RoundNumber` to epsilon won't make much of a difference *(except it's faster)*. – Andreas Jun 04 '18 at 04:14