Una implementación PHP del algoritmo largest remainder method . Este método es la forma más común de deshacerse de los problemas de redondeo cuando se trabaja con valores porcentuales redondeados.
Supongamos el siguiente ejemplo:
18.562874251497007%
20.958083832335326%
18.562874251497007%
19.161676646706585%
22.75449101796407%
Al redondear los porcentajes anteriores usando las funciones de redondeo de PHP, obtenemos:
19%
21%
19%
19%
23%
Lo que de hecho suma 101%
en lugar de 100%
. El largest remainder method resuelve este problema siguiendo los siguientes pasos:
composer require " kschu91/largest-remainder-method "
Si no está familiarizado con el compositor: uso básico del compositor
$ numbers = [
18.562874251497007 ,
20.958083832335326 ,
18.562874251497007 ,
19.161676646706585 ,
22.75449101796407
];
$ lr = new LargestRemainder ( $ numbers );
print_r ( $ lr -> round ());
lo que resulta en:
Array
(
[0] => 19
[1] => 21
[2] => 18
[3] => 19
[4] => 23
)
La precisión predeterminada se establece en 0
. Pero puedes cambiar este comportamiento usando el 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 ());
lo que resulta en:
Array
(
[0] => 18.56
[1] => 20.96
[2] => 18.56
[3] => 19.16
[4] => 22.76
)
En general, no tienes los números a los que deseas aplicar este algoritmo en una matriz simple como en los ejemplos anteriores. Prefiere tenerlos en objetos o matrices asociativas. Es por eso que esta biblioteca también admite devoluciones de llamadas para aplicar este algoritmo.
Sólo tienes que proporcionar 2 devoluciones de llamada al método usort
. El primero, para recuperar el número relevante del objeto. Y el segundo para escribir el número redondeado en el objeto resultante.
Asegúrese de pasar el primer argumento de la devolución de llamada del configurador como referencia, por ejemplo. como en el siguiente ejemplo:
&$item
. De lo contrario, los datos resultantes mantendrán sus números originales y no se redondearán.
$ 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 ;
}
));
lo que resulta en:
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
)
)