[Python-Dev] basenumber redux (original) (raw)
Adam Olsen rhamph at gmail.com
Wed Jan 18 00:29:35 CET 2006
- Previous message: [Python-Dev] basenumber redux
- Next message: [Python-Dev] basenumber redux
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 1/17/06, Alex Martelli <aleaxit at gmail.com> wrote:
Being able to change imaplib to use basenumber instead of (int, float) won't make it SIMPLER, but it will surely make it BETTER -- why should a long be rejected, or a Decimal, for that matter?
Because there's no guarantee that they'll produce correct results? All number types are approximations of true numbers, and they all behave wrong in creative ways.
For example:
def xrange(start, stop, step): i = start while i < stop: yield i i += step
This works fine so long as you only give it int as input, and has no maximum value.
for i in xrange(253, 253+3, 1): print i ... 9007199254740992 9007199254740993 9007199254740994
Float inputs also work so long as you don't get large enough to provoke rounding. However, as soon as you do...
for i in xrange(253, 253+3, 1.0): print i ... 9007199254740992 9.00719925474e+15 9.00719925474e+15 9.00719925474e+15 9.00719925474e+15 9.00719925474e+15 9.00719925474e+15 974e+15 Traceback (most recent call last): File "", line 1, in ? KeyboardInterrupt
The function fails. Floating point, despite being a "number" and supporting the "number interface", does not behave close enough to what the programmer desires to work for all values. There might be a way to handle floats specially that a mathematician may understand, but the only way I know of is to convert to int at the start of the function.
def xrange(start, stop, step): start, stop, step = int(start), int(stop), int(step) i = start while i < stop: yield i i += step
for i in xrange(253, 253+3, 1.0): print i ... 9007199254740992 9007199254740993 9007199254740994
That works so long as the floats are all integral values. Unfortunately a non-integral value will get truncated silently. An explicit check for equality after the conversion would have to be added, or Guido's index could be used, but index seems misnamed for this usage.
Another approach would be changing operations involving floats to return intervals instead. The high end of the interval would continue to count up when rounding is provoked, and would raise an exception when the i < stop is executed (due to being ambiguous). Once float uses intervals you could state that all number types are expected to use intervals in the face of inexactness (and those who don't behave as expected would have unexpected results.)
-- Adam Olsen, aka Rhamphoryncus
- Previous message: [Python-Dev] basenumber redux
- Next message: [Python-Dev] basenumber redux
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]