Tergantung operasi apa yang akan Anda lakukan. Tolong tawarkan informasi lebih lanjut.
eversor
@ eversor Bisakah Anda memberi saya deskripsi tipe data apa yang harus digunakan untuk operasi yang berbeda?
questborn
1
Sedang melakukan perhitungan yang mengharuskan saya untuk secara akurat mewakili sen.
questborn
Apakah Anda dapat meramalkan jumlah uang terbesar yang perlu ditangani oleh aplikasi Anda? Dan, kalkulasi Anda, apakah akan sederhana (tambahan dll) atau operasi keuangan yang lebih kompleks?
eversor
Jawaban:
133
Java memiliki Currencykelas yang mewakili kode mata uang ISO 4217.
BigDecimaladalah jenis terbaik untuk mewakili nilai desimal mata uang.
Joda Money telah menyediakan perpustakaan untuk mewakili uang.
@ Borat: Anda bisa jika tahu apa yang Anda lakukan, lihat artikel ini oleh Peter Lawrey. tetapi tampaknya setidaknya sama besar kerumitan untuk melakukan semua pembulatan untuk menggunakan BigDecimal.
Nathan Hughes
35
"Jika saya punya uang receh untuk setiap kali saya melihat seseorang menggunakan FLOAT untuk menyimpan mata uang, saya akan memiliki $ 999.997634" - Bill Karwin
Collin Krawll
36
Anda dapat menggunakan API Uang dan Mata Uang (JSR 354) . Anda dapat menggunakan API ini di, asalkan Anda menambahkan dependensi yang sesuai untuk proyek Anda.
Untuk Java 8, tambahkan implementasi referensi berikut sebagai ketergantungan pada Anda pom.xml:
Bagaimana dengan serialisasi dan penyimpanan ke db? Format apa yang harus digunakan untuk mengirim melalui kawat?
Paweł Szczur
1
Saya percaya bahwa Oracle mendedikasikan againts termasuk Java Money di Java 9. Sungguh memalukan. Tapi jawaban yang bagus. Kita masih bisa menggunakannya dengan Maven
borjab
3
Apakah Anda memiliki sumber untuk Oracle yang memutuskan untuk memasukkan Java Money dalam Java 9?
Abdull
25
Tipe integral yang mewakili nilai sekecil mungkin. Dengan kata lain program Anda harus berpikir dalam sen bukan dalam dolar / euro.
Ini seharusnya tidak menghentikan Anda dari meminta gui menerjemahkannya kembali ke dolar / euro.
Ingatlah bahwa jumlah uang dapat meluap ukuran int
eversor
5
@Everor yang akan membutuhkan lebih dari 20 juta dolar sebagian besar aplikasi tidak akan membutuhkan sebanyak itu jika mereka melakukan cukup lama karena bahkan pemerintah kita tidak dapat menangani cukup uang untuk melimpah itu
ratchet freak
4
@ scratchetfreak Mungkin lebih baik menggunakan waktu yang lama.
trognanders
5
Banyak bank menangani jumlah uang yang jauh lebih besar yaitu $ 20.000.000 setiap hari. Ini bahkan tidak memperhitungkan mata uang seperti yen dengan nilai tukar besar terhadap dolar. Jenis integer mungkin yang terbaik untuk menghindari masalah pembulatan meskipun mereka menjadi berantakan dengan perhitungan bunga dan nilai tukar. Namun, tergantung pada aplikasinya, Anda mungkin memerlukan tipe integer 64-bit.
Alchymist
Idealnya microdollars, sebenarnya, saat itu jika Anda lakukan misalnya $ 10/3 maka kesalahan pembulatan (3333.3 => 3333.0) tidak terlalu mempengaruhi nilai akhir (dalam hal ini tidak mempengaruhi nilai sebenarnya sama sekali, meskipun itu berbahaya untuk menganggap bahwa itu tidak akan pernah terjadi). Ini sangat penting jika Anda melakukan banyak perhitungan berturut-turut sebelum pengguna melihat hasilnya, karena kesalahan pembulatan akan bertambah.
JSR 354 menyediakan API untuk mewakili, mengangkut, dan melakukan perhitungan komprehensif dengan Uang dan Mata Uang. Anda dapat mengunduhnya dari tautan ini:
API untuk penanganan misalnya jumlah uang dan mata uang
API untuk mendukung implementasi yang dapat dipertukarkan
Pabrik untuk membuat instance dari kelas implementasi
Fungsi untuk perhitungan, konversi, dan pemformatan jumlah uang
API Java untuk bekerja dengan Uang dan Mata Uang, yang rencananya akan dimasukkan dalam Java 9.
Semua kelas spesifikasi dan antarmuka terletak di paket javax.money. *.
Contoh Contoh JSR 354: API Uang dan Mata Uang:
Contoh membuat MonetaryAmount dan mencetaknya ke konsol terlihat seperti ini ::
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));
Saat menggunakan API implementasi referensi, kode yang diperlukan jauh lebih sederhana:
MonetaryAmount monetaryAmount =Money.of(12345.67,"EUR");MonetaryAmountFormat format =MonetaryFormats.getAmountFormat(Locale.getDefault());System.out.println(format.format(monetaryAmount));
API juga mendukung perhitungan dengan MonetaryAmounts:
// getting CurrencyUnits by localeCurrencyUnit yen =MonetaryCurrencies.getCurrency(Locale.JAPAN);CurrencyUnit canadianDollar =MonetaryCurrencies.getCurrency(Locale.CANADA);
MonetaryAmount memiliki berbagai metode yang memungkinkan mengakses mata uang yang ditetapkan, jumlah numerik, ketepatannya, dan lainnya:
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;
Jumlah Moneter dapat dibulatkan menggunakan operator pembulatan:
Semua ini bagus, tetapi seperti yang disarankan Federico di atas, kelihatannya lebih lambat daripada BigDecimal :-)) hanya lelucon buruk, tetapi saya akan memberikan tes itu sekarang 1 tahun kemudian ...
kensai
6
Anda harus menggunakan BigDecimal untuk mewakili nilai moneter. Ini memungkinkan Anda untuk menggunakan berbagai mode pembulatan , dan dalam aplikasi keuangan, mode pembulatan seringkali merupakan persyaratan keras yang bahkan mungkin diamanatkan oleh hukum.
Menarik, saya akan menjalankan tes yang sama dengan hal-hal terbaru pada JDK9
kensai
4
Untuk kasus sederhana (satu mata uang) sudah cukup Integer/ Long. Simpan uang dalam sen (...) atau seperseratus / seperseribu sen (presisi apa pun yang Anda butuhkan dengan pembagi tetap)
BigDecimal adalah tipe data terbaik yang digunakan untuk mata uang.
Ada banyak wadah untuk mata uang, tetapi mereka semua menggunakan BigDecimal sebagai tipe data yang mendasarinya. Anda tidak akan salah dengan BigDecimal, mungkin menggunakan BigDecimal.ROUND_HALF_EVEN pembulatan.
Saya suka menggunakan Tiny Type yang akan membungkus ganda, BigDecimal, atau int seperti jawaban sebelumnya telah menyarankan. (Saya akan menggunakan ganda kecuali masalah presisi muncul).
Tipe Tiny memberi Anda keamanan tipe sehingga Anda tidak bingung dengan uang ganda dengan ganda lainnya.
Jawaban:
Java memiliki
Currency
kelas yang mewakili kode mata uang ISO 4217.BigDecimal
adalah jenis terbaik untuk mewakili nilai desimal mata uang.Joda Money telah menyediakan perpustakaan untuk mewakili uang.
sumber
Anda dapat menggunakan API Uang dan Mata Uang (JSR 354) . Anda dapat menggunakan API ini di, asalkan Anda menambahkan dependensi yang sesuai untuk proyek Anda.
Untuk Java 8, tambahkan implementasi referensi berikut sebagai ketergantungan pada Anda
pom.xml
:Ketergantungan ini akan ditambahkan
javax.money:money-api
secara positif sebagai ketergantungan.Anda kemudian dapat menggunakan API:
sumber
Tipe integral yang mewakili nilai sekecil mungkin. Dengan kata lain program Anda harus berpikir dalam sen bukan dalam dolar / euro.
Ini seharusnya tidak menghentikan Anda dari meminta gui menerjemahkannya kembali ke dolar / euro.
sumber
BigDecimal dapat digunakan, penjelasan yang baik tentang mengapa tidak menggunakan Float atau Double dapat dilihat di sini: Mengapa tidak menggunakan Double atau Float untuk mewakili mata uang?
sumber
JSR 354: API Uang dan Mata Uang
JSR 354 menyediakan API untuk mewakili, mengangkut, dan melakukan perhitungan komprehensif dengan Uang dan Mata Uang. Anda dapat mengunduhnya dari tautan ini:
JSR 354: Unduhan API Uang dan Mata Uang
Spesifikasi terdiri dari hal-hal berikut:
Contoh Contoh JSR 354: API Uang dan Mata Uang:
Contoh membuat MonetaryAmount dan mencetaknya ke konsol terlihat seperti ini ::
Saat menggunakan API implementasi referensi, kode yang diperlukan jauh lebih sederhana:
API juga mendukung perhitungan dengan MonetaryAmounts:
CurrencyUnit dan MonetaryAmount
MonetaryAmount memiliki berbagai metode yang memungkinkan mengakses mata uang yang ditetapkan, jumlah numerik, ketepatannya, dan lainnya:
Jumlah Moneter dapat dibulatkan menggunakan operator pembulatan:
Saat bekerja dengan koleksi MonetaryAmounts, beberapa metode utilitas yang bagus untuk memfilter, menyortir, dan mengelompokkan tersedia.
Operasi MonetaryAmount khusus
Sumber:
Menangani uang dan mata uang di Jawa dengan JSR 354
Melihat ke dalam Java 9 Money and Currency API (JSR 354)
Lihat Juga: JSR 354 - Mata Uang dan Uang
sumber
Anda harus menggunakan BigDecimal untuk mewakili nilai moneter. Ini memungkinkan Anda untuk menggunakan berbagai mode pembulatan , dan dalam aplikasi keuangan, mode pembulatan seringkali merupakan persyaratan keras yang bahkan mungkin diamanatkan oleh hukum.
sumber
Saya akan menggunakan Joda Money
Itu masih di versi 0.6 tetapi terlihat sangat menjanjikan
sumber
Saya telah melakukan microbenchmark (JMH) untuk membandingkan Moneta (implementasi JSR 354 mata uang java) dengan BigDecimal dalam hal kinerja.
Anehnya, kinerja BigDecimal tampaknya lebih baik daripada moneta. Saya telah menggunakan konfigurasi moneta berikut:
org.javamoney.moneta.Money.defaults.precision = 19 org.javamoney.moneta.Money.defaults.roundingMode = HALF_UP
Yang menghasilkan
Silakan koreksi saya jika saya kehilangan sesuatu
sumber
Untuk kasus sederhana (satu mata uang) sudah cukup
Integer
/Long
. Simpan uang dalam sen (...) atau seperseratus / seperseribu sen (presisi apa pun yang Anda butuhkan dengan pembagi tetap)sumber
BigDecimal adalah tipe data terbaik yang digunakan untuk mata uang.
Ada banyak wadah untuk mata uang, tetapi mereka semua menggunakan BigDecimal sebagai tipe data yang mendasarinya. Anda tidak akan salah dengan BigDecimal, mungkin menggunakan BigDecimal.ROUND_HALF_EVEN pembulatan.
sumber
Saya suka menggunakan Tiny Type yang akan membungkus ganda, BigDecimal, atau int seperti jawaban sebelumnya telah menyarankan. (Saya akan menggunakan ganda kecuali masalah presisi muncul).
Tipe Tiny memberi Anda keamanan tipe sehingga Anda tidak bingung dengan uang ganda dengan ganda lainnya.
sumber