Gần đây chúng tôi đã triển khai một hệ thống cần xử lý các giá trị bằng nhiều loại tiền tệ và chuyển đổi giữa chúng và tìm ra một vài điều khó khăn.
KHÔNG BAO GIỜ SỬ DỤNG SỐ ĐIỂM NỔI BẬT CHO TIỀN
Số học dấu phẩy động giới thiệu những điểm không chính xác có thể không được chú ý cho đến khi chúng làm hỏng điều gì đó. Tất cả các giá trị phải được lưu dưới dạng số nguyên hoặc loại thập phân cố định và nếu bạn chọn sử dụng loại thập phân cố định thì hãy đảm bảo bạn hiểu chính xác loại đó làm gì trong phần mềm (nghĩa là bên trong sử dụng số nguyên hoặc dấu phẩy động kiểu).
Khi bạn cần thực hiện tính toán hoặc chuyển đổi:
- Chuyển đổi giá trị thành dấu phẩy động
- Tính giá trị mới
- Làm tròn số và chuyển đổi lại thành số nguyên
Khi chuyển đổi số dấu phẩy động trở lại thành số nguyên ở bước 3, đừng chỉ sử dụng nó - hãy sử dụng hàm toán học để làm tròn số đó trước. Điều này thường sẽ làround
, mặc dù trong trường hợp đặc biệt nó có thể floor
hoặc ceil
. Biết sự khác biệt và lựa chọn cẩn thận.
Lưu trữ loại số bên cạnh giá trị
Điều này có thể không quan trọng đối với bạn nếu bạn chỉ xử lý một loại tiền tệ, nhưng điều quan trọng đối với chúng tôi là xử lý nhiều loại tiền tệ. Chúng tôi đã sử dụng mã 3 ký tự cho một loại tiền tệ, chẳng hạn như USD, GBP, JPY, EUR, v.v.
Tùy thuộc vào tình huống, nó cũng có thể hữu ích để lưu trữ:
- Cho dù số đó là trước hay sau thuế (và thuế suất là bao nhiêu)
- Số có phải là kết quả của một chuyển đổi (và nó được chuyển đổi từ đâu)
Biết giới hạn chính xác của các số bạn đang xử lý
Đối với các giá trị thực, bạn muốn chính xác như đơn vị tiền tệ nhỏ nhất. Điều này có nghĩa là bạn không có giá trị nào nhỏ hơn một xu, một xu, yên, fen, v.v. Đừng lưu trữ các giá trị với độ chính xác cao hơn mà không có lý do.
Trong nội bộ, bạn có thể chọn xử lý các giá trị nhỏ hơn, trong trường hợp đó là một loại giá trị tiền tệ khác . Hãy chắc chắn rằng mã của bạn biết cái nào và không bị lẫn lộn. Tránh sử dụng các giá trị dấu phẩy động ngay cả ở đây.
Cộng tất cả các quy tắc đó lại với nhau, chúng tôi quyết định các quy tắc sau. Trong mã đang chạy, tiền tệ được lưu trữ bằng một số nguyên cho đơn vị nhỏ nhất.
class Currency {
String code; // eg "USD"
int value; // eg 2500
boolean converted;
}
class Price {
Currency grossValue;
Currency netValue;
Tax taxRate;
}
Trong cơ sở dữ liệu, các giá trị được lưu trữ dưới dạng một chuỗi theo định dạng sau:
USD:2500
Điều đó lưu trữ giá trị $ 25,00. Chúng tôi chỉ có thể làm điều đó vì mã liên quan đến tiền tệ không cần phải nằm trong chính cơ sở dữ liệu, vì vậy tất cả các giá trị có thể được chuyển đổi thành bộ nhớ trước tiên. Các tình huống khác sẽ không nghi ngờ cho vay chính mình cho các giải pháp khác.
Và trong trường hợp tôi không làm rõ sớm hơn, đừng sử dụng float!