#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2013
    Posts
    1
    Rep Power
    0

    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.
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    May 2009
    Posts
    524
    Rep Power
    34
    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

    • b49P23TIvg agrees : Gratitude on following post.
    Last edited by dwblas; September 24th, 2013 at 02:02 PM.
  4. #3
  5. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,963
    Rep Power
    481
    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 03:47 PM.
    [code]Code tags[/code] are essential for python code and Makefiles!
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,963
    Rep Power
    481
    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 04:36 PM. Reason: foolin' around.
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo