classification
Title: ldexp(x,n) misbehaves when abs(n) is large
Type: behavior Stage:
Components: Library (Lib) Versions: Python 3.0, Python 2.6, Python 2.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: mark.dickinson Nosy List: christian.heimes, fredrikj, mark.dickinson
Priority: normal Keywords: patch

Created on 2008-03-25 23:25 by fredrikj, last changed 2008-05-09 17:57 by mark.dickinson. This issue is now closed.

Files
File name Uploaded Description Edit
ldexp.patch mark.dickinson, 2008-04-26 15:33
Messages (7)
msg64527 - (view) Author: Fredrik Johansson (fredrikj) Date: 2008-03-25 23:25
Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from math import ldexp
>>> from sys import maxint

>>> ldexp(1.234, maxint//2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: math range error

>>> ldexp(1.234, maxint)
0.0

>>> ldexp(1.234, -maxint)
0.0

>>> ldexp(1.234, -maxint-2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: long int too large to convert to int

The first and third cases seem right.

The second is clearly a bug.

In the fourth case, it would be more correct to return 0.0 than to raise
an exception IMHO.
msg64529 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2008-03-25 23:38
ldexp(1.234, maxint) works as expected in our trunk-math branch.
ldexp(1.234, -maxint-2) fails with the same error message.
msg64532 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2008-03-26 01:12
I agree that the second and fourth cases are bugs.

The second case looks like a Windows only problem:  I get the expected 
OverflowError on both OS X 10.5.2/Intel and SuSE Linux 10.2/i686.

The fourth case is cross-platform, and occurs also for large exponents:

>>> ldexp(1.234, maxint+1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: long int too large to convert to int

It's still present in Python 3.0.

I'll take a look.
msg64574 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2008-03-27 00:43
There are similar problems with integer shifts.  In the trunk:

>>> 1>>(2**40)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: long int too large to convert to int

and in Python 3.0:

>>> 1>>(2**40)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: Python int too large to convert to C long

These should probably by fixed, too, though at least the error
message is clear.

What should 1<<(2**31) do?
msg65844 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2008-04-26 15:33
Here's a patch that should fix ldexp(x, large_int), as follows:

ldexp(x, n) = x if x is a NaN, zero or infinity
ldexp(x, n) = copysign(0., x) for x finite and nonzero, n large and -ve
ldexp(x, n) -> OverflowError for x finite and nonzero, n large and +ve

It would be good if someone else could review this before I check it in;
Fredrik, would you have time for this?
msg66456 - (view) Author: Fredrik Johansson (fredrikj) Date: 2008-05-09 06:51
I'm not qualified to comment on the implementation. The test cases all
look right.
msg66482 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2008-05-09 17:56
I've committed a (slightly reworked) version of this patch in r62948.
Closing this issue; the problem with 1 >> 2**31 is a separate issue.  

Thanks for the report, Fredrik.
History
Date User Action Args
2008-05-09 17:57:00mark.dickinsonsetstatus: open -> closed
resolution: fixed
messages: + msg66482
2008-05-09 06:52:00fredrikjsetmessages: + msg66456
2008-04-26 15:33:43mark.dickinsonsetfiles: + ldexp.patch
keywords: + patch
messages: + msg65844
2008-03-27 00:43:16mark.dickinsonsetmessages: + msg64574
2008-03-26 01:12:37mark.dickinsonsetmessages: + msg64532
versions: + Python 3.0
2008-03-25 23:38:08christian.heimessetpriority: normal
assignee: mark.dickinson
messages: + msg64529
nosy: + mark.dickinson, christian.heimes
versions: + Python 2.6
2008-03-25 23:25:36fredrikjcreate