[Python-Dev] Mixing float and Decimal -- thread reboot (original) (raw)
Guido van Rossum guido at python.org
Sun Mar 21 17:53:14 CET 2010
- Previous message: [Python-Dev] Mixing float and Decimal -- thread reboot
- Next message: [Python-Dev] Mixing float and Decimal -- thread reboot
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Sat, Mar 20, 2010 at 6:54 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:
Guido van Rossum wrote:
I think we should seriously reconsider allowing mixed arithmetic involving Decimal, not just mixed comparisons. I'm glad I'm not the only one that started wondering that. I wasn't quite game enough to actually suggest it though :)
There is one choice which I'm not sure about. Should a mixed float/Decimal operation return a float or a Decimal? I note that Fraction (which is properly embedded in the numeric tower) supports this and returns a float result in this case. While I earlier proposed to return the most "complicated" type of the two, i.e. Decimal, I now think it may also make sense to return a float, being the most "fuzzy" type in the numeric tower. This would also make checking for accidental floats easier, since floats now propagate throughout the computation (like NaN) and a simple assertion that the result is a Decimal instance suffices to check that no floats were implicitly mixed into the computation. To blend a couple of different ideas from the thread reboot together: I suggest a 'linearised' numeric tower that looks like: int -> Decimal -> Fraction -> float -> complex As Adam stated, this is a pragmatic tower stating which implicit coercions are defined by the code, not a formal mathematical relationship. Note that this would involve adding mixed Fraction/Decimal arithmetic as well as Decimal/float arithmetic.
Yes, that was my intention too.
I placed Decimal to the left of Fraction to keep Decimal's dependencies clear and because Decimal -> Fraction conversions appear straightforward (using power of 10 denominators) without introducing the precision issues that would arise in Decimal -> Fraction conversions.
This is just wrong. Decimal is much more like float than like int or Fraction, due to its rounding behavior. (You cannot produce exact results for 1/3 using either Decimal or float.)
Clearly the difficult decision is whether Decimal is between Fraction and float, or between float and complex (I prefer not to say "to the left/right of" since PEP 3141 orders the types in the opposite way as people have been doing here). Both are floating point types that sometimes produce rounded results (e.g. 1/3); the difference is that they use different bases and that Decimal has configurable precision when rounding.
I would make float the last station before complex, whereas Mark would prefer Decimal to go there. I defer to Mark, who has thought a lot more about Decimal than I have.
I also like the idea of adding the decimal context signal that Facundo suggests (e.g. under the name ImplicitCoercionToBinaryFloat).
Yes, this is what I was trying to say (but didn't find the right words for).
So "quick and dirty don't need a perfect answer" operations end up with ordinary binary floats, while more precise code can enable the signal trap to ensure the calculation fails noisily if binary floats are introduced.
But does this break a tie for the relative ordering of Decimal and float in the tower?
Allowing implicit operations would also finally allow Decimal to be registered with numbers.Real.
Right, that's one aspect of what I meant by "embedded in the numeric tower".
Whatever we decide to do will need to be codified in a PEP though. "Cleaning Up Python's Numeric Tower" or something along those lines.
The cleanup is really just specific to Decimal -- int, Fraction and float are already properly embedded in the tower (PEP 3141 doesn't advertise Fraction enough, since it predates it). That we may have to change the hash implementation for the other types is merely a compromise towards efficiency.
The implementation of hash will be complicated, and it may make sense to tweak the hash function of float, Fraction and Decimal to make it easier to ensure that for values that can be represented in either type the hash matches the equality. But this sounds a worthwhile price to pay for proper embedding in the numeric tower. And Mark appears to already have a good answer to that problem.
Which I still have to review. (Mark, if you're there, could you make a brief post here on the mathematical definition of the new hash you're proposing, and why it is both efficient to compute and good (enough) as a hash function?)
-- --Guido van Rossum (python.org/~guido)
- Previous message: [Python-Dev] Mixing float and Decimal -- thread reboot
- Next message: [Python-Dev] Mixing float and Decimal -- thread reboot
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]