[Python-ideas] numerical type combining integer and float/decimal properties [Was: Re: Python Numbers as Human Concept Decimal System]

Guido van Rossum guido at python.org
Mon Mar 10 18:56:20 CET 2014


On Mon, Mar 10, 2014 at 10:48 AM, Wolfgang Maier <
wolfgang.maier at biologie.uni-freiburg.de> wrote:

> Am Montag, 10. März 2014 14:53:42 UTC+1 schrieb Stefan Krah:
>
> > [My apologies for being terse, I don't have much time to follow this
> discussion right now.]
>
> > Nick Coghlan <ncoghlan at gmail.com> wrote:
> >> I think users of decimal literals will just need to deal with the risk
> of
> unexpected rounding, as the alternatives are even more problematic.
>
> > That is why I think we should seriously consider moving to IEEE semantics
> for a decimal literal.  Among other things:
> > - Always round the literal inputs.
> > - Supply IEEE contexts.
> > - Make Decimal64 the default.
> > - Add the missing rounding modes to sqrt() and exp().
> > - Keep the ability to create exact Decimals through the constructor when
> no context is passed.
> > - Make the Decimal constructor use the context for rounding if it is
> passed.
> > - ...
>
> While I find this discussion about decimal literals extremely interesting,
> in my opinion, such a literal should have an underlying completely new
> numerical type, if it is really supposed to be for inexperienced users.
>
> Most of the discussions right now concern rounding issues that occur after
> the decimal point, but I think an at least equally big problem is rounding
> *to the left* of it as in (using current float):
>
> >>> 1e50 + 1000
> 1e+50
>
> Importantly, Decimal is no cure here:
>
> >>> Decimal(10**50) + Decimal(100)
> Decimal('1.000000000000000000000000000E+50')
>
> (of course, you can debate context settings to make this particular example
> work, but, in general, it happens with big enough numbers.)
>
> The solution for this example is using ints of course:
>
> >>> 10**50 + 100
> 100000000000000000000000000000000000000000000000100
>
> , but obviously this works only for whole numbers, so there currently is no
> built-in way to make this example work correctly:
>
> >>> 10**50 - 9999999999999999.5
> 1e+50
>
> (or with Decimal:
> >>> Decimal(10**50) - Decimal('9999999999999999.5')
> Decimal('1.000000000000000000000000000E+50')
> ).
>
> If we are discussing a new number literal I would like to have it cope with
> this and my suggestion is a new numeric type that's sort of a hybrid
> between
> int and either Decimal or float, i.e., a type that behaves like int for
> digits left of the decimal point, but may truncate to the right.
> In pure Python, something similar (but not a literal form of course) could
> be implemented as a class that stores the left digits as an int and the
> right digits as a float/Decimal internally. Calculations involving this
> class would be slow due to the constant need of shifting digits between the
> integer´and the float part, and might be too slow for many users even when
> written in C, but its behavior would meet the expectation of inexperienced
> people better than the existing types.
> Going back to Mark Harris' initial proposal of unifying numeric types
> (which
> I am not trying to support in any way here), such a type would even allow
> to
> unify int and float since an ints could be considered a subset of the new
> type with a fractional part of zero.
>

I think what you're proposing here is variant of fixed-point numbers. The
representation you seem to be looking for is an arbitrary-precision integer
plus an exponent. A question for you: how would you treat results like 1/3?

-- 
--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140310/e51f1b29/attachment-0001.html>


More information about the Python-ideas mailing list