正确的总和除以同和,打击舍入误差(Correct sums with dividing sums,

2019-09-20 01:17发布

Web应用程序使用PHP编码与MySQL数据库。

我有一个分裂的成本时计算的一些人不同成本的系统。 例如人A购买的东西10和人B,C,和d应拆分成本。

该系统应为此注册的10 人A和积极的记录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。

有些人可能会争辩说,有足够的小数有大量行的时候,这是唯一的一个问题。 但是,在一个经济体系,我认为有一个故障安全系统,甚至从一开始就非常重要。 它必须是可扩展的 ,并且不能有丝毫的差错。 不公平是好的,只是没有错误。

类似的问题: 总和除以值的问题(处理舍入误差)

Answer 1:

这似乎工作- http://jsfiddle.net/nQakD/ 。

使用jQuery的为例,但如果你知道PHP,你应该能够很容易地将其转换为PHP。 如果您还需要PHP代码,告诉我,我会替你写。

我在这里也粘贴代码 -

$(document).ready(function() {
    var price = 17.48, people = 4, payment = (price/people).toFixed(2), count=0;
    var payments = [];
    for(i = 0; i < people; i++) {
       payments.push(payment);   
    }

    if(payment*people != price) {
        var currentPayment = payment*people;

        $(payments).each(function() {
            if(currentPayment < price) {
                currentPayment = (currentPayment-this).toFixed(2);
                var newPayment = parseFloat(this)+0.01;
                payments[count] = newPayment.toFixed(2);
                currentPayment = parseFloat(currentPayment)+parseFloat(newPayment);
            }
            else if(currentPayment > price) {
                currentPayment = (currentPayment-this).toFixed(2);
                var newPayment = parseFloat(this)-0.01;
                payments[count] = newPayment.toFixed(2);
                currentPayment = parseFloat(currentPayment)+parseFloat(newPayment);
            }
            count++;
        });   

    }  
    $(payments).each(function() {
        $("#result").append("<b>"+this+"</b><br/>");
    });       
});​

编辑:

这里是工作的PHP代码 -

$price = 13.34;
$people = 4;
$payment = (float)$price/$people;
$payment = 0.01 * (int)($payment*100);
$count = 0;
$payments = Array();
for($i = 0; $i < $people; $i++) {
    array_push($payments, $payment);
}
if($payment*$people != $price) {
    $currentPayment = $payment*$people;
    foreach($payments as $pay) {
        if($currentPayment < $price) {
            $currentPayment = $currentPayment-$pay;
            $currentPayment = 0.01 * (int)($currentPayment*100);               
            $newPayment = (float)$pay+0.01;
            $newPayment = 0.01 * (int)($newPayment*100);
            $payments[$count] = $newPayment;
            $currentPayment = (float)$currentPayment+$newPayment;
        }
        else if($currentPayment > $price) {
            $currentPayment = $currentPayment-$pay;
            $currentPayment = 0.01 * (int)($currentPayment*100);               
            $newPayment = (float)$pay-0.01;
            $newPayment = 0.01 * (int)($newPayment*100);
            $payments[$count] = $newPayment;
            $currentPayment = (float)$currentPayment+$newPayment;
        }
        $count++;
    }
}
foreach($payments as $payed) {
    echo '<b>'.$payed.'</b><br />';
}​​​

编辑2:

这应该可以解决的问题,JS - http://jsfiddle.net/nQakD/上面还更新的代码。

编辑3:

编辑PHP代码和JS代码,因此不会对所有实例的工作- http://jsfiddle.net/nQakD/ 。



Answer 2:

也许做一个新的“四舍五入的平衡”上为每一位用户。 如果是10被分成三部分,那么每个用户将支付3.34。 每个用户也将有一分钱的2/3到他们的舍入平衡。 (这必须被存储为文本我相信)。

下一次同样的事情发生,检查四舍五入的平衡。他们有一分钱的2/3,所以现在你可以把三分之一关闭(所以他们现在在舍入平衡一分钱的1/3),并只收取3.33 。



文章来源: Correct sums with dividing sums, countering rounding errors