简体   繁体   中英

Random Float against an specific amount with 100 days php

I am trying to generate random values against '100' amount of value for 100 days. I am trying this way with for loop:

        $total_days = 100;
        $total_amount = 100;
        $arr = array();

        for($i = 0; $i < $total_days; ++$i)
        {
            $arr[] = rand(0.0, 1000.0);
        }

        $actual_sum = array_sum($arr);

        for($i = 0; $i < $total_days; ++$i)
        {
            $arr[$i] *= $total_amount /$actual_sum;
            //echo $arr[$i]."<BR><BR>";
            
            $value = $arr[$i];

            $genpackageroi = array(
                'userid' => $userid,
                'pkgid' => $pkgid,
                'pkgcount' => $pkcount,
                'amount' => $value,
                'created_at' => $created_at,
                'updated_at' => $updated_at,
            );

            DB::table('genpackageroi')->insert($genpackageroi);

        }

The random generated value is like 0.1245444 OR 1.1245545, lots of numbers after decimal. While I just want this to be generated in float value like 1.21, 0.10, 2.25 like so. I it possible to do that?

But I want to generate the random numbers in round numbers. Because It dose not matches the actual amount after generating all the random numbers if we sum the generated random numbers. Like if I generates the random numbers for amount of 100, then the sum of all generated random numbers should 100. This is what actually I want.

What I gathered from your statement is that you want 100 floating numbers with 2 decimal places, and the sum of all these numbers should add up to 100.

This certainly is not the cleanest solution, but here goes:

$total_days = 100;
$total_amount = 100;
$arr = array();

for($i = 0; $i < $total_days; ++$i)
{
    $arr[] = rand(0.0, 1000.0);
}
$actual_sum = array_sum($arr);
for($i = 0; $i < $total_days; ++$i)
{
        $y = $arr[$i] * ($total_amount /$actual_sum);
        $arr[$i] = round($y, 2); //round the numbers to 2 dp. Sum of all numbers could be greater than 100.
}
//hack, logic explained below
$maxElementKeys = array_keys($arr, max($arr)); //get max element's key
unset($arr[$maxElementKeys[0]]); //remove the max element from array, now the array contains 99 elements
$arr = array_values($arr); //rebase the keys

for($i = 0; $i < $total_days; ++$i) 
{  
    if($i < ($total_days - 1) )
        $value = $arr[$i]; 
    else 
        $value = $total_amount - array_sum($arr); //to get the 100th number, subtract from 100 to ensure the total always adds up to 100
    $genpackageroi = array(
        'userid' => $userid,
        'pkgid' => $pkgid,
        'pkgcount' => $pkcount,
        'amount' => $value,
        'created_at' => $created_at,
        'updated_at' => $updated_at,
    );
    DB::table('genpackageroi')->insert($genpackageroi);
}

The logic here is that round all numbers to 2dps. The total of which would in most cases exceed 100 by a few dps. Next, get the max random number in the array and remove it from the array to make it an array containing 99 elements. The max number is removed to ensure that the sum of the new array stays below well clear of 100. So, to get the 100th element, get the sum of the new array and subtract that value from 100. Now, the total of all elements of the array and the 100th element that was just calculated should add up to exactly 100, with negligible chance for failure.

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