Re: [Python-Dev] Return type of round, floor, and ceil in 2.6
[GvR to Tim]
Do you have an opinion as to whether we should adopt round-to-even at all (as a default)?
For the sake of other implementations (Jython, etc) and for ease of reproducing the results with other tools (Excel, etc), the simplest choice is int(x+0.5). That works everywhere, it is easy to explain, it runs fast, and it is not hard to get right. my two cents, Raymond
On 4 Jan, 10:45 pm, python@rcn.com wrote:
[GvR to Tim]
Do you have an opinion as to whether we should adopt round-to-even at all (as a default)?
For the sake of other implementations (Jython, etc) and for ease of reproducing the results with other tools (Excel, etc), the simplest choice is int(x+0.5). That works everywhere, it is easy to explain, it runs fast, and it is not hard to get right.
I agree for the default. Except the part where Excel, Jython, and Python's current round, actually use sign(x) * int(abs(x)+0.5), so maybe it's not *completely* easy to get right ;-). Having other rounding methods *available*, though, would be neat. The only application I've ever worked on where I cared about the difference, the user had to select it (since accounting requirements differ by jurisdiction and, apparently, by bank preference). Having a standard way to express this (especially if it worked across different numeric types, but perhaps I digress) would be pleasant. Implementing stochastic rounding and banker's rounding oneself, while not exactly hard, is a drag.
On Jan 4, 2008 10:16 PM, <glyph@divmod.com> wrote:
On 4 Jan, 10:45 pm, python@rcn.com wrote:
[GvR to Tim]
Do you have an opinion as to whether we should adopt round-to-even at all (as a default)?
For the sake of other implementations (Jython, etc) and for ease of reproducing the results with other tools (Excel, etc), the simplest choice is int(x+0.5). That works everywhere, it is easy to explain, it runs fast, and it is not hard to get right.
I agree for the default. Except the part where Excel, Jython, and Python's current round, actually use sign(x) * int(abs(x)+0.5), so maybe it's not *completely* easy to get right ;-).
Having other rounding methods *available*, though, would be neat. The only application I've ever worked on where I cared about the difference, the user had to select it (since accounting requirements differ by jurisdiction and, apparently, by bank preference). Having a standard way to express this (especially if it worked across different numeric types, but perhaps I digress) would be pleasant. Implementing stochastic rounding and banker's rounding oneself, while not exactly hard, is a drag.
The decimal module already supports rounding modes in its context. For other types, perhaps converting to decimal might be good enough? -- --Guido van Rossum (home page: http://www.python.org/~guido/)
On 04:54 pm, guido@python.org wrote:
On Jan 4, 2008 10:16 PM, <glyph@divmod.com> wrote:
Having other rounding methods *available*, though, would be neat. The only application I've ever worked on where I cared about the difference, the user had to select it (since accounting requirements differ by jurisdiction and, apparently, by bank preference). Having a standard way to express this (especially if it worked across different numeric types, but perhaps I digress) would be pleasant. Implementing stochastic rounding and banker's rounding oneself, while not exactly hard, is a drag.
The decimal module already supports rounding modes in its context. For other types, perhaps converting to decimal might be good enough?
Yes, that's the right thing to do. I had missed it. After all it is decimal rounding I want, and any financial applications I'm going to write these days are using decimals already for all the usual reasons. At first I didn't realize why I'd missed this feature. While the rounding *modes* are well documented, though, after 20 minutes of reading documentation I still haven't found a method or function that simply rounds a decimal to a given significant digit. Is there one, should there be one, or is the user simply meant to use Context.quantize with appropriate arguments?
On Jan 5, 2008 5:54 PM, <glyph@divmod.com> wrote:
At first I didn't realize why I'd missed this feature. While the rounding *modes* are well documented, though, after 20 minutes of reading documentation I still haven't found a method or function that simply rounds a decimal to a given significant digit. Is there one, should there be one, or is the user simply meant to use Context.quantize with appropriate arguments?
quantize is about as close as it gets. Note that it's a Decimal method as well as a Context method, so you can invoke it directly on a given decimal:
Decimal("2.34567").quantize(Decimal("0.01")) Decimal("2.35")
I've also occasionally felt a need for a simple rounding function that isn't affected by context. Would others be interested in such a function being added to Decimal? I guess there are two possibly useful operations: (1) round to a particular decimal place ( e.g. nearest ten, nearest hundredth, ..) and (2) to round to a particular number of significant digits; in both cases, the user should be able to specify the desired rounding mode. And for each operation, it might also be useful to specify whether the result should be padded with zeros to the desired length or not. (i.e. when rounding 3.399 to 3 significant places, should it produce 3.4 or 3.40?) Any thoughts? Mark
[Mark Dickinson]
quantize is about as close as it gets. Note that it's a Decimal method as well as a Context method, so you can invoke it directly on a given decimal:
Decimal("2.34567").quantize(Decimal("0.01")) Decimal("2.35")
This "reads better" in many cases if you define a constant first, like: PENNIES = Decimal("0.01") ... [lots of code] ... rounded = some_decimal.quantize(PENNIES)
I've also occasionally felt a need for a simple rounding function that isn't affected by context. Would others be interested in such a function being added to Decimal? I guess there are two possibly useful operations: (1) round to a particular decimal place ( e.g. nearest ten, nearest hundredth, ..) and (2) to round to a particular number of significant digits; in both cases, the user should be able to specify the desired rounding mode. And for each operation, it might also be useful to specify whether the result should be padded with zeros to the desired length or not. ( i.e. when rounding 3.399 to 3 significant places, should it produce 3.4 or 3.40?)
Any thoughts?
+1 from me. Like the 754 standard, the decimal std is trying to mandate a more-or-less minimal set of core functionality, with no concern for user interface. "Convenience functions" can be valuable additions in such cases, & I agree it's far from obvious to most how to accomplish rounding using the decimal facilities. I think it's obvious ;-) that rounding 3.399 to 3 sig. dig. should produce 3.40.
[Tim]
I agree it's far from obvious to most how to accomplish rounding using the decimal facilities.
FWIW, there is an entry for this in the Decimal FAQ: http://docs.python.org/lib/decimal-faq.html Raymond
On Sat, Jan 05, 2008, glyph@divmod.com wrote:
At first I didn't realize why I'd missed this feature. While the rounding *modes* are well documented, though, after 20 minutes of reading documentation I still haven't found a method or function that simply rounds a decimal to a given significant digit. Is there one, should there be one, or is the user simply meant to use Context.quantize with appropriate arguments?
Rephrasing Uncle Timmy: Decimal has so far focused on adhering to the decimal standard, not on providing convenience to users. As long as the core continues to adhere to the standard, there's no reason not to add convenience. -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ Weinberg's Second Law: If builders built buildings the way programmers wrote programs, then the first woodpecker that came along would destroy civilization.
participants (6)
-
Aahz -
glyph@divmod.com -
Guido van Rossum -
Mark Dickinson -
Raymond Hettinger -
Tim Peters