Random, Y U NO random?


#1

Seems Random is broken:

        String s;
        for (int i = 0; i < 100; ++i)
        {
            if (i != 0)
                s += ", ";
            Random r (i);
            int const val = r.nextInt (4);
            s += String (val);
        }
        Logger::outputDebugString (s);

Produces:

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0

This is bad!


#2

Probably has to do with your seed… try moving the Random object instance outside of the loop.

Random r;
String s;

for (int i = 0; i < 100; ++i)
{
    if (i != 0)
        s += ", ";

    int const val = r.nextInt (4);
    s += String (val);
}

Logger::outputDebugString (s);

#3

How about

    String s;
	Random r(Time::getCurrentTime().currentTimeMillis());
        for (int i = 0; i < 100; ++i)
        {
            if (i != 0)
                s += ", ";

            int const val = r.nextInt (4);
            s += String (val);
        }
        Logger::outputDebugString (s);

that seems to work:

[debug]2, 0, 1, 2, 2, 3, 3, 3, 3, 1, 1, 1, 0, 2, 1, 1, 0, 1, 1, 0, 2, 1, 0, 2, 1, 2, 0, 2, 3, 0, 2, 2, 0, 2, 3, 1, 0, 3, 0, 1, 2, 2, 1, 2, 0, 0, 2, 3, 0, 1, 0, 2, 1, 2, 1, 1, 1, 1, 3, 2, 2, 0, 2, 2, 2, 2, 0, 0, 1, 2, 0, 3, 1, 3, 0, 3, 1, 0, 2, 2, 3, 0, 0, 1, 2, 1, 0, 2, 2, 2, 1, 2, 0, 0, 1, 3, 0, 2, 3, 2 h


#4

It only works because your seed is some huge value. But small seeds should work just as well. This Random class looks broken.


#5

I never passed anything BUT the current time in millis, the manual says to do that:

For a given seed value, the subsequent numbers generated by this object will be predictable, so a good idea is to set this value based on the time, e.g.

new Random (Time::currentTimeMillis()) 

but i never went into details it always worked.


#6

Any random number algorithm is going to be sensitive to certain seed values, and this one’s only a very simple multiply-shift algorithm - I’m not surprised at all that it’d screw up with seed values that only use the bottom few bits!

By far the best way to seed it is to just use the Random() default constructor, which does some shenanigans to make sure its pretty securely chosen.


#7

I need pseudo-random numbers for unit tests. So they can’t be purely or securely random.