Rand Improvement
olekukonko opened this issue · 0 comments
olekukonko commented
Assumption:
- I want to assume that you are using
% 256
because you want to limit the generated numbers between0 - 256
;
Observation 1:
If that is true rand() ^ rand() % 256 would be wrong because of Operator Precedence
Arithmetic comes before bitwise so basically what you are writing is :
rand() ^ (rand() % 256)
Observation 2:
If what you intend to accomplish is
(rand() ^ (rand()) % 256
It would not be efficient on windows platform because of the use of Linear Congruential Generator
. It can be improved with:
(rand() ^ (rand() / getrandmax())) % 256;
Here is a simple test script
$results = array(
"m1" => 0,
"m2" => 0
);
$repeat = ceil(256 / 2); // 50 - 50 ;
for($i = 0; $i < $repeat; $i ++) {
foreach($results as $k => $no) {
$results[$k] += $k($repeat);
}
if ($i == 0) {
printf("First Run\n%s\n\n", json_encode($results, 128));
}
}
printf("$repeat Runs\n%s\n", json_encode($results, 128));
function m1($x) {
$data = array();
$collision = 0;
for($i = 0; $i < $x; $i ++) {
$n = (rand() ^ (rand() / getrandmax())) % 256;
if (isset($data[$n])) {
$collision ++;
} else {
$data[$n] = 0;
}
$data[$n] ++;
}
// rsort($data);
// var_dump($data);
return $collision;
}
function m2($x) {
$data = array();
$collision = 0;
for($i = 0; $i < $x; $i ++) {
$n = (rand() ^ rand()) % 256;
if (isset($data[$n])) {
$collision ++;
} else {
$data[$n] = 0;
}
$data[$n] ++;
}
// rsort($data);
// var_dump($data);
return $collision;
}
Output
First Run
{
"m1": 0,
"m2": 99 <--- Collision on your method
}
128 Runs
{
"m1": 0,
"m2": 12672 <--- Collision on your method
}
- Windows 7 Ultimate Edition Service Pack 1) i586
- PHP Version 5.4.14
- API220100525,TS,VC9