note 96022 added to function.mt-rand
| From: | ISAWHIM at osu1 dot php dot net | Date: | Wed, 03 Feb 2010 16:46:44 +0000 |
| Subject: | note 96022 added to function.mt-rand | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-165630@lists.php.net to get a copy of this message | ||
This is not trying to dissuade use of this alternative, just trying to expand on the things to
"watch-out-for", when using this...
As per the description assumption...
"Many random number generators of older libcs have dubious or unknown characteristics and are
slow."
You would elude to the assumption that mt_rand() does not have, "dubious or unknown
characteristics". It is obvious that it is faster, but that does not count the additional code
required to ensure validity of results, or scope of input value checking.
This function fails horribly, without error, when operating out of the scope of the range. (Key
point being, "without error".)
mt_getrandmax() is NOT the max INTEGER size. It is limited to positive numbers from ZERO to your
integers largest value. Thus, it is HALF the size of an INTEGER, since integers are SIGNED, but
mt_rand can only correctly randomize from ZERO to mt_getrandmax(). (Though, that is not entirely
true. It can do negative numbers, if the min/max range/spread is not greater than the value of
mt_getrandmax()... sometimes.)
Things to watch-out for... (Sort of negates any speed gains.)
This assumes you "Attempted" to process MIN>=0 and MAX<=mt_getrandmax().
Returning a negative value = RANDOMIZER FAILED
Returning a vlaue higher than mt_getrandmax() = RANDOMIZER FAILED
Returning SAME_NUMBER from more than one call = Possibly RANDOMIZER FAILED
Returning a number <MIN or >MAX = RANDOMIZER FAILED
PHP version 5.2.6 on Apechee 2.0.63 on a Linux server.
Specific instances of failure... (All these still return a value.)
With RAND_MAX reporting that it is '2147483647'.
<?PHP
// Returns negative numbers as if (-2147483647,0)
$z = mt_rand(0,2147483648);
// Returns mostly 1 or negative numbers
$z = mt_rand(-2147483647,2147483647);
// Returns negative numbers, but within range set???
// So much for returning only values from 0 to Max
$z = mt_rand(-2147483647,0);
// Attempt to stay within the range/spread of mt_getrandmax()
// Results are odd, like 180 to 2147478000
$z = mt_rand(2147483647,4294967294);
// Works, but it should not, as the value is not an INT
// Values are converted to floor(x), so range is (0,0)
$z = mt_rand(0.000001,0.9999999);
?>
Code used to test...
<?PHP
// Reports the MAX possible, which is half of an INT's value
echo('RAND_MAX: '.mt_getrandmax());
for($i=0;$i<=100000;$i++) {
// RAND_MAX = 2147483647
$z = mt_rand(0,2147483647);
// echo($z.'<BR>'); // Uncomment to see results, lower LOOP values first!
if($z>$high || !isset($high)){$high=$z;}
if($z<$low || !isset($low)){$low=$z;}
}
echo('HIGH: '.$high.'<BR>LOW: '.$low.'<BR>');
?>
To get a number that is actually in the full range of an INT, you need to make two separate calls,
and add them together. Then convert that unsigned INT value into a signed INT value.
----
Server IP: 69.147.83.197
Probable Submitter: 75.92.64.47
----
Manual Page -- http://www.php.net/manual/en/function.mt-rand.php
Edit -- https://master.php.net/note/edit/96022
Del: integrated -- https://master.php.net/note/delete/96022/integrated
Del: useless -- https://master.php.net/note/delete/96022/useless
Del: bad code -- https://master.php.net/note/delete/96022/bad+code
Del: spam -- https://master.php.net/note/delete/96022/spam
Del: non-english -- https://master.php.net/note/delete/96022/non-english
Del: in docs -- https://master.php.net/note/delete/96022/in+docs
Del: other reasons-- https://master.php.net/note/delete/96022
Reject -- https://master.php.net/note/reject/96022
Search -- https://master.php.net/manage/user-notes.php