Skip to content

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

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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