[Patches] fix overflow bug in ldexp(x, exp)
Guido van Rossum
guido@python.org
Tue, 09 May 2000 10:05:27 -0400
[me]
> > On Solaris 2.7, I'm now getting this:
> >
> > >>> ldexp(1, 100000000)
> > Traceback (most recent call last):
> > File "<stdin>", line 1, in ?
> > OverflowError: math range error
> > >>> ldexp(1, sys.maxint-1)
> > Traceback (most recent call last):
> > File "<stdin>", line 1, in ?
> > OverflowError: math range error
> > >>> ldexp(1, sys.maxint) # this takes a second or two...
> > Infinity # ...expected OverflowError!
> > >>>
> >
> > I have a feeling though that this is a bug in the C math library --
> > not sure if it's worth fixing. On Linux I get an OverflowError as
> > expected for sys.maxint.
[Trent]
> It seems to me, as well, that that is a C math library bug. It is not
> returning an ERANGE errno. Can you reproduce this with a simple C program, on
> Solaris?
>
> #include <stdio.h>
> #include <math.h>
> #include <errno.h>
> #include <linits.h>
<limits.h> !
> int main(void)
> {
> double x;
> printf("ldexp(1.0, %d)=%lf\n", INT_MAX, ldexp(1.0, INT_MAX));
> printf("errno = %d (ERANGE=%d)\n", errno, ERANGE);
> }
This takes over a second to run and then prints
ldexp(1.0, 2147483647)=Inf
errno = 0 (ERANGE=34)
Clearly a C library bug. I won't bother to report it to Sun.
> > Note that ldexp(1, 3.14) is still accepted! The 'i' format calls
> > tp_int for floats and int(3.14) is 3.
>
> That is another matter. I don't know what I should expect the 'i' formatter
> to do. It calls PyInt_AsLong. Should PyInt_AsLong complain if it is given a
> PyFloatObject? That is a philosophical question that is kind of moot here
> (its behaviour is not going to change).
See other discusssion. I agree.
> I think that ldexp() should *not* accept a float for the 'exp' argument
> because the rounding to an int is not obvious to the user. I suppose the 'O&'
> formatter could be used with a special converter that raises a TypeError if
> the argument is not an integral type (i.e. PyInt or PyLong). Is it worth
> making that change? Is it even desired to make that change because it might
> break some code out there.
See other discussion. It's not worth the change -- too many other
places suffer in the same way.
--Guido van Rossum (home page: http://www.python.org/~guido/)