Tôi hiểu rằng BigDecimal là phương pháp hay nhất được khuyến nghị để 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 hơn không?
Tôi hiểu rằng BigDecimal là phương pháp hay nhất được khuyến nghị để 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 hơn không?
Câu trả lời:
BigDecimal
tất cả các cách. Tôi đã nghe nói về việc một số người tạo ra các lớp Cash
hoặc Money
lớp học của riêng 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ó thể là với BigDecimal.ROUND_HALF_EVEN
việc làm tròn.
Chỉnh sửa: Như Don đã đề cập trong câu trả lời của mình , có những dự án có nguồn mở như timeandmoney và trong khi tôi hoan nghênh chúng vì đã cố gắng ngăn các nhà phát triển phải phát minh lại bánh xe, tôi chỉ không đủ tin tưởng vào một thư viện tiề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 họ sử dụng BigDecimal
quá .
Nó có thể hữu ích cho những người đến đây bằng các công cụ tìm kiếm để biết về JodaMoney: http://www.joda.org/joda-money/ .
BigDecimal
được nâng cấp!
Tôi không bày tỏ ý kiến của mình ở đây, nhưng có những lập luận khá tốt chống lại BigDecimal mà ai đó có thể nên ném ra:
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money/
Một thư viện tiện lợi mà tôi đã gặp trước đó là thư viện Joda-Money . Một trong những cách triển khai của nó thực sự dựa trên BigDecimal. Nó dựa trên đặc điểm kỹ thuật ISO-4217 cho 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 nhỏ các tệp mà người ta có thể xem nhanh nếu cần sửa đổi. Joda-Money được xuất bản theo giấy phép Apache 2.0.
Nếu bạn chỉ sử dụng đô la và xu, tôi sẽ sử dụng giá trị dài (bù đắp bằng 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ó thể sẽ mở rộng lớp để có .toString () sử dụng định dạng chính xác và như một nơi để đặt các phương thức khác có thể xuất hiện (Trong một thời gian dài, nhân và chia sẽ trở nên tồi tệ nếu số thập phân không phải là không điều chỉnh)
Ngoài ra, nếu bạn sử dụng định nghĩa lớp và giao diện của riêng mình, thì bạn có thể thay thế việc triển khai theo ý muốn.
BigDecimal
hoặc một đại diện điểm cố định khác là những gì thường cần cho tiền.
Các biểu diễn và tính toán dấu phẩy động ( Double
, Float
) không chính xác, dẫn đến kết quả sai.
Bạn phải rất cẩn thận khi đối phó với 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 phao hoặc kép.
Nhưng tôi không chắc 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 các xu trong một int hoặc dài. Bằng cách này, bạn sẽ không bao giờ xử lý một chữ số thập phân.
Bạn chỉ hiển thị đô la khi bạn in nó. Luôn làm việc với xu bên trong 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í một trăm 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 giao dịch với phần nghìn xu và sử dụng lâu dài. Hoặc có thể bạn sẽ 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ả những người bắt đầu nói về việc sử dụng float hoặc double để đại diện cho tiền. Họ chỉ đang yêu cầu rắc rối.
Tôi cảm thấy lời khuyên của tôi không đầy đủ, vì vậy xin vui lòng thêm vào nó. Bạn đang đối phó với các loại nguy hiểm!
Tạo một lớp Tiền là cách để đi. Sử dụng BigDecimal (hoặc thậm chí là số nguyên) bên dưới. Sau đó sử dụng lớp Currency để xác định quy ước làm tròn.
Thật không may nếu không có toán tử quá tải Java làm cho nó khá khó chịu khi tạo các kiểu cơ bản như vậy.
Có một 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 để đại diện cho 2 khái niệm này.
Chắc chắn không phải là 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 nghị triển khai một lớp Tiền chuyên dụng để đại diện cho số lượng tiền tệ và cũng thực hiện các quy tắc chuyển đổi tiền tệ.
Này, đây là một bài viết rất thú vị trên BigDecimal và một ví dụ minh họa về lý do tại sao đôi khi nó được sử dụng thay vì dùng gấp đôi. Hướng dẫn BigDecimal .
Bạn có thể sử dụng lớp DecimalFormat khi cuối cùng hiển thị giá trị tiền tệ. Nó cung cấp hỗ trợ bản địa hóa và khá dễ mở rộng.
Tôi sẽ gói BigDecimal trong lớp Money cũng có một loại tiền tệ giống như ai đó đã đề cập ở trên. Điều quan trọng là bạn phải thực hiện rất nhiều 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, đó là một ý tưởng hay nếu bạn thêm một hàm tạo thuận tiện lấy một chuỗi hoặc một phương thức gốc thực hiện tương tự để bạn có thể viết các bài kiểm tra của mình như sau:
assertEquals(Money.create("100.0 USD").add("10 GBP"),Money.create("116 USD"));
Luôn có những ràng buộc và chi tiết cụ thể liên quan. Bất kỳ ai không có đủ kinh nghiệm để đánh giá cao các vấn đề tinh vi được nêu trong bài viết sau đây nên nghiêm túc xem xét lại trước khi xử lý dữ liệu tài chính trong thế giới thực:
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money
BigDecimal hầu như không phải là đại diện chính xác duy nhất hoặc phần duy nhất của câu đố. Với một số điều kiện nhất định, việc sử dụng loại Tiền được hỗ trợ bằng 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. Đúng, điều đó ngụ ý việc sử dụng đô la làm tiền tệ và giới hạn số lượng nhưng những ràng buộc như vậy hoàn toàn có thể chấp nhận được đối với nhiều trường hợp sử dụng và tất cả các loại tiền tệ đều có các trường hợp đặc biệt để làm tròn và mệnh giá phụ, vì vậy không có giải pháp "chung".