algorithm - resueltos - punto flotante metodos numericos
¿Estrategias comunes para lidiar con errores de redondeo en soft-intensive-soft? (6)
Nunca almacene valores monetarios en un doble o flotante: use un int
o long
ya que no hay forma de almacenar 0.1 con precisión en binario.
¿Cuál es su consejo sobre:
- compensación del error acumulado en operaciones matemáticas masivas en colecciones de objetos Money. ¿Cómo se implementa esto en su código de producción para su localidad?
- teoría detrás del redondeo en la contabilidad.
- cualquier literatura sobre el tema.
Actualmente leo Fowler . Menciona Money type, su estructura típica (int, long, BigDecimal), pero no dice nada sobre estrategias.
Las publicaciones más antiguas sobre redondeo de dinero ( aquí y aquí ) no brindan los detalles y la formalidad que necesito.
Los pensamientos que encontré en el inet se refieren a "Round half even" como la mejor forma de equilibrar el error.
Gracias por la ayuda.
Usa el redondeo del banquero. Usted redondea al penique más cercano.
http://www.xbeat.net/vbspeed/i_BankersRounding.htm
Puede ampliar esto para redondear toward
el penique más cercano. Así que 22.5 rondas a 22, pero 23.5 rondas a 24. 23.1 y 22.9 ambas redondean a 23. Sin embargo, el algoritmo original del banquero es más popular.
Hay muchos problemas de redondeo cuando se registran datos financieros. El primer problema es la capacidad de almacenar y recuperar números decimales exactos
- la mayoría de las bases de datos ofrecen tipos de datos decimales en los que puede especificar el número de dígitos antes y después del punto decimal (las monedas también varían en número de dígitos decimales, he manejado monedas con 0, 2, 3 dígitos decimales)
- Al tratar con estos datos y desea evitar cualquier error de redondeo inesperado en el lado de la aplicación, puede utilizar BCD como enfoque genérico, o puede usar enteros para representar cualquier notación decimal fija o mezclar su propio
Si se resuelve este primer problema, entonces ninguna adición (o substracción) puede introducir ningún error de redondeo. Lo mismo ocurre con la multiplicación por número entero.
El segundo problema, después de que pueda almacenar y recuperar datos sin pérdida de información, se esperan errores de redondeo debido a la división (o multiplicación por no enteros).
Por ejemplo, si su formato de moneda permite 2 decimales y desea almacenar la transacción que los registros equilibran un débito de 10 a 3 piezas iguales, solo puede almacenarlo como
10.00
-3.33
-3.33
-3.33
y
-0.01
(error de redondeo)
Este es un problema esperado que ocurrirá independientemente de la opción de almacenamiento de tipo de datos y que debe tenerse en cuenta si desea que sus cuentas se equilibren. Esta situación se presenta principalmente por división (o por multiplicación por no enteros que tienen muchos dígitos significativos).
Una forma de resolver esto es verificar si sus datos se equilibran después de dichas operaciones y reconocer la diferencia de redondeo permitida en lugar de una situación de error.
EDITAR: En cuanto a las referencias a la literatura, esta parece interesante y no demasiado larga y se refiere a una audiencia bastante amplia con escenarios interesantes.
He trabajado un poco (solo un poco) con montos monetarios y tenía mucha curiosidad sobre la estrategia utilizada en mi empresa ...
Resulta que utilizamos el double
, pero lo han pensado.
El problema es que las cantidades con las que lidiamos no son tan buenas (digamos menos de 10k) y como mucho necesitamos 3 dígitos después del decimal, para un total de 7 dígitos significativos.
Dado que estamos usando software de 64 bits (y C ++), el tipo double
ofrece suficientes dígitos significativos para la cantidad de operaciones que realizamos :)
Si necesita más precisión, hay algoritmos para usar (por ejemplo, al agregar varios dineros) pero, personalmente, creo que el corazón del problema proviene más de:
- Conversión de un dinero a otro, que cambia por supuesto
- problemas de impresión, con algunos dineros que no requieren decimal, otros requieren 2 como máximo, etc.
¿Tal vez podrías expandir las operaciones que estás haciendo?
Lo que debe hacer puede estar bien informado por las convenciones del mercado o la jurisdicción en la que está operando. Por ejemplo, la fijación de precios de los bonos en el mercado australiano requiere que redondee ciertas operaciones intermedias a 8 decimales. El precio final se cotiza a un número específico de decimales (3 creo que fuera de mi cabeza).
Si está tratando con una aplicación de contabilidad, esperaría que las normas de contabilidad relevantes para su entorno legal posiblemente dicten esto.
Todo depende de la aplicación. Es de esperar que no haya demasiadas situaciones en las que se requiera el redondeo. Por ejemplo, transferir dinero de una cuenta a otra no requiere redondeo.
Para las situaciones en las que se requiere redondeo, realmente no importa lo que haga siempre que elija una política, la comunique y la respete. Por ejemplo, creo que el interés en mi cuenta de ahorros se redondea al centavo más cercano.