On Sat, Mar 8, 2014 at 12:10 AM, Guido van Rossum email@example.com wrote:
But Decimal(<float>) is relatively new (it was an error in 2.6). I know it's annoying to change it again, but I also have the feeling that there's not much use in producing a Decimal with 53 (or more?) decimal digits of precision from a float with 53 bits -- at least not by default. Maybe we can relent on this guarantee and make the constructor by default use fewer digits (e.g. using the same algorithm used by repr(<float>)) and have an optional argument to produce the full precision? Or reserve Decimal.from_float() for that?
Using the same algorithm as used by repr(float) feels like a bad idea to me: my gut feeling is that a conversion from float to Decimal is a fundamental operation that should be easily describable in simple terms, and should not involve the level of complication and 'magic' involved in the float repr. (That level of magic seems fine for the repr, because in most cases you don't actually care too much what string you get so long as it evaluates back to the correct float; you're not doing arithmetic with the result.)
IEEE 754-2008 requires simply that conversions between numbers in different formats round correctly. It specifies a "convertFormat" operation, described as follows:
""" If the conversion is to a format in a different radix or to a narrower precision in the same radix, the result shall be rounded as specified in Clause 4. Conversion to a format with the same radix but wider precision and range is always exact. ... """
... where clause 4 is the one that outlines the general rounding rules that apply to almost all IEEE 754 operations.
I see three sane options for float to Decimal conversion:
Option 2 would seem closest to what IEEE 754 specifies. To augment option 2, we could also make it easier to create Decimal contexts corresponding to the IEEE 754 recommended interchange formats (decimal32, decimal64, decimal128). This was already proposed in http://bugs.python.org/issue8786.