I am following this tutorial by Hans Petter Langtangen, in order to understand Cython better for the purpose of fast generation of random numbers.
The author has the following line:
r = 1 + int(rand()/(RAND_MAX*6.0))
in his tutorial, which claims to produce a random integer between 1 and 6. To me, it looks like a mistake, as rand()
(cimported from libc.stdlib
) is generating a random integer from 0 to RAND_MAX
, so I guess the line
r = 1 + int(6*rand()/(RAND_MAX(1.0))
should be more appropriate there. So I have created a little Cython script that should roll a random integer between 1 and n
, printing debug messages while doing so. Here's the script:
from libc.stdlib cimport rand, RAND_MAX
def print_rand(int n):
cdef int r
print "max", RAND_MAX
cdef int roll
roll = rand()
print "roll", roll
r = 1 + int(n*roll/(RAND_MAX*1.0))
print r
Then I have compiled the script using the following setup.py
script:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
setup(name='Random print',
ext_modules=[Extension('_rand', ['rand.pyx'],)],
cmdclass={'build_ext': build_ext},)
running it via
python setup.py build_ext --inplace
For testing, I opened IPython
, and the following mystery occurred:
In [1]: import _rand
In [2]: _rand.print_rand(1000)
max 2147483647
roll 1804289383
1
but that doesn't make sense, as
In [3]: 1 + int(1000*1804289383/(2147483647*1.0))
Out[3]: 841
What am I missing here?
The multiplication
n*roll
has a result too large to fit into a Cython int. Unlike with Python ints, which automatically switch to arbitrary-precision representation when such a thing happens, Cython handles overflow like C. That generally means the high bits that don't fit are discarded; I am not sure whether it is undefined behavior in Cython (in which case much worse things can happen), or whether Cython guarantees specific overflow handling.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.