[Python-Dev] Rounding float to int directly (Re: struct module and coercing floats to integers)

Ron Adam rrr at ronadam.com
Fri Aug 4 00:00:04 CEST 2006


Nick Coghlan wrote:
> Ron Adam wrote:
>> Consider an example where you are combining data that had different 
>> number of significant digits.  Keeping all the digits of your answer 
>> gives a false since of accuracy.  The extra digits are meaningless 
>> because the margin of error is greater than any of the digits that 
>> exceed the minimum number of significant digits in your data.  So you 
>> need to remove the extraneous digits by rounding.  Then this answer 
>> can be further used as data, and sense the number of significant 
>> digits is maintained, the margin of error can be calculated accurately.
> 
> This is a fallacy though - add two numbers together each with an error 
> of +/- 0.05, and the error in the total is +/- 0.1. The approach you 
> propose gives the misleading impression that the error in the total is 
> still only +/- 0.05 (as the answer will contain 1 decimal place).

I did say "the margin of error can be calculated accurately".  I did not 
go into detail on the correct method to do that.  You do need to round 
to the correct number of significant digits AND yes, you do need to also 
take into account the number of items in your data set.

If you don't round, the value of your answer would be shifted up or down 
by the amount of the non significant digits.  And the error range would 
also be shifted up or down by that amount.

In any case, my point is (and my opinion) that rounding to floating 
point types is very common and not something that is needed rarely as it 
has been expressed in several messages.  I don't want to debate the 
correct method of calculating errors and maintaining accuracy in 
statistical equations. I'll let the mathematicians do that.


> If you really care about error, you need to do it properly (e.g. stddev 
> or adding the error margins).

Yes


> Anyway, it's not proposed to remove the "round to x decimal places" 
> capability entirely - merely remove it from the builtin round() so that 
> the return type can be changed.

That would work.



This is one of those places where I wonder when should a function be 
included in a types methods and called by either using arguments with 
__init__, an external function to call a private method, or by having it 
be a public method to be called with the dot syntax like is common for 
strings?

If you look at the Decimal type, it has quite of few rounding methods, 
(as well as other non-underscored methods), while int, float, and long, 
do not have them.  Also the Decimal _round() method returns the number 
unchanged (max precision) if no precision argument is given where 
round() has a default precision of 0.

Will there be more efforts (in Py3k to unifiy Decimal and the other 
types so they are more alike in both the way they work and in how they 
are used?



Would it make since for the numeric type to have methods (other than the 
underscored ones) that can be called with the dot syntax like we do in 
unicode and the Decimal types that do not have the underscores?  Or 
would it be better to remove those in favor of builtin or module 
functions?  The extremes of both might be a foolish consistency, but 
this may also be a good area to make some basic improvements for python 
3k.  (I'm sure Guido and others here have though some on this in general.)

If these types gain a round method that all work the same way, then 
round() can then use those and it would return the same type as it is 
given. So then round(float(x)), round(int(x)), round(long(x)) and 
round(Decimal(x)) will return their own type respectfully.

And to get a specific type, you would call the types method directly.

    int.round(x)  -> integer

Which is nicer than int(round(x)).


And the round methods could have arguments to designate the type of 
rounding to use. Where 'f','c', and 'e' are floor, ceiling, and even 
rounding.

    int.round(x, 'c')     # 'f' is the default rounding mode

The functions round(), roundcieling(), and roundeven() could then call 
the method of the type with the appropriate argument, although I'd be 
happy without these round functions if there are round methods are 
consistent across types.


Well, this is the direction I would go in.  Hopefully by Python 9000 the 
decimal type or something equivalent will be as fast as all the others 
and/or computers will be so fast as to make it irrelevant,  then we can 
have just one scaler base type. ;-)

Cheers,
    Ron















More information about the Python-Dev mailing list