¿Cómo consigo que mis decimales se queden en 2 lugares para representar el dinero usando el módulo decimal
?
He establecido la precisión, y casi todo lo demás, y me encontré con el fracaso.
Cuando trabaje con dinero, generalmente querrá limitar la precisión lo más tarde posible para que cosas como la multiplicación no acumulen errores de redondeo. En Python 2 y 3, puedes .quantize()
un Decimal
con la precisión que desees:
unit_price = decimal.Decimal('8.0107') quantity = decimal.Decimal('0.056') price = unit_price * quantity cents = decimal.Decimal('.01') money = price.quantize(cents, decimal.ROUND_HALF_UP)
La respuesta aceptada es correcta en su mayoría, excepto la constante que se debe utilizar para la operación de redondeo. Debe usar ROUND_HALF_UP
lugar de ROUND_05UP
para las operaciones de divisas. Según los documentos :
decimal. ROUND_HALF_UP
Redondea al más cercano con los lazos que salen de cero
decimal. ROUND_05UP
Redondear fuera de cero si el último dígito después del redondeo hacia cero hubiera sido 0 o 5; De lo contrario, redondea hacia cero.
Usar ROUND_05UP
solo se redondearía (para números positivos) si el número en el lugar de las centésimas era un 5 o un 0, lo que no es correcto para el cálculo de moneda.
Aquí hay unos ejemplos:
>>> from decimal import Decimal, ROUND_05UP, ROUND_HALF_UP >>> cents = Decimal('0.01') >>> Decimal('1.995').quantize(cents, ROUND_HALF_UP) Decimal('2.00') # Correct >>> Decimal('1.995').quantize(cents, ROUND_05UP) Decimal('1.99') # Incorrect >>> Decimal('1.001').quantize(cents, ROUND_HALF_UP) Decimal('1.00') # Correct >>> Decimal('1.001').quantize(cents, ROUND_05UP) Decimal('1.01') # Incorrect
Los falsos progtwigdores creen sobre el dinero:
Una forma de resolver esto es almacenar los valores monetarios en centavos como enteros y solo convertirlos a la representación decimal cuando se imprimen valores. Esto se llama aritmética de punto fijo .
>>> decimal.getcontext().prec = 2 >>> d = decimal.Decimal('2.40') >>> d/17 Decimal('0.14')
Solo tiene que establecer la precisión en 2 (la primera línea) y todos ellos no usarán más de 2 decimales.
Sólo para comparación:
>>> 2.4 / 17 0.1411764705882353