[Python-checkins] python/dist/src/Lib random.py,1.26.6.5,1.26.6.6

rhettinger@users.sourceforge.net rhettinger@users.sourceforge.net
Mon, 23 Sep 2002 07:52:42 -0700


Update of /cvsroot/python/python/dist/src/Lib
In directory usw-pr-cvs1:/tmp/cvs-serv24327

Modified Files:
      Tag: release22-maint
	random.py 
Log Message:
Backport:

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.



Index: random.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/random.py,v
retrieving revision 1.26.6.5
retrieving revision 1.26.6.6
diff -C2 -d -r1.26.6.5 -r1.26.6.6
*** random.py	23 Sep 2002 14:48:16 -0000	1.26.6.5
--- random.py	23 Sep 2002 14:52:40 -0000	1.26.6.6
***************
*** 76,79 ****
--- 76,80 ----
  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",
***************
*** 287,291 ****
  
          # This code is a bit messy to make it fast for the
!         # common case while still doing adequate error checking
          istart = int(start)
          if istart != start:
--- 288,292 ----
  
          # This code is a bit messy to make it fast for the
!         # common case while still doing adequate error checking.
          istart = int(start)
          if istart != start:
***************
*** 295,306 ****
                  return int(self.random() * istart)
              raise ValueError, "empty range for randrange()"
          istop = int(stop)
          if istop != stop:
              raise ValueError, "non-integer stop for randrange()"
          if step == 1:
-             if istart < istop:
-                 return istart + int(self.random() *
-                                    (istop - istart))
              raise ValueError, "empty range for randrange()"
          istep = int(step)
          if istep != step:
--- 296,319 ----
                  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:
              raise ValueError, "empty range for randrange()"
+ 
+         # Non-unit step argument supplied.
          istep = int(step)
          if istep != step: