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
)