kschu91/largest-remainder-method

此包的最新版本(v1.1)没有提供许可信息。

最大余数法算法的PHP实现。这种方法是在处理四舍五入的百分比值时消除舍入问题的最常见方式。

v1.1 2022-01-10 17:00 UTC

This package is auto-updated.

Last update: 2024-09-24 14:06:15 UTC


README

Build Status Code Coverage Scrutinizer Code Quality

最大余数法算法

最大余数法算法的PHP实现。这种方法是在处理四舍五入的百分比值时消除舍入问题的最常见方式。

问题

假设以下示例

18.562874251497007%
20.958083832335326%
18.562874251497007%
19.161676646706585%
22.75449101796407%

使用PHP的舍入函数对上述百分比进行舍入时,我们得到

19%
21%
19%
19%
23%

实际上总和为101%而不是100%。最大余数法通过以下步骤解决这个问题:

  1. 将所有值舍入到最接近的整数
  2. 确定舍入值总和与总值的差值
  3. 按小数部分降序分配舍入值之间的差值

安装

composer require "kschu91/largest-remainder-method"

如果您不熟悉composer: composer基本用法

要求

  • PHP >= 7.3

基本用法

$numbers = [
    18.562874251497007,
    20.958083832335326,
    18.562874251497007,
    19.161676646706585,
    22.75449101796407
];

$lr = new LargestRemainder($numbers);

print_r($lr->round());

结果是

Array
(
    [0] => 19
    [1] => 21
    [2] => 18
    [3] => 19
    [4] => 23
)

处理小数或精度

默认精度设置为0。但您可以通过使用setPrecision方法更改此行为

$numbers = [
    18.562874251497007,
    20.958083832335326,
    18.562874251497007,
    19.161676646706585,
    22.75449101796407
];

$lr = new LargestRemainder($numbers);
$lr->setPrecision(2);

print_r($lr->round());

结果是

Array
(
    [0] => 18.56
    [1] => 20.96
    [2] => 18.56
    [3] => 19.16
    [4] => 22.76
)

处理复杂数组/对象

通常,您不会像上述示例那样在简单数组中应用此算法所需的数字。您更有可能将它们放在对象或关联数组中。这就是为什么这个库也支持回调以应用此算法。

您只需向usort方法提供两个回调函数。第一个用于从对象中获取相关数字。第二个用于将舍入数字写回结果对象。

请确保将设置回调函数的第一个参数作为引用传递,例如在下面的示例中:&$item。如果不这样做,结果数据将保留其原始数字,并且不会进行舍入。

$objects = [
    ['a' => 18.562874251497007],
    ['a' => 20.958083832335326],
    ['a' => 18.562874251497007],
    ['a' => 19.161676646706585],
    ['a' => 22.75449101796407]
];

$lr = new LargestRemainder($objects);
$lr->setPrecision(2);

print_r($lr->uround(
    function ($item) {
        return $item['a'];
    },
    function (&$item, $value) {
        $item['a'] = $value;
    }
));

结果是

Array
(
    [0] => Array
        (
            [a] => 18.55
        )

    [1] => Array
        (
            [a] => 20.94
        )

    [2] => Array
        (
            [a] => 18.55
        )

    [3] => Array
        (
            [a] => 19.15
        )

    [4] => Array
        (
            [a] => 22.74
        )

)