0

I'm starting out with learning Python 3.7, and wrote this very simple practice program for finding the square root of a number.

# User enters a number
x = int(input("Enter a number, any number: "))

# Start with a random guess (g) of 4
g = 4

# Check if g*g = x
# If not, redefine g as avg of g and x, square, then recheck

while g*g != x:
    g = (g + x/g)/2

# When g*g = x, print g

else:
    print(g)

For some numbers, the program works just fine. For others, however, the program simply doesn't resolve.

So, for example, if I run this program (in Spyder) and enter 56, it returns a value of 7.483314773547883. If I enter 66, the console doesn't return an output. It simply idles until I interrupt or reset it.

I also tried changing the while condition to:

while g*g not in range(int(x - 0.1), int(x + 0.1)):

But this threw up the same problem. I'd appreciate any advice on what the issue might be here.

  • How did you come up with this algorithm? Is it meant to converge to the square root? – Raiyan Chowdhury Jul 22 '20 at 23:03
  • 3
    Floating point numbers have arithmetical error, and in any event your algorithm is only for approximations anyway. For most inputs `g*g != x` will *always* be true, hence you have an infinite loop. Instead, you need to have some notion of error tolerance in your loop. Something like `abs(g*g - x) > 0.0000000001` – John Coleman Jul 22 '20 at 23:03
  • 1
    The algorithm is modelled on an ancient method for converging to square roots. After posting, I figured out my error: by inserting `print(g)` at the end of the `while` function, I saw it was continuously printing a value which, when squared, added to 66.000000001. So it was stuck indeed an infinite loop. Using @John Coleman's `abs` method worked to fix this, so many thanks for your guidance on this. – Before_Adam Jul 23 '20 at 20:19

1 Answers1

0

As mentioned in the comments, the program is not completing due to floating point numbers having arithmetical error.

However, you could adjust your program using something similar to what you suggested with:

while g*g not in range(int(x - 0.1), int(x + 0.1)):

The issue with that statement is that range only counts up by integers so it's not going to work as expected.

You could try:

while g*g < x-.1 or g*g > x+.1:

Spencer Bard
  • 1,015
  • 6
  • 10