简体   繁体   中英

Cython random roll does not produce the expected output

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM