Skip to content

Instantly share code, notes, and snippets.

@benjaminprojas
Last active April 7, 2023 11:20
Show Gist options
  • Save benjaminprojas/4170975 to your computer and use it in GitHub Desktop.
Save benjaminprojas/4170975 to your computer and use it in GitHub Desktop.
Function to divide money (numbers with 2 decimal points) as evenly as possible between any given number of recipients
<?php
echo nl2br(print_r(divide_money_evenly((float)(string) 78.23, 3), true));
function divide_money_evenly($number, $divided_by, $numbers=array()) {
$total = 0;
for($i=1; $i<=$divided_by; $i++) {
if(abs($number - $total) != 0) {
$divided = $number / $divided_by;
if($divided < 1) {
$rounded = 0;
}
else {
$rounded = floor($divided);
}
if($rounded == 0) {
$total += 0.01;
if(isset($numbers[$i])) {
$numbers[$i] = $numbers[$i] + 0.01;
}
else {
$numbers[$i] = 0.01;
}
}
else {
$total += $rounded;
if(isset($numbers[$i])) {
$numbers[$i] = $numbers[$i] + $rounded;
}
else {
$numbers[$i] = $rounded;
}
}
}
}
$difference = $number - $total;
if($difference > 0) {
$numbers = divide_money_evenly(float)(string) $difference, $divided_by, $numbers);
}
return $numbers;
}
@Pikamander2
Copy link

Pikamander2 commented Apr 7, 2023

Here's a modified version that returns the values as an array of 2-decimal strings like '26.08' rather than 26.080000000000013.

I also cleaned up the variable names and changed its indexing to start at 0 rather than 1.

<?php
function divide_money_evenly($dollar_amount, $num_parts, $dollar_amounts=[])
{
	$total = 0;
	
	for ($i = 0; $i < $num_parts; $i++)
	{
		if (abs($dollar_amount - $total) != 0)
		{
			$divided = $dollar_amount / $num_parts;
		  
			if ($divided < 1)
			{
				$rounded = 0;
			}
			
			else
			{
				$rounded = floor($divided);
			}
			
			if ($rounded == 0)
			{
				$total += 0.01;
				
				if (isset($dollar_amounts[$i]))
				{
					$dollar_amounts[$i] = $dollar_amounts[$i] + 0.01;
				}
				
				else
				{
					$dollar_amounts[$i] = 0.01;
				}
			}
			
			else
			{
				$total += $rounded;
				
				if (isset($dollar_amounts[$i]))
				{
					$dollar_amounts[$i] = $dollar_amounts[$i] + $rounded;
				}
				
				else
				{
					$dollar_amounts[$i] = $rounded;
				}
			}
		}
	}
	
	$difference = $dollar_amount - $total;

	if ($difference > 0)
	{
		$dollar_amounts = divide_money_evenly((float)(string) $difference, $num_parts, $dollar_amounts);
	}
  
	foreach ($dollar_amounts as &$dollar_amount)
	{
	    $dollar_amount = strval($dollar_amount);
	}
  
	return $dollar_amounts;
}

Usage example:

var_export(divide_money_evenly(78.23, 3));

Expected output:

array (
  0 => '26.08',
  1 => '26.08',
  2 => '26.07',
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment