Saltar al contenido

Cómo hacer que los porcentajes redondeados sumen 100%

Nuestros programadores estrellas agotaron sus reservas de café, en su búsqueda a tiempo completo por la resolución, hasta que Gerardo halló el arreglo en Gitea y en este momento la comparte contigo.

Solución:

Hay muchas maneras de hacer precisamente esto, siempre que no le preocupe confiar en los datos decimales originales.

El primer método, y quizás el más popular, sería el método del resto más grande.

Que es básicamente:

  1. Redondeando todo hacia abajo
  2. Obteniendo la diferencia en suma y 100
  3. Distribuir la diferencia sumando 1 a los elementos en orden decreciente de sus partes decimales

En tu caso, sería así:

13.626332%
47.989636%
 9.596008%
28.788024%

Si tomas las partes enteras, obtienes

13
47
 9
28

que suma 97, y quieres sumar tres más. Ahora, observa las partes decimales, que son

.626332%
.989636%
.596008%
.788024%

y toma los más grandes hasta que el total llegue a 100. Entonces obtendrías:

14
48
 9
29

Alternativamente, puede simplemente elegir mostrar un lugar decimal en lugar de valores enteros. Entonces, los números serían 48.3 y 23.9, etc. Esto reduciría mucho la varianza de 100.

Probablemente la “mejor” manera de hacer esto (citado ya que “mejor” es un término subjetivo) es mantener un registro continuo (no integral) de dónde se encuentra y redondear ese valor.

Luego, utilícelo junto con el historial para determinar qué valor se debe utilizar. Por ejemplo, usando los valores que diste:

Value      CumulValue  CumulRounded  PrevBaseline  Need
---------  ----------  ------------  ------------  ----
                                  0
13.626332   13.626332            14             0    14 ( 14 -  0)
47.989636   61.615968            62            14    48 ( 62 - 14)
 9.596008   71.211976            71            62     9 ( 71 - 62)
28.788024  100.000000           100            71    29 (100 - 71)
                                                    ---
                                                    100

En cada etapa, no redondeas el número en sí. En cambio, redondeas el acumulado valor y calcule el mejor número entero que alcanza ese valor desde la línea base anterior; esa línea base es el valor acumulativo (redondeado) de la fila anterior.

Esto funciona porque eres no perder información en cada etapa, sino utilizar la información de manera más inteligente. Los valores redondeados “correctos” están en la columna final y puede ver que suman 100.

Puede ver la diferencia entre esto y el redondeo ciego de cada valor, en el tercer valor anterior. Mientras 9.596008 normalmente redondearía a 10el acumulado 71.211976 redondea correctamente a 71 – esto significa que sólo 9 es necesario agregar a la línea de base anterior de 62.


Esto también funciona para secuencias “problemáticas” como tres aproximadamente:1/3 valores, donde uno de ellos deben ser redondeados:

Value      CumulValue  CumulRounded  PrevBaseline  Need
---------  ----------  ------------  ------------  ----
                                  0
33.333333   33.333333            33             0    33 ( 33 -  0)
33.333333   66.666666            67            33    34 ( 67 - 33)
33.333333   99.999999           100            67    33 (100 - 67)
                                                    ---
                                                    100

Dado que ninguna de las respuestas aquí parece resolverlo correctamente, aquí está mi versión semi-ofuscada usando guiones bajos:

function foo(l, target) 
    var off = target - _.reduce(l, function(acc, x)  return acc + Math.round(x) , 0);
    return _.chain(l).
            sortBy(function(x)  return Math.round(x) - x ).
            map(function(x, i)  return Math.round(x) + (off > i) - (i >= (l.length + off)) ).
            value();


foo([13.626332, 47.989636, 9.596008, 28.788024], 100) // => [48, 29, 14, 9]
foo([16.666, 16.666, 16.666, 16.666, 16.666, 16.666], 100) // => [17, 17, 17, 17, 16, 16]
foo([33.333, 33.333, 33.333], 100) // => [34, 33, 33]
foo([33.3, 33.3, 33.3, 0.1], 100) // => [34, 33, 33, 0]

valoraciones y comentarios

Recuerda algo, que te brindamos la opción de decir si te ayudó.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *