3
\$\begingroup\$

Which version is more efficient in calculating the square root ?

There are 2 versions I have written to calculate square root programatically. Note reqs strictly state not using library functions ?

This is puzzling, the first method takes one extra iteration over the 2nd one but returns the more accurate answer of 3.00.

Why does it take an extra iteration ?

  • So, which one is more efficient ?
  • Do you find any bugs in this code ?
  • When will it overflow ?
  • Do both approaches seem logical, one is trying to calculate the difference between square of approximation and actual number, whereas other trying to bisect the interval. Would you pick one over the other ?
public void squareRoot()
{
 double n = 9;
 double epsilon = 0.001;
 double guess = n*n;
 double low = 0;
 double high = n;
 int cnt=0;
 while(Math.abs(guess*guess-n)>epsilon)
 {
 guess = (low + high)/2;
 if(guess*guess>n)
 high = guess;
 else 
 low = guess;
 cnt+=1;
 System.out.println("Low:"+low+"high:"+high+"guess:"+guess+"cnt:"+cnt);
 }
 if(guess*guess-n<epsilon)
 {
 System.out.println("The square root is:"+guess);
 }
}
public void anotherSquareRoot()
{
 double n = 9;
 double epsilon = 0.001;
 double guess = n*n;
 double low = 0;
 double high = n;
 int cnt=0;
 while(high-low>epsilon)
 {
 guess = (low + high)/2;
 if(guess*guess>n)
 high = guess;
 else 
 low = guess;
 cnt+=1;
 System.out.println("Low:"+low+"high:"+high+"guess:"+guess+"cnt:"+cnt);
 }
 if(guess*guess-n<epsilon)
 {
 System.out.println("The square root is:"+guess);
 }
} 
200_success
146k22 gold badges190 silver badges479 bronze badges
asked Apr 21, 2013 at 3:37
\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

In version 1, you are testing the difference of the square is within 0.001.

The square root of 9.001 is 3.000167

In version 2, you are testing the difference of the square root part. When you square it, the error becomes bigger.

The square of 3.001 is 9.006001

One error:

You need to get rid of the

if(guess*guess-n<epsilon)

at the end of version 2, it will not print for positive differences> 0.001 e.g. for 3.001 9.006001 is 0.00601 bigger.

answered Apr 21, 2013 at 21:42
\$\endgroup\$
4
  • \$\begingroup\$ Which one is more correct ? \$\endgroup\$ Commented Apr 22, 2013 at 13:50
  • \$\begingroup\$ It depends on your requirements. The only one you have stated is no library functions and version 1 uses Math.abs (although it would be easy to implement yourself) so version 2 is more correct. If you want better accuracy, version 1 is better. \$\endgroup\$ Commented Apr 22, 2013 at 14:51
  • \$\begingroup\$ Y is square of the error a better solution ? \$\endgroup\$ Commented Apr 23, 2013 at 2:26
  • \$\begingroup\$ I'm not saying one is better, just different but if I had to choose, I would choose version 2 as it gives you the square root within the error you have specified and uses subtraction, which will be faster than squaring and taking the absolute. \$\endgroup\$ Commented Apr 23, 2013 at 6:05
1
\$\begingroup\$

There are some fairly bizarre things which are present in both.

  • Neither of them takes a parameter
  • Both of them start with double guess = n*n; and then proceed to square the guess again. This is never going to be useful.
  • They use unguided binary chop for a nonlinear function

I would use a Taylor expansion to three or four terms to get a starting point and then Newton-Raphson should home in very fast.

answered Apr 23, 2013 at 12:47
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.