Python -- floating point arithmetic

2010-07-07 Thread david mainzer

Dear Python-User,


today i create some slides about floating point arithmetic. I used an
example from

http://docs.python.org/tutorial/floatingpoint.html

so i start the python shell on my linux machine:

d...@maxwell $ python
Python 2.6.5 (release26-maint, May 25 2010, 12:37:06)
[GCC 4.3.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> >>> sum = 0.0
>>> >>> for i in range(10):
... sum += 0.1
...
>>> >>> sum
0.99989
>>> >>>
But thats looks a little bit wrong for me ... i must be a number greater
then 1.0 because 0.1 = 
0.155511151231257827021181583404541015625000
in python ... if i print it.

So i create an example program:

sum = 0.0
n = 10
d = 1.0 / n
print "%.60f" % ( d )
for i in range(n):
print "%.60f" % ( sum )
sum += d

print sum
print "%.60f" % ( sum )


 RESULTs --
0.1555111512312578270211815834045410156250
0.
0.1555111512312578270211815834045410156250
0.20001110223024625156540423631668090820312500
0.3000444089209850062616169452667236328125
0.40002220446049250313080847263336181640625000
0.5000
0.59997779553950749686919152736663818359375000
0.6999555910790149937383830547332763671875
0.79993338661852249060757458209991455078125000
0.8999111821580299874767661094665527343750
1.0
0.99988897769753748434595763683319091796875000

and the jump from 0.50*** to 0.5999* looks wrong
for me ... do i a mistake or is there something wrong in the
representation of the floating points in python?

my next question, why could i run

print "%.66f" % ( sum )

but not

print "%.67f" % ( sum )

can anybody tell me how python internal represent a float number??


Best and many thanks in advanced,
David

-- 
http://mail.python.org/mailman/listinfo/python-list


Python -- floating point arithmetic

2010-07-07 Thread david mainzer
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA384

Dear Python-User,


today i create some slides about floating point arithmetic. I used an
example from

http://docs.python.org/tutorial/floatingpoint.html

so i start the python shell on my linux machine:

d...@maxwell $ python
Python 2.6.5 (release26-maint, May 25 2010, 12:37:06)
[GCC 4.3.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> sum = 0.0
>>> for i in range(10):
... sum += 0.1
...
>>> sum
0.99989
>>>

But thats looks a little bit wrong for me ... i must be a number greater
then 1.0 because 0.1 = 
0.155511151231257827021181583404541015625000
in python ... if i print it.

So i create an example program:

sum = 0.0
n = 10
d = 1.0 / n
print "%.60f" % ( d )
for i in range(n):
print "%.60f" % ( sum )
sum += d

print sum
print "%.60f" % ( sum )


-  RESULTs --
0.1555111512312578270211815834045410156250
0.
0.1555111512312578270211815834045410156250
0.20001110223024625156540423631668090820312500
0.3000444089209850062616169452667236328125
0.40002220446049250313080847263336181640625000
0.5000
0.59997779553950749686919152736663818359375000
0.6999555910790149937383830547332763671875
0.79993338661852249060757458209991455078125000
0.8999111821580299874767661094665527343750
1.0
0.99988897769753748434595763683319091796875000

and the jump from 0.50*** to 0.5999* looks wrong
for me ... do i a mistake or is there something wrong in the
representation of the floating points in python?

my next question, why could i run

print "%.66f" % ( sum )

but not

print "%.67f" % ( sum )

can anybody tell me how python internal represent a float number??


Best and many thanks in advanced,
David
-BEGIN PGP SIGNATURE-
Version: GnuPG v2.0.15 (GNU/Linux)

iQIcBAEBCQAGBQJMNGpsAAoJEJ82b5xvAlAYYMYP/RTaRcB2NCawBQ25V463+pkO
/YtTqsamrFqENrljqpsPrwOOqR02TQrOvZrV72snDPkkcN36tZHKwbmcnOS0tOAc
kjX0/oNQOvvEMyJUuHJt9kdNjxMEvUUlENEZHLtpxbypIAo3Waf0FBxKo9F4fJJS
PaDIuDgXiLOiaTTUCwa5kKowzjUe8BJOczpUulvGiIvbUac4cxwkPiGvv6L4wzmI
/4x1mG5FSibEzcI2zFRsQNHfTqxuKC3a49DuSPtXZo4YWdqVeSXLntQk70uTa78K
q4cBVEIDqETQyG0mcRABJpcTMPsnGgbgJD74uhDSTARuyHh405XbjKlic7pe1M12
AhuN71QjpGFl80OOXxCja4OKJCAhPEkfhNsJjrlFnSXAoFWg5YvhDbSVkjW6ftt0
tzyGZEoBpRSjGSIeAojYaqt1Xdxwldz2qFjRLX03io3Fgr8PKRbcLRgg1FXaMFPc
gYaY0UEh4dEjt/5afp3ET0LkOhZVMbbi2oSkkFQpRMAzik63zSJRwRxiQXWunlSi
HhKqL4sAICf6MODzquuNzJO9wH8Fkpwi+JPEAwnQm/S6Ty00dN22GezG4TWGfepH
AhKOIEtRIcMgI7kyBfUdOQe6sifKGGuTEeXK12Td9znZN+wKfqG+Ch1mq4Rwy6P7
p2xwF7ZUWNgRU+5Y/bLG
=aS+I
-END PGP SIGNATURE-
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python -- floating point arithmetic

2010-07-08 Thread David Mainzer
On 07/07/2010 08:08 PM, Raymond Hettinger wrote:
> On Jul 7, 5:55 am, Mark Dickinson  wrote:
>> On Jul 7, 1:05 pm, david mainzer  wrote:
>>
>>
>>
>>> Dear Python-User,
>>
>>> today i create some slides about floating point arithmetic. I used an
>>> example from
>>
>>> http://docs.python.org/tutorial/floatingpoint.html
>>
>>> so i start the python shell on my linux machine:
>>
>>> d...@maxwell $ python
>>> Python 2.6.5 (release26-maint, May 25 2010, 12:37:06)
>>> [GCC 4.3.4] on linux2
>>> Type "help", "copyright", "credits" or "license" for more information.>>> 
>>> >>> sum = 0.0
>>>>>>>>> for i in range(10):
>>
>>> ... sum += 0.1
>>> ...>>> >>> sum
>>> 0.99989
>>
>>> But thats looks a little bit wrong for me ... i must be a number greater
>>> then 1.0 because 0.1 = 
>>> 0.155511151231257827021181583404541015625000
>>> in python ... if i print it.
> 
> [Mark Dickinson]
>> So you've identified one source of error here, namely that 0.1 isn't
>> exactly representable (and you're correct that the value stored
>> internally is actually a little greater than 0.1).  But you're
>> forgetting about the other source of error in your example: when you
>> do 'sum += 0.1', the result typically isn't exactly representable, so
>> there's another rounding step going on.  That rounding step might
>> produce a number that's smaller than the actual exact sum, and if
>> enough of your 'sum += 0.1' results are rounded down instead of up,
>> that would easily explain why the total is still less than 1.0.
> 
> One key for understanding floating point mysteries is to look at the
> actual binary sums rather that their approximate representation as a
> decimal string.  The hex() method can make it easier to visualize
> Mark's explanation:
> 
>>>> s = 0.0
>>>> for i in range(10):
> ... s += 0.1
> ... print s.hex(), repr(s)
> 
> 
> 0x1.ap-4 0.10001
> 0x1.ap-3 0.20001
> 0x1.4p-2 0.30004
> 0x1.ap-2 0.40002
> 0x1.0p-1 0.5
> 0x1.3p-1 0.59998
> 0x1.6p-1 0.69996
> 0x1.9p-1 0.79993
> 0x1.cp-1 0.89991
> 0x1.fp-1 0.99989
> 
> Having used hex() to understand representation error (how the binary
> partial sums are displayed), you can use the Fractions module to gain
> a better understanding of rounding error introduced by each addition:
> 
>>>> s = 0.0
>>>> for i in range(10):
>   exact = Fraction.from_float(s) + Fraction.from_float(0.1)
>   s += 0.1
>   actual = Fraction.from_float(s)
>   error = actual - exact
>   print '%-35s%-35s\t%s' % (actual, exact, error)
> 
> 
> 3602879701896397/36028797018963968 3602879701896397/36028797018963968
> 0
> 3602879701896397/18014398509481984 3602879701896397/18014398509481984
> 0
> 1351079888211149/4503599627370496  10808639105689191/36028797018963968
> 1/36028797018963968
> 3602879701896397/9007199254740992
> 14411518807585589/36028797018963968   -1/36028797018963968
> 1/2
> 18014398509481985/36028797018963968   -1/36028797018963968
> 5404319552844595/9007199254740992
> 21617278211378381/36028797018963968   -1/36028797018963968
> 3152519739159347/4503599627370496
> 25220157913274777/36028797018963968   -1/36028797018963968
> 7205759403792793/9007199254740992
> 28823037615171173/36028797018963968   -1/36028797018963968
> 2026619832316723/2251799813685248
> 32425917317067569/36028797018963968   -1/36028797018963968
> 9007199254740991/9007199254740992
> 36028797018963965/36028797018963968   -1/36028797018963968
> 
> Hope this helps your slides,
> 
> 
> Raymond


Thanks to all for your help :)

All your comments helped me and now i know how it works in python !

Best
David
-- 
http://mail.python.org/mailman/listinfo/python-list