Rozumiem, że BigDecimal jest zalecaną najlepszą praktyką przedstawiania wartości pieniężnych w Javie. Czego używasz? Czy jest lepsza biblioteka, z której wolisz korzystać?
Rozumiem, że BigDecimal jest zalecaną najlepszą praktyką przedstawiania wartości pieniężnych w Javie. Czego używasz? Czy jest lepsza biblioteka, z której wolisz korzystać?
Odpowiedzi:
BigDecimal
do samego końca. Słyszałem, że niektórzy ludzie tworzą własne Cash
lub Money
klasy, które zawierają wartość pieniężną w walucie, ale pod skórą nadal jest to BigDecimal
, prawdopodobnie z BigDecimal.ROUND_HALF_EVEN
zaokrągleniem.
Edycja: Jak wspomina Don w swojej odpowiedzi , istnieją projekty open source, takie jak czas i pieniądze , i chociaż brawo im za to, że próbowali uniemożliwić programistom wymyślanie koła na nowo, po prostu nie mam wystarczającego zaufania do biblioteki pre-alpha, aby z niej korzystać to w środowisku produkcyjnym. Poza tym, jeśli poszperasz pod maską, zobaczysz, że oni BigDecimal
też używają .
Informacja o JodaMoney może być przydatna dla osób przybywających tutaj przez wyszukiwarki internetowe: http://www.joda.org/joda-money/ .
BigDecimal
pod maską!
Nie wyrażam tutaj swojej opinii, ale są całkiem dobre argumenty przeciwko BigDecimal, które ktoś prawdopodobnie powinien wyrzucić:
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money/
Wygodną biblioteką, na którą natknąłem się wcześniej, jest biblioteka Joda-Money . Jedna z jego implementacji jest rzeczywiście oparta na BigDecimal. Opiera się na specyfikacji ISO-4217 dla walut i może obsługiwać dostosowaną listę walut (ładowaną przez CVS).
Ta biblioteka zawiera niewielką liczbę plików, przez które można szybko przejść, jeśli potrzebne są modyfikacje. Joda-Money jest publikowany na licencji Apache 2.0.
Jeśli używasz tylko dolarów i centów, użyłbym długiego (przesuniętego o 2 miejsca po przecinku). Jeśli potrzebujesz więcej szczegółów, dobrym rozwiązaniem może być duży ułamek dziesiętny.
Tak czy inaczej, prawdopodobnie rozszerzyłbym klasę tak, aby miała .toString (), która używa poprawnego formatu i jako miejsce do umieszczania innych metod, które mogą się pojawić (przez długi czas mnożenie i dzielenie pójdzie nie tak, jeśli dziesiętna jest n 't dostosowane)
Ponadto, jeśli używasz zdefiniowania własnej klasy i interfejsu, możesz dowolnie zastępować implementację.
BigDecimal
lub inna stała reprezentacja jest tym, co jest ogólnie potrzebne do pieniędzy.
Reprezentacje i obliczenia zmiennoprzecinkowe ( Double
, Float
) są niedokładne, co prowadzi do błędnych wyników.
Musisz być bardzo ostrożny, gdy masz do czynienia z czasem i pieniędzmi.
Mam nadzieję, że kiedy pracujesz z pieniędzmi, każdy powinien wiedzieć, jak nigdy nie używać pływaka ani podwójnej.
Ale nie jestem pewien co do BigDecimal.
W większości przypadków będzie dobrze, jeśli po prostu będziesz śledzić centy w ciągu int lub long. W ten sposób nigdy nie masz do czynienia z miejscem dziesiętnym.
Wyświetlasz dolary tylko podczas drukowania. Zawsze używaj centów wewnętrznych, używając liczb całkowitych. Może to być trudne, jeśli trzeba podzielić lub użyć Math.abs ().
Jednak może Cię to obchodzić pół centa, a nawet setną część. Nie wiem, jaki jest dobry sposób, aby to zrobić. Być może będziesz musiał poradzić sobie z tysięcznymi centami i użyć długiego. A może będziesz zmuszony użyć BigDecimal
Czytałbym o wiele więcej na ten temat, ale zignorowałbym każdego, kto zaczyna mówić o używaniu float lub double do reprezentowania pieniędzy. Po prostu proszą o kłopoty.
Czuję, że moja rada nie jest kompletna, więc proszę, włóż w nią więcej. Masz do czynienia z niebezpiecznymi typami!
Tworzenie klasy Money jest drogą do zrobienia. Używanie BigDecimal (lub nawet int) pod spodem. Następnie użycie klasy Currency do zdefiniowania konwencji zaokrąglania.
Niestety bez przeciążania operatorów Java sprawia, że tworzenie takich podstawowych typów jest dość nieprzyjemne.
Zdecydowanie nie BigDecimal. Jest tak wiele specjalnych zasad dotyczących zaokrąglania i prezentacji, o które musisz się martwić.
Martin Fowler zaleca implementację dedykowanej klasy Money do reprezentowania kwot walut, a także implementuje zasady przeliczania walut.
Hej, oto bardzo interesujący artykuł na temat BigDecimal i ilustrujący przykład, dlaczego czasami jest używany zamiast podwójnych. Samouczek BigDecimal .
Możesz użyć klasy DecimalFormat podczas ostatecznego wyświetlania wartości waluty. Zapewnia obsługę lokalizacji i jest dość rozszerzalny.
Zamknąłbym BigDecimal w klasie Money, która również ma walutę, tak jak ktoś wspomniany powyżej. Ważną rzeczą jest to, że wykonujesz ekstremalną liczbę testów jednostkowych, zwłaszcza jeśli pracujesz z różnymi walutami. Dobrym pomysłem jest również dodanie wygodnego konstruktora, który pobiera ciąg znaków lub metodę fabryczną, która robi to samo, dzięki czemu można napisać swoje testy mniej więcej tak:
assertEquals(Money.create("100.0 USD").add("10 GBP"),Money.create("116 USD"));
W grę wchodzą zawsze ograniczenia i szczegóły. Każdy, kto nie ma wystarczającego doświadczenia, aby docenić subtelne kwestie przedstawione w poniższym artykule, powinien poważnie rozważyć ponowne rozważenie przed zapoznaniem się z rzeczywistymi danymi finansowymi:
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money
BigDecimal nie jest jedyną poprawną reprezentacją ani jedynym elementem układanki. W pewnych warunkach użycie klasy Money zabezpieczonej centami przechowywanymi jako liczba całkowita może być wystarczające i byłoby znacznie szybsze niż BigDecimal. Tak, to implikuje użycie dolarów jako waluty i ogranicza kwoty, ale takie ograniczenia są całkowicie akceptowalne w wielu przypadkach użycia, a wszystkie waluty i tak mają specjalne przypadki zaokrąglania i denominacji, więc nie ma „uniwersalnego” rozwiązania.