Decimals not equalling themselves (e.g. 0.2 = 0.2000000001)

Ken Starks straton at lampsacos.demon.co.uk
Mon Aug 4 06:30:35 EDT 2008


CNiall wrote:
> I am very new to Python (I started learning it just yesterday), but I 
> have encountered a problem.
> 
> I want to make a simple script that calculates the n-th root of a given 
> number (e.g. 4th root of 625--obviously five, but it's just an example 
> :P), and because there is no nth-root function in Python I will do this 
> with something like x**(1/n).
> 
> However, with some, but not all, decimals, they do not seem to 'equal 
> themselves'. This is probably a bad way of expressing what I mean, so 
> I'll give an example:
>  >>> 0.5
> 0.5
>  >>> 0.25
> 0.25
>  >>> 0.125
> 0.125
>  >>> 0.2
> 0.20000000000000001
>  >>> 0.33
> 0.33000000000000002
> 
> As you can see, the last two decimals are very slightly inaccurate. 
> However, it appears that when n in 1/n is a power of two, the decimal 
> does not get 'thrown off'. How might I make Python recognise 0.2 as 0.2 
> and not 0.20000000000000001?
> 
> This discrepancy is very minor, but it makes the whole n-th root 
> calculator inaccurate. :\

As everyone else has pointed out, this is likely to be a
'floating point' error. what they don't mention is that you
don't actually have to use floating point at all.

For example, some numbers, m,  can be represented as the product of
rational powers of primes. Its not that easy to add and subtract
them, but multiplication, division, raising to the nth power and
taking the nth root, are all easy. (m and n  positive integers).

There certainly are algorithms that will evaluate the 'fourth
root of 625' as precisely 5.

More generally, there are algorithms that will guarantee to return
either
+ the exact answer as a float (if it is one)
+ the nearest or second nearest float to the actual answer
   depending on your choice of:
     - round towards zero
     - round away from zero
     - round towards positive infinity
     - round towards negative infinity
     - round depending on parity of next digit

It is the representation of the numbers during the intermediate
stages that is critical. You trade-off speed against accuracy.

You may well find, if you do this, that the results returned
by built-in mathematical functions DO NOT return either the
nearest or the second nearest float to the actual answer. It
depends on the underlying C library that was used, and its
programmers' choices.

So your home-rolled 'nth power' function would add a little
something to the standard functionality of the language,
and writing it would add to your understanding of the
language too.







More information about the Python-list mailing list