September 24th, 2013, 12:01 PM

My floats keep becoming imprecise!
"n = 25
root = 0.0
while root**2 < n:
root+=0.1"
Root always ends up equaling 5.099999999999998 for some reason...
I've changed n to n+0.1 and it is still the same. I need it to equal 5, but still be a float.
September 24th, 2013, 12:42 PM

Use Python's Decimal module for times when floats don't give you enough precision. For the limits of floating point numbers on a computer, see http://www.lahey.com/float.htm
or http://docs.python.org/tutorial/floatingpoint.html
Code:
from decimal import Decimal as dec
n = dec('25.0')
root = dec('0.0')
while root**2 < n:
root+=dec('0.1')
print root ## prints 5.0
FYI
Code:
n = 25.0
root = 0.0
while root**2 < n:
root+=0.1
print repr(root), repr(root**2)
""" Final 7 calcs
4.5 20.25
4.6 21.159999999999997
4.699999999999999 22.089999999999993
4.799999999999999 23.03999999999999
4.899999999999999 24.009999999999987
4.999999999999998 24.999999999999982
5.099999999999998 26.009999999999977
"""
Comments on this post
Last edited by dwblas; September 24th, 2013 at 01:02 PM.
September 24th, 2013, 02:42 PM

Your main trouble is that your answer is off by a tenth. Do read dwblas's suggested articles so you'll understand more about arithmetic with finite precision base 2 or whatever.
This improved algorithm computes the root as 4.999999999999998.
Code:
step = 0.1
n = 25
r = 0.0
while r ** 2 < n:
r += step
q = r  step
root = q if (n  q*q) < (r*r  n) else r
print(root)
[edit]And thank you for demonstrating that the decimal module works in base 10. I was thinking of it, and have used it as an implementation of arbitrary precision.[/edit]
Last edited by b49P23TIvg; September 24th, 2013 at 02:47 PM.
[code]
Code tags[/code] are essential for python code and Makefiles!
September 24th, 2013, 03:24 PM

Code:
NB. Newton's method to find square root of 25 starting from 1 written in J.
NB. converges to 5 www.jsoftware.com
(+(25*:)%+:)^:a:1
1 13 7.46154 5.40603 5.01525 5.00002 5 5
(+(25*:)%+:)^:a:0 NB. starting from 0 gives intermediate _%_ (infinity divided by infinity), which is Not A Number.
NaN error
 (+(25*:)%+:)^:a:0
NB. which, written as an adverb accepts somewhat arbitrary functions.
NewtonMethod =: adverb def '(] + ( u) % u D.1@:])^:a:'
25 *: NewtonMethod 1
1 13 7.46154 5.40603 5.01525 5.00002 5 5
25 (3 _2 1&p.) NewtonMethod 12
12 7.54545 6.02967 5.80127 5.79583 5.79583 5.79583
3 _2 1 p. 5.79583
25
Last edited by b49P23TIvg; September 24th, 2013 at 03:36 PM.
Reason: foolin' around.
[code]
Code tags[/code] are essential for python code and Makefiles!