Я розумію, що BigDecimal рекомендується найкращою практикою для представлення грошових цінностей на Java. Що ви використовуєте? Чи є краща бібліотека, яку ви віддаєте перевагу використовувати натомість?
Я розумію, що BigDecimal рекомендується найкращою практикою для представлення грошових цінностей на Java. Що ви використовуєте? Чи є краща бібліотека, яку ви віддаєте перевагу використовувати натомість?
Відповіді:
BigDecimal
всю дорогу. Я чув про те, що деякі люди створюють власні курси Cash
або Money
класи, в яких інкапсулюється грошова вартість із валютою, але під шкірою це все одно BigDecimal
, можливо, з BigDecimal.ROUND_HALF_EVEN
округленням.
Редагувати: Як згадує Дон у своїй відповіді , існують проекти з відкритим джерелом, такі як timeandmoney , і хоча я аплодую їм за те, що вони намагаються перешкодити розробникам заново винаходити колесо, я просто не маю достатньої впевненості в бібліотеці пре-альфа для використання це у виробничому середовищі. Крім того, якщо ви покопаєтесь під капотом, ви побачите, що вони BigDecimal
теж використовують .
Людям, які прибувають сюди за допомогою пошукових систем, може бути корисно дізнатися про JodaMoney: http://www.joda.org/joda-money/ .
BigDecimal
під капотом!
Я тут не висловлюю свою думку, але є досить вагомі аргументи проти BigDecimal, які, мабуть, хтось повинен викинути:
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money/
Зручною бібліотекою, з якою я зіткнувся раніше, є бібліотека Joda-Money . Одна з його реалізацій справді базується на BigDecimal. Він заснований на специфікації ISO-4217 для валют і може підтримувати спеціальний список валют (завантажується через CVS).
Ця бібліотека має невелику кількість файлів, які можна швидко переглянути, якщо потрібні зміни. Joda-Money видається під ліцензією Apache 2.0.
Якщо ви просто використовуєте долари та центи, я б використовував лонг (компенсований на 2 знаки після коми). Якщо вам потрібні докладніші відомості, може знадобитися великий десятковий знак.
У будь-якому випадку, я б, напевно, розширив клас, щоб мати .toString (), який використовує правильний формат, і як місце, де можна розмістити інші методи, які можуть виникнути (Довгий час множення і ділення підуть не так, якщо десяткове значення isn не відрегульовано)
Крім того, якщо ви використовуєте визначення власного класу та інтерфейсу, ви можете замінити реалізацію за бажанням.
BigDecimal
або інше подання з фіксованою точкою - це те, що зазвичай потрібно для грошей.
Подання та обчислення з плаваючою точкою ( Double
, Float
) неточні, що призводить до помилкових результатів.
Ви повинні бути настільки обережними, маючи справу з часом і грошима.
Коли ви працюєте з грошима, я сподіваюся, що всі повинні знати, що ніколи не використовувати поплавок або дубль.
Але я не впевнений щодо BigDecimal.
У більшості випадків вам буде добре, якщо ви просто будете відстежувати центи в int або long. Таким чином ви ніколи не маєте справу з десятковою комою.
Ви відображаєте долари лише тоді, коли їх друкуєте. Завжди працюйте з центрами, використовуючи цілі числа. Це може бути складно, якщо потрібно розділити або використовувати Math.abs ().
Тим не менш, ти можеш піклуватися про піввідсотка, а то й про соту відсоток. Я не знаю, який хороший спосіб це зробити. Можливо, вам просто доведеться мати справу з тисячною копійкою і використовувати довгу. Або, можливо, вас змусять використовувати BigDecimal
Я б набагато більше читав про це, але ігнорував усіх, хто починає говорити про використання поплавка або дубля для представлення грошей. Вони просто просять неприємностей.
Я вважаю, що моя порада не є повною, тому, будь ласка, вкладіть більше. Ви маєте справу з небезпечними типами!
Є краща бібліотека, час і гроші . IMO значно перевершує бібліотеки, надані JDK для представлення цих 2 концепцій.
Однозначно не BigDecimal. Існує стільки спеціальних правил для округлення та подання, що вам доведеться турбуватися.
Мартін Фаулер рекомендує застосовувати виділений клас Money для представлення сум валют, а також реалізує правила конвертації валют.
Гей, ось дуже цікава стаття про BigDecimal та наочний приклад того, чому іноді її використовують замість подвійних. Підручник з BigDecimal .
Ви можете використовувати клас DecimalFormat, коли в кінцевому підсумку відображаєте значення валюти. Він забезпечує підтримку локалізації та є досить розширюваним.
Я б інкапсулював BigDecimal у клас Money, який також має валюту, як хтось згаданий вище. Важливо те, що ви проводите надзвичайно багато одиничних тестів, особливо якщо працюєте з різними валютами. Крім того, це гарна ідея, якщо ви додасте зручний конструктор, який бере рядок, або фабричний метод, який робить те саме, щоб ви могли написати свої тести приблизно так:
assertEquals(Money.create("100.0 USD").add("10 GBP"),Money.create("116 USD"));
Завжди є обмеження та особливості. Кожен, хто не має достатнього досвіду, щоб оцінити тонкі питання, викладені в наступній статті, повинен серйозно переглянути, перш ніж мати справу з реальними фінансовими даними:
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money
BigDecimal навряд чи є єдиним правильним поданням чи єдиною частиною головоломки. За певних умов використання класу Money, підтриманого центами, що зберігається як ціле число, може бути достатнім та набагато швидшим, ніж BigDecimal. Так, це передбачає використання доларів як валюти та обмежує суми, але такі обмеження є цілком прийнятними для багатьох випадків використання, і всі валюти в будь-якому випадку мають особливі випадки для округлення та суб-номіналів, тому немає "універсального" рішення.