a coder
a coder

Reputation: 7649

Generate non-negative random value slightly above or below a number

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

Answers (4)

hindmost
hindmost

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

Zantier
Zantier

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

Siva Kumar J
Siva Kumar J

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

h.s.o.b.s
h.s.o.b.s

Reputation: 1319

Limit it:

$tickled = $v + ( mt_rand( $v*(-1), 40) / 100 );

Upvotes: 1

Related Questions