To zależy od tego, jakie operacje zamierzasz wykonać. Proszę podać więcej informacji.
eversor
@eversor Czy możesz mi podać opis, jaki typ danych powinien być używany do różnych operacji?
questborn
1
Robię obliczenia, które wymagają ode mnie dokładnego przedstawienia centów.
questborn
Czy jesteś w stanie przewidzieć największą kwotę, którą Twoja aplikacja będzie musiała obsłużyć? A twoje obliczenia, czy będą one proste (reklamy itp.) Czy bardziej złożone operacje finansowe?
eversor
Odpowiedzi:
133
Java ma Currencyklasę reprezentującą kody walut ISO 4217.
BigDecimaljest najlepszym typem do reprezentowania wartości dziesiętnych waluty.
Joda Money zapewnił bibliotekę do reprezentowania pieniędzy.
@ Borat: jeśli wiesz, co robisz, zapoznaj się z tym artykułem autorstwa Petera Lawreya. ale wydaje się co najmniej tak samo kłopotliwe, jak przy użyciu BigDecimals.
Nathan Hughes
35
„Gdybym miał bilon za każdym razem, gdy widziałem, jak ktoś używa FLOAT do przechowywania waluty, miałbym 999,997634 $” - Bill Karwin
Collin Krawll
36
Możesz użyć interfejsu Money and Currency API (JSR 354) . Możesz użyć tego interfejsu API pod warunkiem, że dodasz odpowiednie zależności do swojego projektu.
W przypadku języka Java 8 dodaj następującą implementację referencyjną jako zależność pom.xml:
Należy pamiętać, że ilość pieniędzy może przepełnić rozmiar int
eversor
5
@eversor, który potrzebowałby ponad 20 milionów dolarów, większość aplikacji nie potrzebowałaby tak wiele, gdyby działały długo, ponieważ nawet nasze szopy nie obsługują wystarczającej ilości pieniędzy, aby to przelać
maniak ratchet
4
@ratchetfreak Prawdopodobnie lepiej użyć dłuższego czasu.
trognanders
4
Wiele banków obsługuje codziennie znacznie większe sumy pieniędzy, które wynoszą 20 000 000 USD. To nawet nie bierze pod uwagę walut takich jak jen z dużymi kursami wymiany do dolara. Typy liczb całkowitych mogą być najlepsze, aby uniknąć problemów z zaokrąglaniem, chociaż stają się one nieczytelne przy obliczaniu odsetek i kursów walut. Jednak w zależności od aplikacji może być wymagana 64-bitowa liczba całkowita.
Alchymist
Idealnie byłoby, gdyby mikrodolary działały tak, jakbyś robił np. 10 USD / 3, błąd zaokrąglania (3333.3 => 3333.0) nie wpływa tak bardzo na końcową wartość (w tym przypadku w ogóle nie wpływa na rzeczywistą wartość, chociaż jest niebezpieczne jest założenie, że nigdy nie będzie). Jest to szczególnie ważne, jeśli wykonujesz wiele obliczeń z rzędu, zanim użytkownik zobaczy wynik, ponieważ błędy zaokrąglania będą się komplikować.
JSR 354 zapewnia interfejs API do reprezentowania, transportu i wykonywania kompleksowych obliczeń za pomocą pieniędzy i waluty. Możesz pobrać go z tego linku:
Interfejs API do obsługi np. Kwot pieniężnych i walut
Interfejsy API do obsługi wymiennych implementacji
Fabryki do tworzenia instancji klas implementacji
Funkcjonalność do obliczeń, konwersji i formatowania kwot pieniężnych
Java API do pracy z pieniędzmi i walutami, które planuje się włączyć do Java 9.
Wszystkie klasy specyfikacji i interfejsy znajdują się w pakiecie javax.money. *.
Przykładowe przykłady JSR 354: API pieniędzy i walut:
Przykład utworzenia MonetaryAmount i wydrukowania go na konsoli wygląda następująco:
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));
Podczas korzystania z referencyjnego interfejsu API implementacji niezbędny kod jest znacznie prostszy:
MonetaryAmount monetaryAmount =Money.of(12345.67,"EUR");MonetaryAmountFormat format =MonetaryFormats.getAmountFormat(Locale.getDefault());System.out.println(format.format(monetaryAmount));
Interfejs API obsługuje również obliczenia za pomocą MonetaryAmounts:
// getting CurrencyUnits by localeCurrencyUnit yen =MonetaryCurrencies.getCurrency(Locale.JAPAN);CurrencyUnit canadianDollar =MonetaryCurrencies.getCurrency(Locale.CANADA);
MonetaryAmount ma różne metody, które umożliwiają dostęp do przypisanej waluty, kwoty liczbowej, jej precyzji i nie tylko:
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;
Kwoty pieniężne można zaokrąglać za pomocą operatora zaokrąglania:
Wszystko to jest miłe, ale jak sugeruje Federico powyżej, wygląda wolniej niż BigDecimal :-)) tylko zły żart, ale dam temu test już rok później ...
kensai
6
Powinieneś używać BigDecimal do reprezentowania wartości pieniężnych. Pozwala to na korzystanie z różnych trybów zaokrąglania , aw aplikacjach finansowych tryb zaokrąglania jest często trudnym wymogiem, który może być nawet wymagany przez prawo.
Co ciekawe, przeprowadzę ten sam test z najnowszymi materiałami na JDK9
kensai,
4
W prostym przypadku (jedna waluta) to wystarczy Integer/ Long. Trzymaj pieniądze w centach (...) lub setnych / tysięcznych centach (dowolna precyzja, której potrzebujesz z ustalonym dzielnikiem)
BigDecimal jest najlepszym typem danych dla waluty.
Istnieje wiele kontenerów dla waluty, ale wszystkie używają BigDecimal jako podstawowego typu danych. Nie pomylisz się z BigDecimal, prawdopodobnie używając zaokrąglania BigDecimal.ROUND_HALF_EVEN.
Lubię używać Tiny Types, które zawijałyby double, BigDecimal lub int, jak sugerowały poprzednie odpowiedzi. (Użyłbym podwójnego, chyba że pojawią się problemy z precyzją).
Mały typ zapewnia bezpieczeństwo pisania, więc nie mylisz podwójnych pieniędzy z innymi podwójnymi.
Odpowiedzi:
Java ma
Currency
klasę reprezentującą kody walut ISO 4217.BigDecimal
jest najlepszym typem do reprezentowania wartości dziesiętnych waluty.Joda Money zapewnił bibliotekę do reprezentowania pieniędzy.
źródło
Możesz użyć interfejsu Money and Currency API (JSR 354) . Możesz użyć tego interfejsu API pod warunkiem, że dodasz odpowiednie zależności do swojego projektu.
W przypadku języka Java 8 dodaj następującą implementację referencyjną jako zależność
pom.xml
:Ta zależność zostanie tranzystorowo dodana
javax.money:money-api
jako zależność.Następnie możesz użyć interfejsu API:
źródło
Typ całkowy reprezentujący najmniejszą możliwą wartość. Innymi słowy, twój program powinien myśleć w centach, a nie w dolarach / euro.
Nie powinno to powstrzymywać cię przed przetłumaczeniem GUI na dolary / euro.
źródło
Można użyć BigDecimal , dobre wyjaśnienie, dlaczego nie należy używać Float lub Double można zobaczyć tutaj: Dlaczego nie użyć Double lub Float do reprezentowania waluty?
źródło
JSR 354: API pieniędzy i walut
JSR 354 zapewnia interfejs API do reprezentowania, transportu i wykonywania kompleksowych obliczeń za pomocą pieniędzy i waluty. Możesz pobrać go z tego linku:
JSR 354: Pobieranie interfejsu API pieniędzy i walut
Specyfikacja składa się z następujących rzeczy:
Przykładowe przykłady JSR 354: API pieniędzy i walut:
Przykład utworzenia MonetaryAmount i wydrukowania go na konsoli wygląda następująco:
Podczas korzystania z referencyjnego interfejsu API implementacji niezbędny kod jest znacznie prostszy:
Interfejs API obsługuje również obliczenia za pomocą MonetaryAmounts:
CurrencyUnit i MonetaryAmount
MonetaryAmount ma różne metody, które umożliwiają dostęp do przypisanej waluty, kwoty liczbowej, jej precyzji i nie tylko:
Kwoty pieniężne można zaokrąglać za pomocą operatora zaokrąglania:
Podczas pracy z kolekcjami MonetaryAmounts dostępnych jest kilka przydatnych narzędzi do filtrowania, sortowania i grupowania.
Niestandardowe operacje MonetaryAmount
Zasoby:
Obsługa pieniędzy i walut w Javie z JSR 354
Patrząc na interfejs API pieniędzy i walut Java 9 (JSR 354)
Zobacz także: JSR 354 - Waluta i pieniądze
źródło
Powinieneś używać BigDecimal do reprezentowania wartości pieniężnych. Pozwala to na korzystanie z różnych trybów zaokrąglania , aw aplikacjach finansowych tryb zaokrąglania jest często trudnym wymogiem, który może być nawet wymagany przez prawo.
źródło
Chciałbym użyć Joda pieniądze
Nadal jest w wersji 0.6, ale wygląda bardzo obiecująco
źródło
Zrobiłem znak mikrodruku (JMH), aby porównać Monetę (implementację JSR 354 w walucie Java) z BigDecimal pod względem wydajności.
Zaskakujące wydaje się, że wydajność BigDecimal jest lepsza niż moneta. Użyłem następującej konfiguracji moneta:
org.javamoney.moneta.Money.defaults.precision = 19 org.javamoney.moneta.Money.defaults.roundingMode = POŁOWA
Wynikające z
Prosimy o poprawienie mnie, jeśli czegoś brakuje
źródło
W prostym przypadku (jedna waluta) to wystarczy
Integer
/Long
. Trzymaj pieniądze w centach (...) lub setnych / tysięcznych centach (dowolna precyzja, której potrzebujesz z ustalonym dzielnikiem)źródło
BigDecimal jest najlepszym typem danych dla waluty.
Istnieje wiele kontenerów dla waluty, ale wszystkie używają BigDecimal jako podstawowego typu danych. Nie pomylisz się z BigDecimal, prawdopodobnie używając zaokrąglania BigDecimal.ROUND_HALF_EVEN.
źródło
Lubię używać Tiny Types, które zawijałyby double, BigDecimal lub int, jak sugerowały poprzednie odpowiedzi. (Użyłbym podwójnego, chyba że pojawią się problemy z precyzją).
Mały typ zapewnia bezpieczeństwo pisania, więc nie mylisz podwójnych pieniędzy z innymi podwójnymi.
źródło