Tôi hiểu rằng BigDecimal được khuyến nghị thực hành tốt nhất để biểu diễn các giá trị tiền tệ trong Java. Bạn dùng gì? Có thư viện nào tốt hơn mà bạn thích sử dụng thay thế không?Trình bày các giá trị tiền tệ trong Java
Trả lời
BigDecimal
tất cả các cách. Tôi đã nghe nói về một số folks tạo ra các lớp học Cash
hoặc Money
riêng của họ đóng gói một giá trị tiền mặt với tiền tệ, nhưng dưới da nó vẫn là một BigDecimal
, có lẽ với BigDecimal.ROUND_HALF_EVEN
làm tròn.
Edit: Như Don đề cập trong his answer, có dự án sourced mở như timeandmoney, và trong khi tôi khen ngợi các em cố gắng để ngăn chặn các nhà phát triển từ phải phát minh lại bánh xe, tôi chỉ không có đủ niềm tin vào một trước thư viện -alpha để sử dụng nó trong môi trường sản xuất. Bên cạnh đó, nếu bạn đào xung quanh dưới mui xe, bạn sẽ thấy they use BigDecimal
too.
+1. Chúng tôi đã quyết định thêm một lớp container cũng tiêu thụ một loại tiền tệ. Điều này có ích khi hiển thị các giá trị tiền tệ trong bảng. – dhiller
Vâng, đó là một cách tiếp cận khá phổ biến và nó có ý nghĩa rất nhiều. Một điều trước tiên là khi bạn phải đối phó với Yên Nhật, vì họ không có một mệnh giá tiền tệ nhỏ như xu, vì vậy nó cần các quy tắc làm tròn riêng của nó. – ninesided
@ninesided đưa ra một ví dụ tuyệt vời về lý do tại sao việc cuộn của riêng bạn lại là một câu trả lời không tốt. "Ồ, và nhân tiện, nó không hoạt động với $ CURRENCY_X." Đó là một dấu hiệu tốt cho thấy nó cũng không hiệu quả với nhiều loại tiền tệ khác. –
BigDecimal
hoặc một đại diện điểm cố định khác là thông thường cần thiết cho tiền.
Dấu chấm động (Double
, Float
) biểu diễn và tính toán không chính xác, dẫn đến kết quả sai.
Nói đúng, BigDecimal cũng không chính xác; nó chỉ tương ứng tốt hơn với phép làm tròn thập phân mà chúng ta thường sử dụng trong cuộc sống hàng ngày và cho phép bạn chỉ định các chế độ làm tròn. –
@Michael Borgwardt BigDecimal khác với IEEE FP ở quy mô rõ ràng được chỉ định. Mặc dù không phải tất cả các hoạt động đều chính xác, điều này đảm bảo rằng một tập hợp các hoạt động và hành vi là * luôn * chính xác và tỷ lệ là * hằng số * trong khi tỷ lệ cho IEEE FP giảm theo giá trị. –
Điều đó có liên quan gì đến tiền? Các tổ chức kế toán trên khắp thế giới thường có những yêu cầu rất cụ thể về cách bạn làm toán bằng tiền của họ. BigDecimal có phù hợp chính xác với từng tiêu chuẩn này không? Nó sẽ làm như vậy vào năm tới, khi những tiêu chuẩn đó thay đổi? Và BigDecimal thậm chí không đến gần để xác định các quy tắc làm tròn hữu ích cho tiền tệ. –
Nếu bạn chỉ sử dụng đô la và xu, tôi sẽ sử dụng một khoảng thời gian dài (bù trừ 2 chữ số thập phân). Nếu bạn cần thêm chi tiết, số thập phân lớn có thể là cách để đi. Dù bằng cách nào, tôi có lẽ sẽ mở rộng lớp để có một .toString() sử dụng định dạng chính xác, và là một nơi để đưa các phương pháp khác có thể đi lên (Đối với một thời gian dài, nhân và chia sẽ đi awry nếu số thập phân không được điều chỉnh)
Ngoài ra, nếu bạn sử dụng xác định lớp và giao diện của riêng mình, thì bạn có thể thay thế triển khai theo ý muốn.
Xem ra, thậm chí lâu dài có thể là quá ngắn để giữ nợ Liên bang Hoa Kỳ trong Cents ... nếu không phải bây giờ sau đó trong một vài năm. – Ingo
Tôi đồng ý - bất kỳ số lượng lớn đô la (hoặc có thể nếu bạn đang theo dõi tiền trong Yên), bạn nên sử dụng BigDecimal - nhưng thậm chí sau đó tôi nghiêm túc xem xét sử dụng một lớp container cho nó. Tôi nghĩ rằng phần lớn sự phức tạp của lập trình xuất phát từ những người không định nghĩa các lớp nhỏ, đơn giản xung quanh các bộ sưu tập và các kiểu nội tại. –
Bạn phải cẩn thận khi xử lý thời gian và tiền bạc.
Khi bạn đang làm việc với tiền, tôi hy vọng mọi người nên biết không bao giờ sử dụng một phao hoặc một đôi.
Nhưng tôi không chắc chắn về BigDecimal.
Trong hầu hết các trường hợp, bạn sẽ ổn nếu bạn chỉ theo dõi xu trong một hoặc lâu. Bằng cách này bạn không bao giờ đối phó với một số thập phân.
Bạn chỉ hiển thị đô la khi in. Luôn luôn làm việc với xu nội bộ bằng cách sử dụng số nguyên. Điều này có thể phức tạp nếu cần chia hoặc cần sử dụng Math.abs().
Tuy nhiên, bạn có thể quan tâm đến nửa xu, hoặc thậm chí là một phần trăm của một xu. Tôi không biết cách tốt để làm điều này là gì. Bạn có thể chỉ cần đối phó với hàng ngàn xu và sử dụng một thời gian dài. Hoặc có thể bạn sẽ bị buộc phải sử dụng BigDecimal
Tôi sẽ đọc nhiều hơn về điều này, nhưng bỏ qua tất cả mọi người bắt đầu nói về việc sử dụng phao hoặc gấp đôi để đại diện cho tiền. Họ chỉ yêu cầu rắc rối.
Tôi cảm thấy lời khuyên của mình chưa hoàn chỉnh, vì vậy hãy đặt nhiều hơn vào nó. Bạn đang đối phó với các loại nguy hiểm!
Tại sao bạn cần phải "buộc" để sử dụng BigDecimal? Bạn không chắc chắn về điều gì? Nó rõ ràng là tốt hơn để làm việc với xu, vì nó cho phép bạn xác định rõ ràng chế độ làm tròn. –
@MichaelBorgwardt: vâng, nó cho phép bạn chỉ định một tập con nhỏ của các chế độ làm tròn bạn cần cho tiền tệ. Vì thế? (Gợi ý: tiền tệ làm tròn được quyết định, thông thường, bởi các tổ chức kế toán quốc gia. Họ hoàn toàn hạnh phúc để quăng trong trường hợp đặc biệt kỳ lạ. Xem http://stackoverflow.com/questions/5134237/swiss-and-argentinian-currency-fourth- chữ số thập phân làm tròn chỉ vì một trong nhiều lý do giải trí tại sao làm tròn BigDecimal hoàn toàn vô dụng ở đây.) –
@James: Chính xác thì nó "vô ích" như thế nào? Làm thế nào để thực hiện các trường hợp đặc biệt này sẽ khó hơn với BigDecimal chứ không phải với cái gì khác? –
Tạo lớp Money là cách để thực hiện. Sử dụng BigDecimal (hoặc thậm chí là int) bên dưới. Sau đó sử dụng loại tiền tệ để xác định quy ước làm tròn.
Thật không may nếu không có quá tải toán tử Java khiến việc tạo các kiểu cơ bản như vậy khó chịu.
Có thư viện tốt hơn, timeandmoney. IMO, nó vượt trội hơn nhiều so với các thư viện do JDK cung cấp để biểu diễn 2 khái niệm này.
Câu trả lời này đã được đăng cách đây ba năm. Hôm nay, dự án timeandmoney vẫn là pre-alpha theo liên kết đó. –
@JamesMoore Cuộc gọi tốt.Câu trả lời bây giờ là 7 tuổi và dự án vẫn không ổn định. – Navin
Chắc chắn không phải BigDecimal. Có rất nhiều quy tắc đặc biệt để làm tròn và trình bày mà bạn phải lo lắng.
Martin Fowler khuyên bạn nên triển khai lớp chuyên dụng Money để đại diện cho số tiền và cũng thực hiện các quy tắc cho quy đổi tiền tệ.
và loại dữ liệu cơ bản của lớp Money? BigDecimal. – ninesided
Điều đó không đúng. Bạn có thể sử dụng Integer trong lớp tiền, đó là những gì Martin làm. Tôi đã làm việc này nhiều lần rồi. – egervari
Đề xuất này là chính xác; tính toán liên quan đến tiền là một đầm lầy rộng lớn của các trường hợp đặc biệt thay đổi theo thời gian. BigDecimal có thể hữu ích như một phần nhỏ của giải pháp, nhưng nó chắc chắn không phải là chung. –
Bạn có thể sử dụng lớp DecimalFormat khi hiển thị giá trị tiền tệ. Nó cung cấp hỗ trợ bản địa hóa và có thể mở rộng được.
Tôi sẽ đóng gói BigDecimal trong lớp Money cũng có đơn vị tiền tệ giống như ai đó đã đề cập ở trên. Điều quan trọng là bạn làm một số lượng cực lớn các bài kiểm tra đơn vị và đặc biệt là nếu làm việc với các loại tiền tệ khác nhau. Ngoài ra nó là một ý tưởng tốt nếu bạn thêm một constructor thuận mà phải mất một chuỗi hoặc một phương pháp nhà máy mà không giống nhau để bạn có thể viết bài kiểm tra một cái gì đó của bạn như thế này:
assertEquals(Money.create("100.0 USD").add("10 GBP"),Money.create("116 USD"));
Nó có thể có ích cho những người đến đây bởi các công cụ tìm kiếm để biết về JodaMoney: http://www.joda.org/joda-money/.
Hey, đây là một bài viết rất thú vị về BigDecimal, và một ví dụ minh họa về lý do tại sao đôi khi nó được sử dụng thay vì tăng gấp đôi. BigDecimal Tutorial.
Thư viện tiện lợi mà tôi đã chạy trước đó là thư viện Joda-Money. Một trong những triển khai của nó thực sự dựa trên BigDecimal. Nó dựa trên đặc điểm ISO-4217 cho các loại tiền tệ và có thể hỗ trợ danh sách tiền tệ tùy chỉnh (được tải qua CVS).
Thư viện này có một số lượng tệp nhỏ mà người dùng có thể nhanh chóng thực hiện nếu cần sửa đổi. Joda-Money được xuất bản theo giấy phép Apache 2.0.
Tôi không bày tỏ quan điểm của tôi ở đây, nhưng có những lý lẽ khá tốt so với BigDecimal rằng ai đó có lẽ nên vứt bỏ:
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money/
Luôn luôn có những khó khăn và chi tiết cụ thể có liên quan. Bất cứ ai mà không đủ kinh nghiệm để đánh giá cao những vấn đề tinh tế được nêu trong bài viết sau đây nên xem xét lại nghiêm túc trước khi giao dịch với các dữ liệu tài chính thực tế:
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money
BigDecimal là hầu như không đại diện đúng chỉ hoặc mảnh duy nhất của câu đố. Với điều kiện nhất định, sử dụng một lớp Money được hỗ trợ bởi các xu được lưu trữ dưới dạng số nguyên có thể là đủ và sẽ nhanh hơn nhiều so với BigDecimal. Có, điều đó ngụ ý việc sử dụng đô la làm tiền và giới hạn số tiền nhưng những ràng buộc như vậy hoàn toàn có thể chấp nhận được cho nhiều trường hợp sử dụng và tất cả các loại tiền tệ có trường hợp đặc biệt để làm tròn và mệnh giá, vì vậy không có giải pháp "phổ quát".
Điều này có vẻ là một nhận xét về bài đăng khác thay vì câu trả lời thực tế. Nó cũng quá nồng nhiệt. Hãy cố gắng trở nên dân sự hơn trong tương lai. –
Điểm công bằng, được chỉnh sửa. – Craig
- 1. Lưu trữ các giá trị tiền tệ trong SQLite3
- 2. Java String.format với ký hiệu tiền tệ
- 3. Thư viện tiền tệ cho Java
- 4. TryUpdateModel với giá trị được định dạng tiền tệ?
- 5. Vị trí ký hiệu tiền tệ trong các chuỗi .NET
- 6. Mã đơn vị tiền tệ để lập bản đồ ký hiệu tiền tệ
- 7. Java: Ký hiệu tiền tệ dựa trên mã số tiền tệ ISO 4217
- 8. Thực tiễn tốt nhất để làm việc với các giá trị tiền tệ trong PHP?
- 9. Chuyển đổi tiền tệ
- 10. Magento đa đa tiền tệ
- 11. Định dạng tiền tệ không có ký hiệu tiền tệ
- 12. Đặt giá trị theo đơn vị tiền tệ trong <input type = "number" />
- 13. C# Tiền tệ thành chuỗi
- 14. Formatting tệ sử dụng mẫu trưng bày trong MVC
- 15. Định dạng tiền tệ MVC
- 16. HTML 5 Định dạng tiền tệ
- 17. Chuỗi tiền tệ định dạng
- 18. NSNumberFormatter Tiền tệ Không có Biểu tượng?
- 19. Làm cách nào để ghi đè các ký hiệu tiền tệ trong Java?
- 20. Danh sách tiền tệ ISO
- 21. Chuỗi định dạng tiền tệ trong asp.net
- 22. Đơn vị tiền tệ trong JavaScript
- 23. Cách tốt nhất để trình bày cặp khóa/giá trị Trong các tên lớp HTML
- 24. Chuyển đổi chuỗi tiền tệ thành float trong Objective-C
- 25. Django: FloatField hoặc DecimalField cho tiền tệ?
- 26. Hiển thị đơn vị tiền tệ trong C#
- 27. mysql chọn int là tiền tệ hoặc chuyển đổi int sang định dạng tiền tệ?
- 28. Hoạt động tiền tệ với javaScript?
- 29. các giá trị chọnOneMenu giá trị sử dụng Trình quản trị web Selenium + Java
- 30. Cách sử dụng regex cho đơn vị tiền tệ
hãy xem [JSR 354] (http://jcp.org/en/jsr/detail?id=354) – yegor256
Đây là một loại tiền tệ mà bạn có thể sao chép và mở rộng: http: // java-articles. info/articles /? p = 254 –
Ngoài ra, hãy xem phần thực hiện tham chiếu của JSR-354 https: // github.com/JavaMoney/jsr354-ri – beat