pashayi
pashayi

Reputation: 71

Why is the square root calculation slower for larger numbers?

This is a Java code to ask for a number then printing its square root without using Math.sqrt() method:

import java.util.Random;
import java.io.*;
public class Square {
    public static void main(String[] args) throws IOException {
        final double TOL = 0.5E-15;
        InputStreamReader reader = new InputStreamReader(System.in);
        BufferedReader input = new BufferedReader(reader);
        System.out.print("Enter a number to get the aquare of it: ");
        double n = new Double(input.readLine()).doubleValue();
        Random random = new Random();
        double x = random.nextDouble();
        do {
            x = (x+n/x)/2;
        } while(Math.abs(x*x-n)>TOL*2*x);
        System.out.println("sqrt(" + n + ") = " + x);
    }
 }

Please run this in you computer and test it for several numbers. for numbers below 30.1, it runs and calculates the square root quickly. But when you enter 30.2 or larger numbers, no square root is calculated(at least with feasible waitings)! Any interesting explanation for this behavior?!

Upvotes: 1

Views: 365

Answers (5)

sve
sve

Reputation: 4356

What you have there is the so-called Babylonian method for computing the square root of a number. However, I think that your stop condition should be only a scalar (for example TOL) and not TOL*2*x.

Upvotes: 0

Bohemian
Bohemian

Reputation: 425063

The "problem" is that double has a limited precision: The larger the number represented, the larger the inaccuracy - that is the larger the smallest change must be to store a different double.

Once your attempted answer exceeds a certain numerical size, double can not resolve the number finely enough to achieve the accuracy defined by TOL.

Upvotes: 0

cl-r
cl-r

Reputation: 1264

Why random? a coded double judiciously choosed avoid calcul like x*x


In your code you can add *2 to the TOL definition and remove *2 from loop

Good programming remove all unnecessary things

Upvotes: 0

Joris W
Joris W

Reputation: 517

change the do-while to:

do {
    x = (x+n/x)/2;
    System.out.println(x);
    System.out.println(x*x);
} while(Math.abs(x*x-n)>TOL*2*x);

this gives repeatly (for input 30.2):

5.495452665613634
30.199999999999992

as you can see is the square of 5.495452665613634 30.199999999999992, this has as result that the condition Math.abs(x*x-n)>TOL*2*x is always fullfilled (the difference is 7.105427357601002E-15. while the condition is > 5.4954526656136345E-15, which is true)

in otherwords, you forgot that a computerprogram has some limitations for storing values, or your TOL isn't high enough

Upvotes: 4

Kryptos
Kryptos

Reputation: 542

Well the entire code is built on the premise that at some point you will get the correct value for x. What you get from the Random object will affect the time as will the size of the number you choose.

It's not really an efficient way of calculating sqrt.

Upvotes: 2

Related Questions