Pregunta

Entiendo que BigDecimal es la mejor práctica recomendada para representar valores monetarios en Java. ¿Que usas? ¿Hay alguna biblioteca mejor que prefieras usar?

¿Fue útil?

Solución

BigDecimal hasta el final. He oído hablar de algunas personas que crean sus propias clases Cash o Money que encapsulan un valor en efectivo con la moneda, pero debajo de la piel sigue siendo un BigDecimal , probablemente con BigDecimal.ROUND_HALF_EVEN redondeo.

Editar: Como Don menciona en su respuesta , hay proyectos de código abierto como timeandmoney , y los aplaudo por tratar de evitar que los desarrolladores tengan para reinventar la rueda, simplemente no tengo suficiente confianza en una biblioteca pre-alfa para usarla en un entorno de producción. Además, si cavas debajo del capó, verás usan BigDecimal también .

Otros consejos

Puede ser útil para las personas que llegan aquí por los motores de búsqueda conocer JodaMoney: http: // www .joda.org / joda-money / .

No estoy expresando mi opinión aquí, pero hay argumentos bastante buenos en contra de BigDecimal que probablemente alguien debería tirar:

http://lemnik.wordpress.com/2011 / 03/25 / bigdecimal-and-your-money /

Una biblioteca conveniente con la que me encontré anteriormente es la biblioteca Joda-Money . Una de sus implementaciones está basada en BigDecimal. Se basa en la especificación ISO-4217 para monedas y puede admitir una lista de monedas personalizada (cargada a través de CVS).

Esta biblioteca tiene una pequeña cantidad de archivos que uno puede revisar rápidamente si se necesitan modificaciones. Joda-Money se publica bajo la licencia Apache 2.0.

Si solo usa dólares y centavos, usaría un largo (compensado por 2 decimales). Si necesita más detalles, un gran decimal puede ser el camino a seguir.

De cualquier manera, probablemente extienda la clase para que tenga un .toString () que use el formato correcto, y como un lugar para colocar otros métodos que puedan surgir (durante mucho tiempo, la multiplicación y la división saldrán mal si el decimal no se ajusta)

Además, si usa definir su propia clase e interfaz, puede reemplazar la implementación a voluntad.

BigDecimal u otra representación de punto fijo es lo que generalmente se necesita para obtener dinero.

Las representaciones y cálculos de

coma flotante ( Double , Float ) son inexactos, lo que lleva a resultados erróneos.

Tienes que tener mucho cuidado cuando trabajas con tiempo y dinero.

Cuando trabajas con dinero, espero que todos sepan que nunca debes usar un flotador o un doble.

Pero no estoy seguro acerca de BigDecimal.

En la mayoría de los casos, estará bien si solo realiza un seguimiento de los centavos en un int o largo. De esta manera nunca se trata con un decimal.

Solo muestra dólares cuando lo imprime. Siempre trabaje con centavos internos usando enteros. Esto puede ser complicado si necesita dividir o si necesita usar Math.abs ().

Sin embargo, es posible que le interese medio centavo, o incluso un centésimo de centavo. No sé cuál es una buena manera de hacer esto. Es posible que solo necesite lidiar con la milésima de centavos y usar un largo. O tal vez se verá obligado a usar BigDecimal

Leería mucho más sobre esto, pero ignoraría a todos los que comienzan a hablar de usar una carroza o un doble para representar dinero. Solo están pidiendo problemas.

Siento que mi consejo no está completo, así que ponle más atención. ¡Estás lidiando con tipos peligrosos!

Crear una clase de dinero es el camino a seguir. Usando BigDecimal (o incluso un int) debajo. Luego, utilice la clase de moneda para definir la convención de redondeo.

Desafortunadamente, sin la sobrecarga del operador, Java hace que sea bastante desagradable crear estos tipos básicos.

Hay una mejor biblioteca, timeandmoney . En mi opinión, es muy superior a las bibliotecas proporcionadas por el JDK para representar estos 2 conceptos.

Definitivamente no es BigDecimal. Hay tantas reglas especiales para redondear y presentar que debe preocuparse.

Martin Fowler recomienda la implementación de una clase Money dedicada para representar los montos en moneda, y que también implementa reglas para la conversión de moneda.

Oye, aquí hay un artículo muy interesante sobre BigDecimal, y un ejemplo ilustrativo de por qué a veces se usa en lugar de dobles. Tutorial BigDecimal .

Puede usar la clase DecimalFormat cuando finalmente muestre un valor de moneda. Proporciona soporte de localización y es bastante extensible.

Encapsularía BigDecimal en la clase Money que también tiene una moneda tal como alguien mencionó anteriormente. Lo importante es que realice una cantidad extrema de pruebas unitarias y especialmente si trabaja con monedas diferentes. También es una buena idea si agrega un constructor conveniente que toma una cadena o un método de fábrica que hace lo mismo para que pueda escribir sus pruebas de esta manera:

   assertEquals(Money.create("100.0 USD").add("10 GBP"),Money.create("116 USD"));

Siempre hay restricciones y detalles involucrados. Cualquier persona sin suficiente experiencia para apreciar los sutiles problemas descritos en el siguiente artículo debe reconsiderar seriamente antes de tratar con datos financieros del mundo real:

http://lemnik.wordpress.com/2011/ 25/03 / bigdecimal-and-your-money

BigDecimal no es la única representación correcta o la única pieza del rompecabezas. Dadas ciertas condiciones, usar una clase Money respaldada por centavos almacenados como un entero podría ser suficiente y sería mucho más rápido que BigDecimal. Sí, eso implica el uso de dólares como moneda y cantidades limitadas, pero tales restricciones son perfectamente aceptables para muchos casos de uso y todas las monedas tienen casos especiales para redondear y sub-denominaciones de todos modos, por lo que no hay un universal. solución.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top