简体   繁体   中英

random rounding

So, i got two numbers, say, A and B.

A is any positive number and B is percentage between 0 and 100.

What i need is percentage B of A, but randomly round up or down, eg

A = 15, B = 50, result=7(50%) or 8(50%)

A = 10, B = 33, result=3(67%) or 4(33%)

My current code is

floor($A* ($B + rand(0, 9) ) / 100)

But i believe this is not correct and there's better solutions to this.

EDIT:

I've reviewed the answers, and actually tested them( here ). The problem with submitted solutions is that they all use rand(0,1) which means that it would always round up or down exacly in 50% of cases. But here's a problem: For example, lets take "A = 10, B = 33" case again. There's basically no difference between if B=31 or B=39. What i wanted it to be is to correspond to percentage(eg 31 would result 3 in 90% times and 4 in 10% of cases)

From what i can see in answer, it seems that my original solution would work just fine. I should have originally mentioned that it's not just "random rounding" and explain second case a little bit better.

The original idea was that i have an array of, say, 10 items, and i need to get 33% of them. I cant give 3 or 4 of them all the time, because it messes up the whole point of percentage. So i needed it to be at least statistically correct in long run.

But anyway, thanks for your time.

Rather than randomly deciding which way to round (which will skew your results randomly, and give you non deterministic functions), why not do what bankers do and "round to even"?

echo(round(1.5,0,PHP_ROUND_HALF_EVEN) . "<br>");
echo(round(-1.5,0,PHP_ROUND_HALF_EVEN) . "<br>");

That way 4.5 rounds to 4 and 3.5 rounds to 4. So 50% of the time your midpoint will round up, and 50% of the time your midpoint will round down, as you desired.

Why not decouple the issues of calculating the percentage and deciding how to round?

$X = $A * $B / 100;
$Y = (rand(0,1) > 0) ? floor($X) : ceil($X);
function myround($a, $b) {
    $d = $a * $b / 100.0;
    $f = floor($d);
    if ((rand() / getrandmax()) > ($d - $f)) return $f + 1.0;
    return $f;  
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM