Pregunta

Tengo que escribir una rutina de contabilidad para un programa que estoy construyendo que me dará una división incluso de un número decimal por un número entero. Así que, por ejemplo:

$143.13 / 5 =

28.62
28.62
28.63
28.63
28.63

He visto el artículo aquí: dividen uniformemente en c # , pero parece que se sólo funciona para las divisiones de números enteros. Cualquier idea de una solución elegante a este problema?

¿Fue útil?

Solución

Calcular la cantidad a la vez, y restar cada cantidad del total para asegurarse de que siempre tiene la izquierda total correcto:

decimal total = 143.13m;
int divider = 5;
while (divider > 0) {
  decimal amount = Math.Round(total / divider, 2);
  Console.WriteLine(amount);
  total -= amount;
  divider--;
}

resultado:

28,63
28,62
28,63
28,62
28,63

Otros consejos

Puede resolver esto (en centavos) sin construir una matriz:

int a = 100 * amount;
int low_value = a / n;
int high_value = low_value + 1;
int num_highs = a % n;
int num_lows = n - num_highs;

Es más fácil tratar con centavos. Yo sugeriría que en vez de 143.13, se divide 14313 en 5 partes iguales. Que le da 2862 y un resto de 3. Usted puede asignar este resto a las tres primeras partes o de cualquier forma que desee. Por último, convertir los centavos a dólares.

También se nota que siempre obtendrá un resto menor que el número de piezas que desee.

En primer lugar, asegúrese de que usted no utiliza un número de coma flotante para representar dólares y centavos (ver otros mensajes de por qué, pero la simple razón es que no todos los números decimales pueden representarse como flotadores, por ejemplo, $ 1,79) .

Aquí hay una manera de hacerlo:

decimal total = 143.13m;
int numberOfEntries = 5;
decimal unadjustedEntryAmount = total / numberOfEntries;
decimal leftoverAmount = total - (unadjustedEntryAmount * numberOfEntries);
int numberOfPenniesToDistribute = leftoverAmount * 100;
int numberOfUnadjustedEntries = numberOfEntries - numberOfPenniesToDistribute;

Así que ahora usted tiene las cantidades no ajustadas de 28.62, y entonces usted tiene que decidir cómo distribuir el resto. Usted puede distribuir un centavo extra a cada uno, comenzando en la parte superior o en la parte inferior (parece que quiere de la parte inferior).

for (int i = 0; i < numberOfUnadjustedEntries; i++) {
  Console.WriteLine(unadjustedEntryAmount);
}

for (int i = 0; i < numberOfPenniesToDistribute; i++) {
  Console.WriteLine(unadjustedEntryAmount + 0.01m);
}

También puede añadir todo el resto a las primeras o las últimas entradas. Por último, dependiendo de las necesidades de contabilidad, usted podría también crear una transacción separada para el resto.

Si usted tiene un flotador que está garantizado exactamente dos dígitos de precisión, lo que acerca de esto (pseudocódigo):

amount = amount * 100 (convert to cents)
int[] amounts = new int[divisor]
for (i = 0; i < divisor; i++) amounts[i] = amount / divisor
extra = amount % divisor
for (i = 0; i < extra; i++) amounts[i]++

y luego hacer lo que quiera con amounts, que está en centavos -. Se podría convertir de nuevo a los flotadores si tenía absolutamente a, o formato que dólares y centavos

Si no está claro, el punto de todo esto no es sólo para dividir un valor flotante de manera uniforme, sino para dividir una cantidad monetaria lo más uniformemente posible, dado que los centavos son una unidad indivisible de dólares. Para el PO: quisiera saber si esto no es lo que quería

.

Puede utilizar el algoritmo de la pregunta que está haciendo referencia por multipling por 100, utilizando el número entero función uniformemente dividir y luego dividiendo cada uno de los resultados por 100 (suponiendo que sólo desea manejar 2 DP, si quieres 3dp múltiple por 1000 etc)

También es posible utilizar la generación C # iterador para hacer la respuesta de Guffa más conveniente:

public static IEnumerable<decimal> Divide(decimal amount, int numBuckets)
{
    while(numBuckets > 0)
    {
        // determine the next amount to return...
        var partialAmount = Math.Round(amount / numBuckets, 2);
        yield return partialAmount;
        // reduce th remaining amount and #buckets
        // to account for previously yielded values
        amount -= partialAmount;
        numBuckets--;
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top