who can tell me how to unsubscribe the message.
At 2011-06-13 01:13:05,"Steven DAprano" <st...@pearwood.info> wrote: >Ryan Strunk wrote: >> Hi everyone, >> I'm designing a timeline. When the user presses the right arrow, 0.1 is >> added to the current position. The user can add events to the timeline, and >> can later scroll back across those events to see what they are. But >> something I absolutely don't understand is happening: >> I used the program to place events at 1.1, 2.1, and 3.1. Here is the end of >> the debug output for arrowing to 3.1 and placing the event: >> position = 2.7 >> position = 2.8 >> position = 2.9 >> position = 3.0 >> position = 3.1 >> event placed. >> Everything appears straight forward. > > >It only *appears* straight forward, it actually isn't. That's because >the printed output is rounded so as to look nice. Compare: > > >>> x = 1/10.0 > >>> print(x) # displayed as nicely as possible >0.1 > >>> print('%.25f' % x) # display 25 decimal places >0.1000000000000000055511151 > > >For speed and simplicity, floats are stored by the computer using >fractional powers of two. That's fine for numbers which are powers of >two (1/2, 1/4, 1/256, and sums of such) but numbers that humans like to >use tend to be powers of 10, not 2. > >Unfortunately, many common fractions cannot be written exactly in >binary. You're probably familiar with the fact that fractions like 1/3 >cannot be written exactly in decimal: > >1/3 = 0.33333333... goes on forever > >The same is true for some numbers in binary: > >1/10 in decimal = 1/16 + 1/32 + 1/256 + ... > >also goes on forever. Written in fractional bits: > >1/10 decimal = 0.00011001100110011... in binary > >Since floats can only store a finite number of bits, 1/10 cannot be >stored exactly. It turns out that the number stored is a tiny bit larger >than 1/10: > > >>> Fraction.from_float(0.1) - Fraction(1)/10 >Fraction(1, 180143985094819840) > >Rounding doesn't help: 0.1 is already rounded as close to 1/10 as it can >possibly get. > >Now, when you print the dictionary containing those floats, Python >displays (almost) the full precision: > > >>> print {1: 0.1} >{1: 0.10000000000000001} > > >In newer versions of Python, it may do a nicer job of printing the float >so that the true value is hidden. E.g. in Python 3.1 I see: > > > >>> print({1: 0.1}) >{1: 0.1} > >but don't be fooled: Python's print display is pulling the wool over >your eyes, the actual value is closer to 0.10000000000000001. > > >One consequence of that is that adding 0.1 ten times does not give 1 >exactly, but slightly less than 1: > > >>> x = 0.1 > >>> 1 - sum([x]*10) >1.1102230246251565e-16 > > >(P.S. this is why you should never use floats for currency. All those >missing and excess fractions of a cent add up to real money.) > > >To avoid this, you can: > > >* Upgrade to a newer version of Python that lies to you more often, so >that you can go on living in blissful ignorance (until such time as you >run into a more serious problem with floats); > >* Use the fraction module, or the decimal module, but they are slower >than floats; or > >* Instead of counting your timeline in increments of 0.1, scale >everything by 10 so the increment is 1. > >That is, instead of: > >2.0 2.1 2.2 2.3 ... > >you will have > >20 21 22 23 24 ... > > >* Or you just get used to the fact that some numbers are not exact in >floating point. > > > > >-- >Steven > >_______________________________________________ >Tutor maillist - Tutor@python.org >To unsubscribe or change subscription options: >http://mail.python.org/mailman/listinfo/tutor
_______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor