Strange behavior of the rand () function

2

By setting the documentation

echo rand() // Imprime algo completamente aleatório
echo rand($min, $max) // Imprime algo em um range entre min e max

In a code, inside a loop, I accidentally generated the following rand($max, $min) I noticed the bizarre behavior, it does not generate a warning saying that the value of the first parameter should not be greater than the value of the second, as if for example I omitted just one of the values, which would generate me:

  

E_WARNING: type 2 - rand () expects exactly 2 parameters, 1 given

If I use the mt_rand function, for example, it gives me the warning:

  

E_WARNING: type 2 - mt_rand (): max () is smaller than min ()

But with rand generated values with a peculiar behavior that made me curious

Testing for example the following code:

for($j = 0; $j < 10; $j++){
    for($i = 0; $i < 10; $i++){
        if($i < 9) echo rand(10,0).",";
        else echo rand(10,0)." | teste -> ".($j+1)."<br/>";
    }
}

I got more or less the following:

3,10,4,5,7,8,4,9,5,2 | teste -> 1
2,2,10,5,9,6,8,2,5,2 | teste -> 2
7,8,4,10,5,7,8,8,5,4 | teste -> 3
9,7,4,3,10,10,9,4,8,4 | teste -> 4
5,8,4,4,3,3,8,10,4,3 | teste -> 5
2,9,9,5,8,4,10,5,10,5 | teste -> 6
8,9,10,2,10,9,10,9,2,8 | teste -> 7
2,6,6,5,9,8,7,6,8,9 | teste -> 8
8,8,7,6,2,5,8,2,9,8 | teste -> 9
5,6,6,4,7,6,3,6,4,4 | teste -> 10

And worse! If you change rand to closest values, type rand(10,8) , it prints:

10,10,10,10,10,10,10,10,10,10 | teste -> 1
10,10,10,10,10,10,10,10,10,10 | teste -> 2
10,10,10,10,10,10,10,10,10,10 | teste -> 3
10,10,10,10,10,10,10,10,10,10 | teste -> 4
10,10,10,10,10,10,10,10,10,10 | teste -> 5
10,10,10,10,10,10,10,10,10,10 | teste -> 6
10,10,10,10,10,10,10,10,10,10 | teste -> 7
10,10,10,10,10,10,10,10,10,10 | teste -> 8
10,10,10,10,10,10,10,10,10,10 | teste -> 9
10,10,10,10,10,10,10,10,10,10 | teste -> 10

I tested the following online emulators: repl.it , ideone.com and phpfiddle.org and I noticed that in those that use more current versions of PHP this does not happen, I went deeper and found this emulator to choose old versions: sandbox.onlinephpfunctions.com and I saw that until version 7.0.14 this still happened, I tried to look for some thing in the php.net changelog and in the official php repository at gitHub but could not find anything about it.

Anyway, this is a mistake, and it should not even exist in code! But it struck me as a curiosity, which actually happens with the rand function in old versions of PHP, when a max value is less than the min value?

    
asked by anonymous 24.05.2017 / 10:46

1 answer

2

I have read both documentation, in English and Portuguese. I can say that there is a very big difference between them. See the English documentation if you have no problem with English.

I also checked the source code in GitHub .

Currently, in the most recent versions available, calls to the rand function are called mt_rand , however it treats max < min specifically to avoid calling mt_rand with the values exchanged.

Have a look at the documentation comments in English that speaks precisely of the trend of PHP in generate close numbers of multiples of 3, but I did not understand the exact reason for this. It seems that another comment attempted to explain putting the blame on the large range of numbers used by the previous one.

By implementing php_mt_rand_range in C in GitHub , if random number generation is of low entropy at the least significant bits, the return given by (result % umax) + min (where umax = max - min + 1 ) will always be similar when the difference between the minimum and the maximum is also small. To judge if the random number function has high entropy is beyond my knowledge, however, and even more to my knowledge is to judge if the least significant bits have high entropy.

    
24.05.2017 / 12:17