Reputation: 7649
I need to slightly scramble real numbers in a report. The values are typically between 0 and 1000, with most being small numbers containing decimals with a scale of 2.
Some examples:
32.1
0.10
0.02
0.01
I put together this simple function to scramble the values slightly:
function tickle_int($v)
{
$tickled = $v + (mt_rand(-40, 40) / 100);
if ($tickled==$v)
{
$tickled = tickle_int($v);
}
return $tickled;
}
But I'm finding that the returned value is often negative. If I change the low value of mt_rand to 0, I only get scrambled values that are greater than the original value, reducing randomness.
How could this function be modified to only return a non-negative value that is randomly above or below the passed input?
Edit to add I need to avoid 0. The scrambled value needs to be non-negative and not zero. The kicker is passing .01. I need a way of randomzing that to values such as .009, .02, .011, ect -- while continuing to significantly randomize larger values.
Upvotes: 0
Views: 82
Reputation: 7195
You have to move -40
outside of mt_rand
:
function tickle_int($v, $w)
{
$tickled = $v + (mt_rand(0, 2 * $w) - ($v >= $w? $w : $v)) / 100;
if ($tickled==$v)
{
$tickled = tickle_int($v);
}
return $tickled;
}
tickle_int(0.5, 40);
Upvotes: 1
Reputation: 875
If you don't care too much about the random distribution, then you could simply do
if ($tickled < 0)
{
$tickled = 0;
}
return $tickled;
Otherwise, you need to modify the min parameter passed to mt_rand
to be dependent on $v
.
Upvotes: 0
Reputation: 165
try this,
function tickle_int($v)
{
$random = mt_rand(40, 80);
$tickled = $v + (($random - 40) / 100);
if ($tickled==$v)
{
$tickled = tickle_int($v);
}
print_r($tickled);
}
Upvotes: 1