1

I am doing this in python with while loop. It's not terminating.

x = 2.0
ans = 0
while ans**2 != abs(x):    
    print (ans)  
    ans = ans + 0.001
    if ans**2 == abs(x):  
        print(ans)
ForceBru
  • 43,482
  • 10
  • 63
  • 98
Akshat Patni
  • 161
  • 1
  • 4
  • 10
  • That's because `ans` is never equal to sqrt(2). In fact, _no_ floating point number is equal to sqrt(2), not even the number returned by `math.sqrt(2)`. – Kevin May 22 '15 at 11:58
  • 9
    You *should not* compare *float* values with `==` or `!=` operators, use *tolerance* instead: `abs(ans** 2 - abs(x)) >= 0.0001` – Dmitry Bychenko May 22 '15 at 11:58
  • @Kevin: sqrt(2) in its mathematical sense isn't relevant here. he's comparing floating point numbers. – Karoly Horvath May 22 '15 at 12:10
  • @Kevin He's not comparing to sqrt(2), though. You'd probably say the same about sqrt(11), but in fact `(11 ** 0.5) ** 2 == 11` happens to be True. – Stefan Pochmann May 22 '15 at 12:31

2 Answers2

3

Even this doesn't work like you'd want it to:

>>> (2 ** 0.5) ** 2 == 2
False

For some numbers it does, though, even for non-squares:

>>> (11 ** 0.5) ** 2 == 11
True

It can even go wrong with simpler calculations:

>>> 0.1 + 0.2 == 0.3
False

The problem is that in general, the computer doesn't represent floating point numbers exactly. You only get a number close to the correct number. So you shouldn't do an exactness-test but a closeness-test (check whether the difference is less than some small number small enough to satisfy your needs).

>>> abs((2 ** 0.5) ** 2 - 2) < 1e-10
True
Stefan Pochmann
  • 27,593
  • 8
  • 44
  • 107
1

You shouldn't use != or == operators to compare floating point variables, as it's improbably you'll ever hit the exact square root with such a naive algorithm. Instead, you should define the acceptable error you're willing to tolerate and continue until you've hit a number with a smaller error than that. However, then may not be sufficient. Since you have a constant increment, you may very well find that you'll never get close enough to the square root you're searching for, and therefore, need an additional safeguard to not pass the required result and continue to infinity:

x = 2.0
ans = 0
step = 0.001
delta = 0.0001
while ans**2 < x and abs (ans**2 - x) > delta:
    ans = ans + step

# Done looping, found the best ans for ans**2<x.
# Check one additional value where ans**2>x 
# and choose the one with the smaller delta

overAns = ans + step
if abs (overAns ** 2 - x) < abs (ans ** 2 - x):
    print overAns
else:
    print ans 
Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • Could you illustrate how terrible this algorithm is and perhaps show a nice implementation one more that s far more efficient :) – James Mills May 22 '15 at 12:35
  • I glad to see a very quick answer from u,It was my first on stack.can u pls explain the while command in points and i am very very new to programming pls help me i want to master it. – Akshat Patni May 22 '15 at 12:45
  • Small nitpicking with your introduction: He's only testing whether his number squared equals 2. For that, his number doesn't have to be the square root of 2. – Stefan Pochmann May 22 '15 at 12:48