Skip to content

The random number generator is slightly biased toward returning 0 #1434

@mrcslws

Description

@mrcslws

This code looks wrong.

https://github.com/numenta/nupic.core/blob/69b9c79cf34a9c7ab90c8c0f4616504da40edee7/src/nupic/utils/Random.cpp#L192

I think this line should be while (sample >= smax);.

Here's a quick explanation of this code. It generates a random number between 0 and n - 1 by generating a random integer mod n. The sequence 0 mod n, 1 mod n, 2 mod n, ... will cycle through the ring of integers mod n forever, so each return value is almost equally likely. But this sequence will generally end in the middle of this ring of return values, except when 2^32 - 1 happens to be -1 mod n. So this code correctly finds the highest integer that is divisible by n. At this point, it should subtract 1 from this number, or it should do the >= check that I suggested above. Instead, it does a > check.

So, for example, with the default max 2^32 - 1, if the underlying random number generator does return 2^32 - 1, the function will return 0, when it ought to discard this return value and try again. That means that when you call getUInt32() with no max, it's twice as likely to return 0 than any other number. The problem is much less severe for other use cases like getUInt32(1024), but the issue is still there.

This code would be correct if the underlying RandomImpl never returns zero. But I ran a quick test, and it does in fact return zero. For example, with seed 19, it returns 0 on the 1009865459th call.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions