[Paul McGuire]
...
> >>> print "%.2f" % 1.775
> 1.77
>
> Hmmm, if we rounded, I would have expected 1.775 to round up
> to 1.78.

Platform-dependent.  1.775 isn't exactly representable regardless, but
whether exactly-half-way numbers that are exactly representable round
up or truncate varies across platform C libraries.  For example, 1.25
is exactly representable in binary fp, but '%.1f' % 1.25 produces 1.3
on Windows but 1.2 on most other platforms (most non-Microsoft C
runtimes use the IEEE "round to nearest or even" rule).

> Perhaps this is a floating point rep issue, that we are really
> rounding 1.7749999999999999999 or something.  Sure enough,
> repr shows us:
> 
> >>> repr(1.775)
> '1.7749999999999999'
> 
> So I added a wee bit to 1.775:
> 
> >>> print "%.2f" % 1.775000000001
> 1.78
> 
> Ok, that looks better.  What if I round explicitly?
> 
> >>> print "%.2f" % round(1.775,2)
> 1.78
> 
> Errr?  How come round() is able to understand 1.775 correctly,
> whereas string interp is not?  I'm guessing that round() adds
> some small epsilon to the value to be rounded,

No way -- that would be insane.

> or perhaps even does the brute force rounding I learned in
> FORTRAN back in the 70's:  add 0.5 and truncate.

Yes, that's what Python's round() does.

>  But this would still truncate 1.779999999 to two places, so this
> theory fails also.

No:

>>> 1.775
1.7749999999999999
>>> 1.775 * 100.0
177.5
>>> 1.775*100 + 0.5
178.0
>>>

That is, before adding 0.5, it multiplies by 100.0.  The vagaries of
binary fp are such that machine_value_for(1.755) * 100 is exactly
175.5, and adding 0.5 to that gives 178 exactly.

> What magic is round() doing, and should this same be done in the
> string interp code?

Python implements round() itself.  Float string formatting is done by
the platform C sprintf().  If you care about decimal representations
so much that you can't tolerate vagaries due to differences in the
53rd significant bit, use the new decimal module instead.
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to