2012-05-22 33 views
7

Hãy nói rằng tôi có 2 câu hỏi sau:SQL Bất vs phao

select sum(cast(2666 as float)) * cast(.3 as float) 
select sum(cast(2666 as real)) * cast(.3 as real) 

Các truy vấn trả về 1: 799.8
Các truy vấn trả về 2: 799.800031781197

Tại sao truy vấn thứ 2 không trở về cùng điều thứ nhất?

Trả lời

18

Loại dấu phẩy động nhị phân (như thực và nổi) không thể đại diện chính xác số thập phân. Cụ thể là không thể lưu trữ chính xác 0,3 dưới dạng số dấu phẩy động nhị phân. Thay vào đó một số rất gần với 0,3 được lưu trữ. Điều này được gọi là lỗi biểu diễn.

Kích thước của lỗi khác với thực và nổi bởi vì chúng có độ chính xác khác nhau.

Nếu bạn muốn lưu trữ số thập phân chính xác hơn, hãy xem xét sử dụng decimal or numeric. Nhưng lưu ý rằng mặc dù các loại này có thể lưu trữ chính xác các giá trị thập phân lên đến một số chữ số nhất định, nhưng các phép tính vẫn có thể tạo ra các số không thể được biểu diễn chính xác. Ví dụ: kết quả của 0.1/0.3 không thể được lưu trữ chính xác trong một decimal mặc dù cả hai 0.10.3 có thể. Trong trường hợp này, kết quả sẽ được làm tròn thành giá trị gần nhất có thể được lưu trữ trong loại (ví dụ: 0.333333333 tùy thuộc vào độ chính xác).

+2

Có, chỉ 1/3 là một số định kỳ theo thập phân (0.333333 .. mãi mãi), nó cũng định kỳ theo dạng nhị phân: 0.01010101010101 --- mãi mãi. Tuy nhiên, một số số không lặp lại theo thập phân, như 0,1 được lặp lại theo dạng nhị phân. Ví dụ. 0.1dec = 0.0001100110011 ... mãi mãi trong nhị phân, và do đó không thể được biểu diễn chính xác. – DaveBoltman