用除法和纠正正确的和,以消除舍入误差 [英] Correct sums with dividing sums, countering rounding errors

查看:125
本文介绍了用除法和纠正正确的和,以消除舍入误差的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用MySQL数据库用PHP编码的Web应用.

我有一个系统,可以在划分成本时为多个人计算不同的成本.例如,人员A 买了10块东西,而人员B,C和D 应该分摊费用.

I have a system which calculates different costs for a number of people when splitting a cost. For example Person A buys something for 10 and Persons B, C, and D should split the cost.

为此,系统应为人A 记录10个正记录,而对 B,C和D记录10/3的负记录.

The system should therefor register a positive record for person A of 10 and negative records of 10/3 for B, C and D.

但是,当完成时;四舍五入后, B,C和D 均为-3.33.当然,总数中的哪个不加?解决此问题的最佳方法是什么?最佳解决方案将使获得的人的花费也稍大一些.

However, when this is done; B, C and D all have -3.33 after rounding. Which of course doesn't add up to the total of 10. What's the best way of going about this problem? An optimal solution would randomise what person get's the slightly bigger cost as well.

一个可能的解决方案是,如果我只让最后一个人的债务为10 - (A + B),但是如果四个人分摊成本(例如13.34),就会出现问题.这样,不同的部分将是3.34、3.34、3.34和3.32,而最佳分割将是3.34、3.34、3.33、3.33.

One possible solution is if I just let the last person's debt be 10 - (A + B), but then there's a problem if four persons split a cost of for example 13.34. The different parts would then be 3.34, 3.34, 3.34 and 3.32, whereas the optimal split would be 3.34, 3.34, 3.33, 3.33.

有些人可能会争辩说,使用足够的小数,这仅在具有大量行的情况下才是问题.但是,我认为在经济的系统中,即使从一开始就具有 fail-safe 的系统很重要.它必须是可缩放的,并且甚至不会有丝毫的错误. 不公平没事,只是没有错误.

Some might argue that with sufficient decimals this is only a problem when having vast amounts of rows. But in an economical system I think it's important to have a fail-safe system even from the start. It needs to be scalable, and can't have even the slightest error. Unfairness is alright, just not errors.

类似问题:总和分数值问题(处理舍入错误)

推荐答案

这似乎可行- http://jsfiddle. net/nQakD/.

以jQuery为例,但是如果您了解PHP,则应该可以轻松将其转换为PHP.如果您还需要php代码,请告诉我,我会为您编写.

Used jQuery as example, but if you know PHP you should be able to easily convert it to PHP. If you need also php code, tell me, I will wrote it for you.

我也会在此处粘贴代码-

I'll paste the code here also -

$(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代码-

And here is working php code -

$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 />';
}​​​

这应该可以解决js问题- http://jsfiddle.net/nQakD/也在上面更新了代码

This should fix the js issue - http://jsfiddle.net/nQakD/ updated code above also.

编辑了PHP代码和JS代码,因此它适用于所有示例- http://jsfiddle.net/nQakD/.

Edited PHP code and JS code so it does work for all examples - http://jsfiddle.net/nQakD/ .

这篇关于用除法和纠正正确的和,以消除舍入误差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆