PageRenderTime 50ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/pypy/module/_random/interp_random.py

https://bitbucket.org/pypy/pypy/
Python | 117 lines | 99 code | 14 blank | 4 comment | 17 complexity | 54586a0e7cd47a7524bddd9a2ccab5bc MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import time
  2. from pypy.interpreter.error import oefmt
  3. from pypy.interpreter.typedef import TypeDef
  4. from pypy.interpreter.gateway import interp2app, unwrap_spec
  5. from pypy.interpreter.baseobjspace import W_Root
  6. from rpython.rlib.rarithmetic import r_uint, intmask, widen
  7. from rpython.rlib import rbigint, rrandom, rstring
  8. def descr_new__(space, w_subtype, __args__):
  9. w_anything = __args__.firstarg()
  10. x = space.allocate_instance(W_Random, w_subtype)
  11. x = space.interp_w(W_Random, x)
  12. W_Random.__init__(x, space, w_anything)
  13. return space.wrap(x)
  14. class W_Random(W_Root):
  15. def __init__(self, space, w_anything):
  16. self._rnd = rrandom.Random()
  17. self.seed(space, w_anything)
  18. def random(self, space):
  19. return space.newfloat(self._rnd.random())
  20. def seed(self, space, w_n=None):
  21. if w_n is None:
  22. w_n = space.newint(int(time.time()))
  23. else:
  24. if space.isinstance_w(w_n, space.w_int):
  25. w_n = space.abs(w_n)
  26. elif space.isinstance_w(w_n, space.w_long):
  27. w_n = space.abs(w_n)
  28. else:
  29. n = space.hash_w(w_n)
  30. w_n = space.wrap(r_uint(n))
  31. key = []
  32. w_one = space.newint(1)
  33. w_two = space.newint(2)
  34. w_thirtytwo = space.newint(32)
  35. # 0xffffffff
  36. w_masklower = space.sub(space.pow(w_two, w_thirtytwo, space.w_None),
  37. w_one)
  38. while space.is_true(w_n):
  39. w_chunk = space.and_(w_n, w_masklower)
  40. chunk = space.uint_w(w_chunk)
  41. key.append(chunk)
  42. w_n = space.rshift(w_n, w_thirtytwo)
  43. if not key:
  44. key = [r_uint(0)]
  45. self._rnd.init_by_array(key)
  46. def getstate(self, space):
  47. state = [None] * (rrandom.N + 1)
  48. for i in range(rrandom.N):
  49. state[i] = space.wrap(widen(self._rnd.state[i]))
  50. state[rrandom.N] = space.newlong(self._rnd.index)
  51. return space.newtuple(state)
  52. def setstate(self, space, w_state):
  53. if not space.isinstance_w(w_state, space.w_tuple):
  54. raise oefmt(space.w_TypeError, "state vector must be tuple")
  55. if space.len_w(w_state) != rrandom.N + 1:
  56. raise oefmt(space.w_ValueError, "state vector is the wrong size")
  57. w_zero = space.newint(0)
  58. # independent of platfrom, since the below condition is only
  59. # true on 32 bit platforms anyway
  60. w_add = space.pow(space.newint(2), space.newint(32), space.w_None)
  61. for i in range(rrandom.N):
  62. w_item = space.getitem(w_state, space.newint(i))
  63. if space.is_true(space.lt(w_item, w_zero)):
  64. w_item = space.add(w_item, w_add)
  65. self._rnd.state[i] = space.uint_w(w_item)
  66. w_item = space.getitem(w_state, space.newint(rrandom.N))
  67. self._rnd.index = space.int_w(w_item)
  68. def jumpahead(self, space, w_n):
  69. if space.isinstance_w(w_n, space.w_long):
  70. num = space.bigint_w(w_n)
  71. n = intmask(num.uintmask())
  72. else:
  73. n = space.int_w(w_n)
  74. self._rnd.jumpahead(n)
  75. @unwrap_spec(k=int)
  76. def getrandbits(self, space, k):
  77. if k <= 0:
  78. raise oefmt(space.w_ValueError,
  79. "number of bits must be greater than zero")
  80. bytes = ((k - 1) // 32 + 1) * 4
  81. bytesarray = rstring.StringBuilder(bytes)
  82. for i in range(0, bytes, 4):
  83. r = self._rnd.genrand32()
  84. if k < 32:
  85. r >>= (32 - k)
  86. bytesarray.append(chr(r & r_uint(0xff)))
  87. bytesarray.append(chr((r >> 8) & r_uint(0xff)))
  88. bytesarray.append(chr((r >> 16) & r_uint(0xff)))
  89. bytesarray.append(chr((r >> 24) & r_uint(0xff)))
  90. k -= 32
  91. # little endian order to match bytearray assignment order
  92. result = rbigint.rbigint.frombytes(
  93. bytesarray.build(), 'little', signed=False)
  94. return space.newlong_from_rbigint(result)
  95. W_Random.typedef = TypeDef("Random",
  96. __new__ = interp2app(descr_new__),
  97. random = interp2app(W_Random.random),
  98. seed = interp2app(W_Random.seed),
  99. getstate = interp2app(W_Random.getstate),
  100. setstate = interp2app(W_Random.setstate),
  101. jumpahead = interp2app(W_Random.jumpahead),
  102. getrandbits = interp2app(W_Random.getrandbits),
  103. )