Uma implementação em PHP do algoritmo largest remainder method . Este método é a maneira mais comum de eliminar problemas de arredondamento ao trabalhar com valores percentuais arredondados.
Suponha o seguinte exemplo:
18.562874251497007%
20.958083832335326%
18.562874251497007%
19.161676646706585%
22.75449101796407%
Ao arredondar as porcentagens acima usando as funções de arredondamento do PHP, obtemos:
19%
21%
19%
19%
23%
O que na verdade soma 101% em vez de 100% . O largest remainder method resolve esse problema executando as seguintes etapas:
composer require " kschu91/largest-remainder-method "Se você não está familiarizado com o compositor: uso básico do compositor
$ numbers = [
18.562874251497007 ,
20.958083832335326 ,
18.562874251497007 ,
19.161676646706585 ,
22.75449101796407
];
$ lr = new LargestRemainder ( $ numbers );
print_r ( $ lr -> round ());o que resulta em:
Array
(
[0] => 19
[1] => 21
[2] => 18
[3] => 19
[4] => 23
)
A precisão padrão é definida como 0 . Mas você pode alterar esse comportamento usando o método setPrecision :
$ numbers = [
18.562874251497007 ,
20.958083832335326 ,
18.562874251497007 ,
19.161676646706585 ,
22.75449101796407
];
$ lr = new LargestRemainder ( $ numbers );
$ lr -> setPrecision ( 2 );
print_r ( $ lr -> round ());o que resulta em:
Array
(
[0] => 18.56
[1] => 20.96
[2] => 18.56
[3] => 19.16
[4] => 22.76
)
Principalmente, você não tem os números aos quais deseja aplicar esse algoritmo em uma matriz simples, como nos exemplos acima. Você prefere tê-los em objetos ou matrizes associativas. É por isso que esta biblioteca também suporta retornos de chamada para aplicação deste algoritmo.
Você apenas precisa fornecer 2 retornos de chamada para o método usort . O primeiro, para buscar o número relevante do objeto. E o segundo para escrever o número arredondado de volta no objeto resultante.
Certifique-se de passar o primeiro argumento do retorno de chamada do setter como referência, por exemplo. como no exemplo abaixo:
&$item. Caso contrário, os dados resultantes manterão seus números originais e não serão arredondados.
$ 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 ;
}
));o que resulta em:
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
)
)