Является ли BigDecimal излишним в некоторых случаях?
Я работаю с деньгами, поэтому мне нужно, чтобы мои результаты были точными, но мне нужна точность в 2 десятичных пункта (цента). Требуется ли BigDecimal для гарантирования результатов умножения/деления?
Ответы
Ответ 1
BigDecimal является очень подходящим типом для арифметики десятичных дробей с известным числом цифр после десятичной точки. Вы можете использовать целочисленный тип и отслеживать мультипликатор самостоятельно, но это включает в себя работу с кодом, которая может быть автоматизирована.
Также, как и управление цифрами после десятичной точки, BigDecimal также будет увеличивать количество сохраненных цифр по мере необходимости - многие финансовые и финансовые расчеты в бизнесе включают слишком большие суммы для хранения в центах в int.
Я бы предпочел избежать этого, только если вам нужно хранить очень большой массив сумм и не хватает памяти.
Ответ 2
Одним из распространенных вариантов является выполнение всех ваших вычислений с помощью integer или long (значение центов), а затем просто добавьте два десятичных знака, когда вам нужно отобразить его.
Аналогично, есть библиотека JODA Money, которая даст вам более полнофункциональный API для расчета денег.
Ответ 3
Это зависит от вашего приложения. Одной из причин использования этого уровня точности является предотвращение переполнения ошибок, накопленных во многих операциях, и выпадение ценной информации. Если вы создаете случайное приложение и/или используете его, например, для ввода данных, BigDecimal, скорее всего, будет излишним.
Ответ 4
+1 для Patricias ответ, но я очень сильно препятствую любому реализовать собственные классы с целым типом данных с фиксированной длиной бит, если кто-то действительно не знает, что вы делаете. BigDecimal поддерживает все проблемы округления и точности, а long/int имеет серьезные проблемы:
-
Неизвестное количество цифр: торговые биржи/право/торговля варьируются в зависимости от их количества
дробных цифр, поэтому вы не знаете, должно ли ваше выбранное количество цифр быть изменено и
скорректированные в будущем. Хуже: Есть некоторые вещи, такие как оценка запасов, которые требуют смехотворного количества дробных цифр. Корабль с 1000 метрическими тоннами угля вызывает, например,
4,12 евро - стоимость льда, что составляет 0,000412 €/т.
-
Не реализуемые операции: это означает, что люди, скорее всего, будут использовать с плавающей запятой для
округление/деление или другие арифметические операции, скрывающие неточность и приводящие к
все известные проблемы арифметики с плавающей запятой.
-
Переполнение/Недополнение: после достижения максимальной суммы добавление суммы приводит к изменению знака. Long.MAX_VALUE переключается на Long.MIN_VALUE. Это может легко произойти, если вы делаете такие фракции, как (a * b * c * d)/(e * f), которые могут иметь вполне допустимые результаты в диапазоне длинного, но промежуточный номинант или знаменатель этого не делает.
Ответ 5
Вы можете написать свой собственный класс Currency
, используя long
для хранения суммы. Методы класса будут устанавливать и получать сумму с помощью String
.
Отдел будет заботиться независимо от того, используете ли вы long
или BigDecimal
. Вы должны в каждом конкретном случае определить, что вы делаете с дробными центами. Откажитесь от них, вокруг них или сохраните их (где-то помимо вашей собственной учетной записи).