]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Backport:
authorRaymond Hettinger <python@rcn.com>
Mon, 23 Sep 2002 14:52:40 +0000 (14:52 +0000)
committerRaymond Hettinger <python@rcn.com>
Mon, 23 Sep 2002 14:52:40 +0000 (14:52 +0000)
SF bug 594996:  OverflowError in random.randrange
Loosened the acceptable 'start' and 'stop' arguments so that any
Python (bounded) ints can be used.  So, e.g., randrange(-sys.maxint-1,
sys.maxint) no longer blows up.

Lib/random.py

index af788c637a45a6944e93658d0b9d770483dca269..bfbf4ed1ad90955205d3d357b30e270736692c6a 100644 (file)
@@ -75,6 +75,7 @@ used to "move backward in time":
 
 from math import log as _log, exp as _exp, pi as _pi, e as _e
 from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
+from math import floor as _floor
 
 __all__ = ["Random","seed","random","uniform","randint","choice",
            "randrange","shuffle","normalvariate","lognormvariate",
@@ -286,7 +287,7 @@ class Random:
         """
 
         # This code is a bit messy to make it fast for the
-        # common case while still doing adequate error checking
+        # common case while still doing adequate error checking.
         istart = int(start)
         if istart != start:
             raise ValueError, "non-integer arg 1 for randrange()"
@@ -294,14 +295,26 @@ class Random:
             if istart > 0:
                 return int(self.random() * istart)
             raise ValueError, "empty range for randrange()"
+
+        # stop argument supplied.
         istop = int(stop)
         if istop != stop:
             raise ValueError, "non-integer stop for randrange()"
+        if step == 1 and istart < istop:
+            try:
+                return istart + int(self.random()*(istop - istart))
+            except OverflowError:
+                # This can happen if istop-istart > sys.maxint + 1, and
+                # multiplying by random() doesn't reduce it to something
+                # <= sys.maxint.  We know that the overall result fits
+                # in an int, and can still do it correctly via math.floor().
+                # But that adds another function call, so for speed we
+                # avoided that whenever possible.
+                return int(istart + _floor(self.random()*(istop - istart)))
         if step == 1:
-            if istart < istop:
-                return istart + int(self.random() *
-                                   (istop - istart))
             raise ValueError, "empty range for randrange()"
+
+        # Non-unit step argument supplied.
         istep = int(step)
         if istep != step:
             raise ValueError, "non-integer step for randrange()"