Depende de las operaciones que va a hacer. Por favor ofrezca más información.
eversor
@eversor ¿Puede darme una descripción de qué tipo de datos debe usarse para diferentes operaciones?
questborn
1
Estoy haciendo cálculos que me obligan a representar centavos con precisión.
questborn
¿Puede predecir la mayor cantidad de dinero que su aplicación necesitará manejar? Y, según sus cálculos, ¿serán operaciones financieras simples (adiciones, etc.) o más complejas?
eversor
Respuestas:
133
Java tiene una Currencyclase que representa los códigos de moneda ISO 4217.
BigDecimales el mejor tipo para representar valores decimales de moneda.
Joda Money ha proporcionado una biblioteca para representar el dinero.
@Borat: puedes saber si sabes lo que estás haciendo, ver este artículo de Peter Lawrey. pero parece al menos una molestia tan grande hacer todo el redondeo como usar BigDecimals.
Nathan Hughes
35
"Si tuviera un centavo por cada vez que he visto a alguien usar FLOAT para almacenar divisas, tendría $ 999.997634" - Bill Karwin
Collin Krawll
36
Puede usar la API de dinero y divisas (JSR 354) . Puede usar esta API, siempre que agregue las dependencias apropiadas a su proyecto.
Para Java 8, agregue la siguiente implementación de referencia como una dependencia a su pom.xml:
Tenga en cuenta que la cantidad de dinero que puede desbordar el tamaño de int
Eversor
55
@eversor que necesitaría más de 20 millones de dólares la mayoría de las aplicaciones no necesitan mucho si lo hacen mucho será suficiente como ni siquiera nuestros govenrments manejan el dinero de C suficiente para que el desbordamiento
trinquete monstruo
44
@ratchetfreak Probablemente mejor usar un largo entonces.
trognanders
55
Muchos bancos manejan sumas de dinero mucho mayores que $ 20,000,000 cada día. Esto ni siquiera tiene en cuenta monedas como el yen con grandes tipos de cambio por dólar. Los tipos enteros pueden ser mejores para evitar problemas de redondeo, aunque se complican con los cálculos de interés y tipo de cambio. Sin embargo, dependiendo de la aplicación, es posible que necesite un tipo entero de 64 bits.
Alchymist
Idealmente, los microdólares, en realidad, como entonces, si lo hace, por ejemplo, $ 10/3, entonces el error de redondeo (3333.3 => 3333.0) no afecta tanto el valor final (en este caso no afecta el valor real en absoluto, aunque es peligroso asumir que nunca lo hará). Esto es especialmente importante si está haciendo muchos cálculos seguidos antes de que su usuario vea el resultado, ya que los errores de redondeo se agravarán.
Una API para manejar, por ejemplo, montos monetarios y monedas
API para soportar implementaciones intercambiables
Fábricas para crear instancias de las clases de implementación
Funcionalidad para cálculos, conversión y formateo de importes monetarios.
API de Java para trabajar con dinero y monedas, que se planea incluir en Java 9.
Todas las clases e interfaces de especificación se encuentran en el paquete javax.money. *.
Ejemplos de ejemplo de JSR 354: API de dinero y divisas:
Un ejemplo de crear una MonetaryAmount e imprimirlo en la consola se ve así:
MonetaryAmountFactory<?> amountFactory =Monetary.getDefaultAmountFactory();MonetaryAmount monetaryAmount = amountFactory.setCurrency(Monetary.getCurrency("EUR")).setNumber(12345.67).create();MonetaryAmountFormat format =MonetaryFormats.getAmountFormat(Locale.getDefault());System.out.println(format.format(monetaryAmount));
Cuando se usa la API de implementación de referencia, el código necesario es mucho más simple:
MonetaryAmount monetaryAmount =Money.of(12345.67,"EUR");MonetaryAmountFormat format =MonetaryFormats.getAmountFormat(Locale.getDefault());System.out.println(format.format(monetaryAmount));
La API también admite cálculos con MonetaryAmounts:
// getting CurrencyUnits by localeCurrencyUnit yen =MonetaryCurrencies.getCurrency(Locale.JAPAN);CurrencyUnit canadianDollar =MonetaryCurrencies.getCurrency(Locale.CANADA);
MonetaryAmount tiene varios métodos que permiten acceder a la moneda asignada, la cantidad numérica, su precisión y más:
MonetaryAmount monetaryAmount =Money.of(123.45, euro);CurrencyUnit currency = monetaryAmount.getCurrency();NumberValue numberValue = monetaryAmount.getNumber();int intValue = numberValue.intValue();// 123double doubleValue = numberValue.doubleValue();// 123.45long fractionDenominator = numberValue.getAmountFractionDenominator();// 100long fractionNumerator = numberValue.getAmountFractionNumerator();// 45int precision = numberValue.getPrecision();// 5// NumberValue extends java.lang.Number. // So we assign numberValue to a variable of type NumberNumber number = numberValue;
Las cantidades monetarias se pueden redondear utilizando un operador de redondeo:
Todo esto está muy bien, pero a medida que Federico se sugirió anteriormente, parece más lento que BigDecimal :-)) mala broma sólo entonces, pero voy a darle probar ahora 1 año después ...
kensai
6
Debe usar BigDecimal para representar valores monetarios. Le permite usar una variedad de modos de redondeo , y en aplicaciones financieras, el modo de redondeo es a menudo un requisito difícil que incluso puede ser obligatorio por ley.
Interesante, haré la misma prueba con las últimas cosas en JDK9
kensai
4
Para un caso simple (una moneda) es suficiente Integer/ Long. Mantenga el dinero en centavos (...) o en centésimas / milésimas de centavo (cualquier precisión que necesite con un divisor fijo)
BigDecimal es el mejor tipo de datos para usar para la moneda.
Hay muchos contenedores para la moneda, pero todos usan BigDecimal como el tipo de datos subyacente. No se equivocará con BigDecimal, probablemente con el redondeo BigDecimal.ROUND_HALF_EVEN.
Me gusta usar los tipos pequeños que envolvería un doble, BigDecimal o int como las respuestas anteriores han sugerido. (Usaría un doble a menos que surjan problemas de precisión).
Un Tipo Diminuto le brinda seguridad de tipo para que no confunda un doble dinero con otros dobles.
Respuestas:
Java tiene una
Currency
clase que representa los códigos de moneda ISO 4217.BigDecimal
es el mejor tipo para representar valores decimales de moneda.Joda Money ha proporcionado una biblioteca para representar el dinero.
fuente
Puede usar la API de dinero y divisas (JSR 354) . Puede usar esta API, siempre que agregue las dependencias apropiadas a su proyecto.
Para Java 8, agregue la siguiente implementación de referencia como una dependencia a su
pom.xml
:Esta dependencia se agregará transitivamente
javax.money:money-api
como una dependencia.Luego puede usar la API:
fuente
Un tipo integral que representa el valor más pequeño posible. En otras palabras, su programa debería pensar en centavos, no en dólares / euros.
Esto no debería impedir que la interfaz gráfica lo traduzca nuevamente a dólares / euros.
fuente
Se puede usar BigDecimal, aquí se puede ver una buena explicación de por qué no usar Float o Double: ¿Por qué no usar Double o Float para representar la moneda?
fuente
JSR 354: API de dinero y divisas
JSR 354 proporciona una API para representar, transportar y realizar cálculos completos con Money and Currency. Puedes descargarlo desde este enlace:
JSR 354: Descarga de API de dinero y divisas
La especificación consta de lo siguiente:
Ejemplos de ejemplo de JSR 354: API de dinero y divisas:
Un ejemplo de crear una MonetaryAmount e imprimirlo en la consola se ve así:
Cuando se usa la API de implementación de referencia, el código necesario es mucho más simple:
La API también admite cálculos con MonetaryAmounts:
CurrencyUnit y MonetaryAmount
MonetaryAmount tiene varios métodos que permiten acceder a la moneda asignada, la cantidad numérica, su precisión y más:
Las cantidades monetarias se pueden redondear utilizando un operador de redondeo:
Al trabajar con colecciones de Montos Monetarios, hay disponibles algunos buenos métodos de utilidad para filtrar, ordenar y agrupar.
Operaciones de Monto Monetario Personalizado
Recursos:
Manejo de dinero y monedas en Java con JSR 354
Analizando la API de dinero y moneda de Java 9 (JSR 354)
Ver también: JSR 354 - Moneda y dinero
fuente
Debe usar BigDecimal para representar valores monetarios. Le permite usar una variedad de modos de redondeo , y en aplicaciones financieras, el modo de redondeo es a menudo un requisito difícil que incluso puede ser obligatorio por ley.
fuente
Yo usaría Joda Money
Todavía está en la versión 0.6 pero parece muy prometedor
fuente
He hecho un microbenchmark (JMH) para comparar Moneta (implementación de JSR 354 en moneda java) con BigDecimal en términos de rendimiento.
Sorprendentemente, el rendimiento de BigDecimal parece ser mejor que el de moneta. He usado la siguiente configuración de moneta:
org.javamoney.moneta.Money.defaults.precision = 19 org.javamoney.moneta.Money.defaults.roundingMode = HALF_UP
Resultando en
Por favor, siéntase libre de corregirme si me falta algo
fuente
Para un caso simple (una moneda) es suficiente
Integer
/Long
. Mantenga el dinero en centavos (...) o en centésimas / milésimas de centavo (cualquier precisión que necesite con un divisor fijo)fuente
BigDecimal es el mejor tipo de datos para usar para la moneda.
Hay muchos contenedores para la moneda, pero todos usan BigDecimal como el tipo de datos subyacente. No se equivocará con BigDecimal, probablemente con el redondeo BigDecimal.ROUND_HALF_EVEN.
fuente
Me gusta usar los tipos pequeños que envolvería un doble, BigDecimal o int como las respuestas anteriores han sugerido. (Usaría un doble a menos que surjan problemas de precisión).
Un Tipo Diminuto le brinda seguridad de tipo para que no confunda un doble dinero con otros dobles.
fuente