Wondering if there is an elegant way to do this using a single function instead of writing something custom.
For example I want to separate 100$ into 3 parts (which do NOT have to be equal).
If I simply do 100/3 then each part will be 33.33$.
1 => 33.33 2 => 33.33 3 => 33.33
If I combine these parts back together it will return 99.9 instead of 100.
How can I make it separate the value into 3 parts with one of them being being different so when combined together it will equal 100$ and not 99.9$
1 => 33.34 2 => 33.33 3 => 33.33
I wrote this function, but hoping there’s a one liner that I can use instead
function adjust_parts($total, $parts) { // If total does not equal the sum of all the parts if(array_sum($parts) != $total) { // Keep adding a penny until it's "properly" spread $adjusted = false; while ($adjusted == false) { $parts[0] += 0.01; if(bccomp(array_sum($parts), $total, 2) == 0) { $adjusted = true; } } } return $parts; }
Thank you
Advertisement
Answer
You could make up your $parts
array of $pieces-1
copies of $total/$pieces
, rounded to an appropriate precision, and then just push a final value which is $total
minus the sum of the existing parts. For example:
$total = 100; $pieces = 3; $precision = 2; $parts = array_fill(0, $pieces - 1, round($total / $pieces, $precision)); $parts[] = number_format($total - array_sum($parts), $precision); print_r($parts);
Output
Array ( [0] => 33.33 [1] => 33.33 [2] => 33.34 )