# [Python-ideas] Python Float Update

Steven D'Aprano steve at pearwood.info
Tue Jun 2 03:58:09 CEST 2015

```On Tue, Jun 02, 2015 at 10:08:37AM +1000, Nick Coghlan wrote:

> It seems to me that a potentially better option might be to adjust the
> implicit float->Decimal conversion in the Decimal constructor to use
> the same algorithm as we now use for float.__repr__ [1], where we look
> for the shortest decimal representation that gives the same answer
> when rendered as a float. At the moment you have to indirect through
> str() or repr() to get that behaviour:

Apart from the questions of whether such a change would be allowed by
the Decimal specification, and the breaking of backwards compatibility,
I would really hate that change for another reason.

At the moment, a good, cheap way to find out what a binary float "really
is" (in some sense) is to convert it to Decimal and see what you get:

Decimal(1.3)
-> Decimal('1.3000000000000000444089209850062616169452667236328125')

If you want conversion from repr, then you can be explicit about it:

Decimal(repr(1.3))
-> Decimal('1.3')

("Explicit is better than implicit", as they say...)

Although in fairness I suppose that if this change happens, we could
keep the old behaviour in the from_float method:

# hypothetical future behaviour
Decimal(1.3)
-> Decimal('1.3')
Decimal.from_float(1.3)
-> Decimal('1.3000000000000000444089209850062616169452667236328125')

But all things considered, I don't think we're doing people any favours
by changing the behaviour of float->Decimal conversions to implicitly
use the repr() instead of being exact. I expect this strategy is like
trying to flatten a bubble under wallpaper: all you can do is push the
gotchas and surprises to somewhere else.

Oh, another thought... Decimals could gain yet another conversion
method, one which implicitly uses the float repr, but signals if it was
an inexact conversion or not. Explicitly calling repr can never signal,
since the conversion occurs outside of the Decimal constructor and
Decimal sees only the string:

Decimal(repr(1.3)) cannot signal Inexact.

But:

Decimal.from_nearest_float(1.5)  # exact
Decimal.from_nearest_float(1.3)  # signals Inexact

That might be useful, but probably not to beginners.

--
Steve
```