Nên sử dụng kiểu dữ liệu Float hoặc Decimal cho số tiền bằng đô la?
Câu trả lời là dễ dàng. Không bao giờ trôi nổi. KHÔNG BAO GIỜ !
Các số nổi theo IEEE 754 luôn luôn là nhị phân, chỉ các định dạng thập phân được xác định theo tiêu chuẩn IEEE 754R mới. Nhiều phần nhị phân phân số không bao giờ có thể bằng biểu diễn thập phân chính xác.
Bất kỳ số nhị phân nào cũng có thể được viết dưới dạng m/2^n
(m
, n
số nguyên dương), bất kỳ số thập phân nào dưới dạng m/(2^n*5^n)
. Vì các mã nhị phân thiếu factor 5
nguyên tố , tất cả các số nhị phân có thể được biểu diễn chính xác bằng số thập phân, nhưng không thể ngược lại.
0.3 = 3/(2^1 * 5^1) = 0.3
0.3 = [0.25/0.5] [0.25/0.375] [0.25/3.125] [0.2825/3.125]
1/4 1/8 1/16 1/32
Vì vậy, bạn kết thúc với một số cao hơn hoặc thấp hơn số thập phân đã cho. Luôn luôn.
Tại sao lại là vấn đề đó? Làm tròn.
Làm tròn thông thường có nghĩa là 0..4 giảm, 5..9 lên. Vì vậy, nó không vấn đề nếu kết quả không phải là 0.049999999999
.... hoặc 0.0500000000
... Bạn có thể biết rằng nó có nghĩa là 5 xu, nhưng máy tính không biết điều đó và làm tròn 0.4999
... xuống (sai) và 0.5000
... lên (phải).
Cho rằng kết quả của phép tính dấu phẩy động luôn chứa các cụm từ sai số nhỏ, quyết định hoàn toàn là do may rủi. Sẽ vô vọng nếu bạn muốn xử lý số thập phân làm tròn đến chẵn với các số nhị phân.
Không thuyết phục? Bạn khẳng định rằng trong hệ thống tài khoản của bạn mọi thứ đều hoàn toàn ổn? Tài sản và nợ phải trả bằng nhau? Được, sau đó lấy từng số được định dạng nhất định của mỗi mục nhập, phân tích cú pháp và tính tổng chúng bằng một hệ thập phân độc lập!
So sánh với tổng được định dạng. Rất tiếc, có gì đó không ổn, phải không?
Đối với phép tính đó, yêu cầu độ chính xác và độ trung thực cao (chúng tôi đã sử dụng Oracle'sFLOAT) để chúng tôi có thể ghi lại "một phần tỷ của một xu" được tích lũy.
Nó không giúp chống lại lỗi này. Bởi vì tất cả mọi người đều tự động cho rằng máy tính tính đúng, và thực tế không ai kiểm tra độc lập.