floating point woes

Hans-Peter Jansen hpj at urpla.net
Tue Feb 15 20:18:40 EST 2011


On Wednesday 16 February 2011, 01:24:59 Chris Rebert wrote:
> On Tue, Feb 15, 2011 at 4:09 PM, Chris Rebert <clp2 at rebertia.com> 
wrote:
> > On Tue, Feb 15, 2011 at 3:49 PM, Hans-Peter Jansen <hpj at urpla.net> 
wrote:
> >> Hi,
> >>
> >> while I usually cope with the woes of floating point issues, this
> >> is
> >>
> >> one, that I didn't expect:
> >>>>> round(2.385, 2)
> >>
> >> 2.3799999999999999
> >>
> >> Doesn't the docs say, it's rounded up for this case?
> >>
> >> <quote>
> >> Values are rounded to the closest multiple of 10 to the power
> >> minus n; if two multiples are equally close, rounding is done away
> >> from 0 </quote>
> >>
> >> Well, that one is clearly rounding down.
> >>
> >> What's up, eh, down here?
> >
> > http://docs.python.org/library/functions.html#round :
> > """
> > Note: The behavior of round() for floats can be surprising: for
> > example, round(2.675, 2) gives 2.67 instead of the expected 2.68.
> > This is not a bug: it’s a result of the fact that most decimal
> > fractions can’t be represented exactly as a float. See "Floating
> > Point Arithmetic: Issues and Limitations"[1] for more information.
> > """
> > [1]: http://docs.python.org/tutorial/floatingpoint.html
> >
> > And indeed:
> >>>> from decimal import Decimal
> >>>> Decimal(2.385)
> >
> > Decimal('2.3849999999999997868371792719699442386627197265625')
> >
> > Which, rounded to 2 decimal places, gives us 2.38, which is in turn
> > approximated as:

If that only wouldn't be so arkward to use:

>>> from cdecimal import Decimal, ROUND_HALF_UP
>>> d = Decimal("2.385")
>>> d
Decimal('2.385')
>>> d.quantize(Decimal('1.00'))
Decimal('2.38')

hrmpf.

>>> d.quantize(Decimal('1.00'), ROUND_HALF_UP)
Decimal('2.39')

Oh, well. This is a bit too Cobolesque. (Yes, sure, I know, I can define 
any context, I like.)

> [*whacks forehead hard*]
> Nevermind.

Too true.

> - Chris

Pete



More information about the Python-list mailing list