[Python-ideas] Python Numbers as Human Concept Decimal System

Andrew Barnert abarnert at yahoo.com
Sat Mar 8 09:16:26 CET 2014


From: Mark H. Harris <harrismh777 at gmail.com>
Sent: Friday, March 7, 2014 11:50 PM


>On Saturday, March 8, 2014 12:52:32 AM UTC-6, Mark H. Harris wrote:


>Guido, Andrew,   I have a question about repr() in my current codes for  3.3.4 and below:
>
>Would it be reasonable to add a function to pdeclib to be used internally like this:
>
>
>def Dec(numform):
>        return Decimal(repr(numform))


Yes. If you know that repr(numform) is the string decimal representation that you want for numform, then Decimal(repr(numform)) is guaranteed to be the decimal floating-point value that you want. So if numform is a float, in Python 3.3, given your examples, then this is exactly what you want.

>Does this work correctly (for pdeclib internally) ?  I think this works better than my first

>stab at this (just using str() )  because repr() acts like an eval() ??


I think you're a little confused here.

First, in 3.3, for float, repr and str return the same thing. You may be working with other types for which that isn't true—but in that case, you need to figure out which one gives you the decimal representation you want, and use that one, whether it's repr or str (or something else).

Second, repr() doesn't act like an eval(). It's sort of an _inverse_ of eval, for some types.[1] For example, the repr of Decimal('0.1') is the string "Decimal('0.1')", and eval("Decimal('0.1')") will give you Decimal('0.1').
 
    [1] Please don't rely on this. First, it's not true for all types. Second, even if you restrict yourself to types where it is true, repr is not the best way to exchange or persist values, and eval leads to dangerous and fragile code. But this is very useful for things like playing with Python at the interactive interpreter.

>It looks like what you are proposing will fix the problem I've been whining about.  Thank you.


I think you may be better off using an explicit repr, even if numform is guaranteed to be a float. It makes your intentions clear: you want the one and only Decimal value that matches the decimal string representation of numform, not just arbitrarily any of the many Decimal values that can round-trip back to the float numform, right?

Of course if at all possible, the best thing to do is to avoid creating floats in the first place. Use Decimal('0.1') for constants in your code, use Decimal(user_input) rather than converting user_input with float or eval and then trying to recover the lost information later, etc. But obviously there are cases where you can't do this, because you've, e.g., received the number as a 64-bit IEEE double over the wire from some other program you don't control. That's where Guido's proposal would help you.



More information about the Python-ideas mailing list