Per*_*röm 8 php rounding-error divide
用PHP编写的带有MySQL数据库的Web应用程序.
我有一个系统,可以在分摊成本时为许多人计算不同的成本.例如,人员A购买的东西为10,而人员B,C和D应该分摊成本.
因此,该系统应该记录A人10 的正记录和B,C和D的10/3的负记录.
但是,当这样做时; 四舍五入后B,C和D均为-3.33.这当然并不加起来总数的10什么的要对这个问题的最好方法是什么?一个最优的解决方案是随机化一个人获得的稍微大一点的成本.
一个可能的解决方案是,如果我只是让最后一个人的债务10 - (A + B),但是如果四个人分摊成本例如13.34 则存在问题.那么不同的部分将是3.34,3.34,3.34和3.32,而最佳分割将是3.34,3.34,3.33,3.33.
有些人可能会争辩说,只要有足够的小数,这只是在拥有大量行时的问题.但在一个经济的系统中,我认为从一开始就拥有一个故障安全系统是很重要的.它需要是可扩展的,甚至不会有任何误差.不公平是好的,只是没有错误.
类似的问题:总和分值问题(处理舍入误差)
这似乎有效 - http://jsfiddle.net/nQakD/。
\n\n使用 jQuery 作为示例,但如果您了解 PHP,您应该能够轻松地将其转换为 PHP。如果您还需要 php 代码,请告诉我,我会为您编写。
\n\n我也会将代码粘贴到这里 -
\n\n$(document).ready(function() {\n var price = 17.48, people = 4, payment = (price/people).toFixed(2), count=0;\n var payments = [];\n for(i = 0; i < people; i++) {\n payments.push(payment); \n }\n\n if(payment*people != price) {\n var currentPayment = payment*people;\n\n $(payments).each(function() {\n if(currentPayment < price) {\n currentPayment = (currentPayment-this).toFixed(2);\n var newPayment = parseFloat(this)+0.01;\n payments[count] = newPayment.toFixed(2);\n currentPayment = parseFloat(currentPayment)+parseFloat(newPayment);\n }\n else if(currentPayment > price) {\n currentPayment = (currentPayment-this).toFixed(2);\n var newPayment = parseFloat(this)-0.01;\n payments[count] = newPayment.toFixed(2);\n currentPayment = parseFloat(currentPayment)+parseFloat(newPayment);\n }\n count++;\n }); \n\n } \n $(payments).each(function() {\n $("#result").append("<b>"+this+"</b><br/>");\n }); \n});\xe2\x80\x8b\nRun Code Online (Sandbox Code Playgroud)\n\n编辑:
\n\n这是有效的 php 代码 -
\n\n$price = 13.34;\n$people = 4;\n$payment = (float)$price/$people;\n$payment = 0.01 * (int)($payment*100);\n$count = 0;\n$payments = Array();\nfor($i = 0; $i < $people; $i++) {\n array_push($payments, $payment);\n}\nif($payment*$people != $price) {\n $currentPayment = $payment*$people;\n foreach($payments as $pay) {\n if($currentPayment < $price) {\n $currentPayment = $currentPayment-$pay;\n $currentPayment = 0.01 * (int)($currentPayment*100); \n $newPayment = (float)$pay+0.01;\n $newPayment = 0.01 * (int)($newPayment*100);\n $payments[$count] = $newPayment;\n $currentPayment = (float)$currentPayment+$newPayment;\n }\n else if($currentPayment > $price) {\n $currentPayment = $currentPayment-$pay;\n $currentPayment = 0.01 * (int)($currentPayment*100); \n $newPayment = (float)$pay-0.01;\n $newPayment = 0.01 * (int)($newPayment*100);\n $payments[$count] = $newPayment;\n $currentPayment = (float)$currentPayment+$newPayment;\n }\n $count++;\n }\n}\nforeach($payments as $payed) {\n echo \'<b>\'.$payed.\'</b><br />\';\n}\xe2\x80\x8b\xe2\x80\x8b\xe2\x80\x8b\nRun Code Online (Sandbox Code Playgroud)\n\n编辑2:
\n\n这应该可以解决 js 问题 - http://jsfiddle.net/nQakD/也更新了上面的代码。
\n\n编辑3:
\n\n编辑了 PHP 代码和 JS 代码,使其适用于所有示例 - http://jsfiddle.net/nQakD/。
\n