[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Python comparing float



On Wed, Aug 22, 2012 at 9:07 PM, Ricardo Franco <ricardo.krieg@xxxxxxxxx> wrote:
> Hi, this is more a question about python than pygame. Considering this code:
>
> #####################################################
> rate = 1
> desired_rate = 2
>
> while True:
>     if rate != desired_rate:
>         print rate, desired_rate, (rate != desired_rate)
>         rate += 0.1 * (1 if desired_rate > rate else -1)
>     # if
> # while
> #####################################################
>
> It should smoothly move rate from 1 until 2.
> But the output is this:
>
> 1 2 True
> 1.1 2 True
> 1.2 2 True
> 1.3 2 True
> 1.4 2 True
> 1.5 2 True
> 1.6 2 True
> 1.7 2 True
> 1.8 2 True
> 1.9 2 True
> 2.0 2 True
> 1.9 2 True
> 2.0 2 True
> 1.9 2 True
> 2.0 2 True
> 1.9 2 True
> 2.0 2 True
> 1.9 2 True
> 2.0 2 True
> ...
>
> Is python missing in comparison?

One thing you need to understand about floating point numbers is that
they are not exact -- they are the nearest values that can be
represented in binary in the limited number of bytes (double
precision, in case of python, AFAIR).

Another thing to remember is that the decimal value 0.1 is a periodic
fraction in binary -- it doesn't have a finite exact representation,
just like 1/3 doesn't have one in decimal. That means that whenever
you write 0.1, the computer really stores a value that is a little bit
larger than that. You can try it in the python console:


>>> '%f' % 0.1
'0.100000'
>>> '%.40f' % 0.1
'0.1000000000000000055511151231257827021182'
>>>

Now, consider this:

>>> '%.40f' % (1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1)
'2.0000000000000008881784197001252323389053'

You can clearly see, that this is not equal 2.0.

That's why when you are comparing floating point numbers, you always
have to check if they are within some small error value from each
other. How large that value is depends on your particular use case.

If you really need to have *exact* results, at the expense of slower
computation, use the Decimal type.

I hope that helps,

-- 
Radomir Dopieralski