Это зависит от того, какие операции вы собираетесь делать. Пожалуйста, предложите больше информации.
Eversor
@eversor Можете ли вы дать мне описание того, какой тип данных должен использоваться для различных операций?
Questborn
1
Я делаю расчеты, которые требуют от меня, чтобы точно представлять центы.
Questborn
Можете ли вы предсказать самую большую сумму денег, с которой будет работать ваше приложение? И, ваши расчеты, они будут простыми (дополнения и т. Д.) Или более сложными финансовыми операциями?
Eversor
Ответы:
133
У Java есть Currencyкласс, который представляет коды валюты ISO 4217.
BigDecimalлучший тип для представления десятичных значений валюты.
Joda Money предоставила библиотеку для представления денег.
Почему мы не можем использовать вместо этого float или double?
Эрран Морад
20
@Borat Sagdiyev Вот почему . Также вы можете сослаться на это .
Бухаке Синди
2
@Borat: вы можете, если знаете, что делаете, посмотреть эту статью Питера Лоури. но, по крайней мере, такая большая сложность для округления, как использование BigDecimals.
Натан Хьюз
35
«Если бы у меня было десять центов за каждый раз, когда я видел, как кто-то использовал FLOAT для хранения валюты, у меня было бы 999,997634 доллара», - Билл Карвин
Коллин Кроулл
36
Вы можете использовать Money and Currency API (JSR 354) . Вы можете использовать этот API, если вы добавите соответствующие зависимости в ваш проект.
Для Java 8 добавьте следующую ссылочную реализацию в качестве зависимости к вашей pom.xml:
Имейте в виду , что сумма денег может переполнить размер междунар
eversor
5
@ eversor, для которого потребовалось бы более 20 миллионов долларов, большинству приложений не понадобилось бы столько, если бы они работали долго, и этого будет достаточно, поскольку даже наши правительства не обрабатывают достаточно денег, чтобы переполнить это
чокнутый урод
4
@ratchetfreak Наверное, лучше использовать длинный тогда.
Трогнандерс
5
Многие банки обрабатывают гораздо большие суммы денег, чем 20 000 000 долларов каждый день. Это даже не учитывает такие валюты, как иена, с большими курсами обмена доллара. Целочисленные типы могут быть лучше, чтобы избежать проблем округления, хотя они запутываются в расчетах процента и обменного курса. Однако, в зависимости от приложения, вам может понадобиться 64-битный целочисленный тип.
Алхимик
На самом деле, в идеале микродоллары, как, например, если вы делаете, например, $ 10/3, тогда ошибка округления (3333.3 => 3333.0) не оказывает существенного влияния на конечное значение (в этом случае оно вообще не влияет на реальное значение, хотя это опасно предполагать, что этого никогда не будет). Это особенно важно, если вы выполняете много вычислений подряд, прежде чем ваш пользователь увидит результат, так как ошибки округления будут усугубляться.
JSR 354 предоставляет API для представления, транспортировки и выполнения комплексных расчетов с деньгами и валютой. Вы можете скачать его по этой ссылке:
API для обработки, например, денежных сумм и валют
API для поддержки взаимозаменяемых реализаций
Фабрики для создания экземпляров классов реализации
Функциональность для расчетов, конвертации и форматирования денежных сумм
Java API для работы с деньгами и валютами, который планируется включить в Java 9.
Все спецификации классов и интерфейсов находятся в пакете javax.money. *.
Примеры JSR 354: деньги и валюта API:
Пример создания MonetaryAmount и его печати на консоли выглядит следующим образом:
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));
При использовании эталонного API реализации необходимый код намного проще:
MonetaryAmount monetaryAmount =Money.of(12345.67,"EUR");MonetaryAmountFormat format =MonetaryFormats.getAmountFormat(Locale.getDefault());System.out.println(format.format(monetaryAmount));
API также поддерживает вычисления с MonetaryAmounts:
// getting CurrencyUnits by localeCurrencyUnit yen =MonetaryCurrencies.getCurrency(Locale.JAPAN);CurrencyUnit canadianDollar =MonetaryCurrencies.getCurrency(Locale.CANADA);
MonetaryAmount имеет различные методы, которые позволяют получить доступ к назначенной валюте, числовой сумме, ее точности и многим другим:
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;
MonetaryAmounts можно округлить с помощью оператора округления:
Все это хорошо, но, как Федерико предложил выше, это выглядит медленнее, чем BigDecimal :-)) плохая шутка только тогда, но я дам это испытание сейчас, 1 год спустя ...
kensai
6
Вы должны использовать BigDecimal для представления денежных значений. Это позволяет вам использовать различные режимы округления , а в финансовых приложениях режим округления часто является жестким требованием, которое может даже предписываться законом.
Интересно, что я проведу тот же тест с последним материалом на JDK9
kensai
4
Для простого случая (одна валюты) it' достаточно Integer/ Long. Храните деньги в центах (...) или в сотых / тысячных центах (любая точность, которая вам нужна с фиксированным делителем)
Существует множество контейнеров для валюты, но все они используют BigDecimal в качестве базового типа данных. Вы не ошибетесь с BigDecimal, возможно, используя округление BigDecimal.ROUND_HALF_EVEN.
Мне нравится использовать Tiny Types, которые обертывают либо double, BigDecimal, либо int, как предлагали предыдущие ответы. (Я бы использовал двойной, если не возникнут проблемы с точностью).
Tiny Type дает вам безопасность типов, поэтому вы не перепутаете двойные деньги с другими двойниками.
Ответы:
У Java есть
Currency
класс, который представляет коды валюты ISO 4217.BigDecimal
лучший тип для представления десятичных значений валюты.Joda Money предоставила библиотеку для представления денег.
источник
Вы можете использовать Money and Currency API (JSR 354) . Вы можете использовать этот API, если вы добавите соответствующие зависимости в ваш проект.
Для Java 8 добавьте следующую ссылочную реализацию в качестве зависимости к вашей
pom.xml
:Эта зависимость будет транзитивно добавляться
javax.money:money-api
как зависимость.Затем вы можете использовать API:
источник
Интегральный тип, представляющий наименьшее возможное значение. Другими словами, ваша программа должна думать в центах, а не в долларах / евро.
Это не должно мешать вам переводить графический интерфейс обратно в доллары / евро.
источник
Можно использовать BigDecimal , хорошее объяснение того, почему не использовать Float или Double, можно увидеть здесь: почему бы не использовать Double или Float для представления валюты?
источник
JSR 354: деньги и валюта API
JSR 354 предоставляет API для представления, транспортировки и выполнения комплексных расчетов с деньгами и валютой. Вы можете скачать его по этой ссылке:
JSR 354: деньги и валюта API Скачать
Спецификация состоит из следующих вещей:
Примеры JSR 354: деньги и валюта API:
Пример создания MonetaryAmount и его печати на консоли выглядит следующим образом:
При использовании эталонного API реализации необходимый код намного проще:
API также поддерживает вычисления с MonetaryAmounts:
CurrencyUnit и MonetaryAmount
MonetaryAmount имеет различные методы, которые позволяют получить доступ к назначенной валюте, числовой сумме, ее точности и многим другим:
MonetaryAmounts можно округлить с помощью оператора округления:
При работе с коллекциями MonetaryAmounts доступны некоторые полезные вспомогательные методы для фильтрации, сортировки и группировки.
Пользовательские операции MonetaryAmount
Ресурсы:
Обработка денег и валюты на Java с помощью JSR 354
Изучение API денег и валюты Java 9 (JSR 354)
Смотрите также: JSR 354 - Валюта и деньги
источник
Вы должны использовать BigDecimal для представления денежных значений. Это позволяет вам использовать различные режимы округления , а в финансовых приложениях режим округления часто является жестким требованием, которое может даже предписываться законом.
источник
Я бы использовал Joda Money
Это все еще в версии 0.6, но выглядит очень многообещающе
источник
Я сделал микробенчмарк (JMH) для сравнения Moneta (реализация Java JSR 354) с BigDecimal с точки зрения производительности.
Удивительно, но производительность BigDecimal кажется лучше, чем у Moneta. Я использовал следующие настройки Moneta:
org.javamoney.moneta.Money.defaults.precision = 19 org.javamoney.moneta.Money.defaults.roundingMode = HALF_UP
В результате чего
Пожалуйста, не стесняйтесь поправлять меня, если я что-то упустил
источник
Для простого случая (одна валюты) it' достаточно
Integer
/Long
. Храните деньги в центах (...) или в сотых / тысячных центах (любая точность, которая вам нужна с фиксированным делителем)источник
BigDecimal - лучший тип данных для валюты.
Существует множество контейнеров для валюты, но все они используют BigDecimal в качестве базового типа данных. Вы не ошибетесь с BigDecimal, возможно, используя округление BigDecimal.ROUND_HALF_EVEN.
источник
Мне нравится использовать Tiny Types, которые обертывают либо double, BigDecimal, либо int, как предлагали предыдущие ответы. (Я бы использовал двойной, если не возникнут проблемы с точностью).
Tiny Type дает вам безопасность типов, поэтому вы не перепутаете двойные деньги с другими двойниками.
источник