Issue 2487: ldexp(x,n) misbehaves when abs(n) is large (original) (raw)

Created on 2008-03-25 23:25 by fredrikj, last changed 2022-04-11 14:56 by admin. 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 "", line 1, in 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 "", line 1, in 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 "", line 1, in 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 "", line 1, in OverflowError: long int too large to convert to int and in Python 3.0: >>> 1>>(2**40) Traceback (most recent call last): File "", line 1, in 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
2022-04-11 14:56:32 admin set github: 46739
2008-05-09 17:57:00 mark.dickinson set status: open -> closedresolution: fixedmessages: +
2008-05-09 06:52:00 fredrikj set messages: +
2008-04-26 15:33:43 mark.dickinson set files: + ldexp.patchkeywords: + patchmessages: +
2008-03-27 00:43:16 mark.dickinson set messages: +
2008-03-26 01:12:37 mark.dickinson set messages: + versions: + Python 3.0
2008-03-25 23:38:08 christian.heimes set priority: normalassignee: mark.dickinsonmessages: + nosy: + mark.dickinson, christian.heimesversions: + Python 2.6
2008-03-25 23:25:36 fredrikj create