2008-11-07 32 views
19

Tại sao khi tôi lưu giá trị nói 40,54 trong SQL Server thành một cột kiểu Thực sự nó trả lại cho tôi một giá trị lớn hơn 40,53999878999 thay vì 40,54? Tôi đã nhìn thấy điều này một vài lần nhưng chưa bao giờ tìm ra lý do tại sao nó xảy ra. Có ai khác gặp vấn đề này và nếu có thì sẽ gây ra vấn đề này?Thực so với điểm nổi so với tiền

+0

Điều này: http://www.panix.com/~arnow/brooklyn_college/diatribe.html – Moshe

Trả lời

43

Hãy xem What Every Computer Scientist Should Know About Floating Point Arithmetic.

Số dấu chấm động trong máy tính không đại diện chính xác phần thập phân. Thay vào đó, chúng đại diện cho các phân số nhị phân. Hầu hết các số phân số không có biểu diễn chính xác dưới dạng phần nhị phân, do đó, có một số làm tròn đang diễn ra. Khi một phần nhị phân tròn như vậy được dịch ngược lại thành một phần thập phân, bạn sẽ có được hiệu ứng mà bạn mô tả.

Để lưu trữ giá trị tiền, cơ sở dữ liệu SQL thường cung cấp loại DECIMAL lưu trữ số thập phân chính xác. Định dạng này hơi kém hiệu quả đối với các máy tính để xử lý, nhưng nó khá hữu ích khi bạn muốn tránh các lỗi làm tròn số thập phân.

+2

Trên thực tế, tốc độ * chậm hơn đáng kể đối với máy tính (khoảng 10 lần, do thiếu hỗ trợ phần cứng), nhưng sự chậm chạp không quan trọng đối với hầu hết các ứng dụng vì các thao tác số không ở gần nút cổ chai. – crazy2be

+0

Số dấu chấm động không đại diện cho ** một số ** phân số thập phân chính xác. Số thực trong đời thực cũng không đại diện cho * một số * phân số chính xác. Ví dụ, '1/2' có thể được biểu diễn chính xác trên cả hai hệ thống. – axiac

12

Số dấu chấm động sử dụng phân số nhị phân và chúng không tương ứng chính xác với phân số thập phân.

Để kiếm tiền, tốt hơn là lưu trữ số xu dưới dạng số nguyên hoặc sử dụng loại số thập phân. Ví dụ: Thập phân (8,2) lưu trữ 8 chữ số bao gồm 2 chữ số thập phân (xxxxxx.xx), tức là độ chính xác cent.

+0

Tôi muốn cả hai bạn có được điểm để trả lời tốt. Thay vì lưu trữ các xu, chúng tôi đang sử dụng giá trị themoney. Bạn có nghĩ rằng đây cũng là một thực hành tốt? – Middletone

+0

Lưu trữ xu là tin xấu. Các tổ chức tài chính thường sử dụng xu phân số trong tính toán, và đôi khi cũng cần lưu trữ chúng. Tôi đã từng tham gia một dự án khi điều này xuất hiện sau khi ứng dụng lưu trữ xu được triển khai. Rất xấu. – MusiGenesis

+1

Chỉ cần một lưu ý, không phải là thập phân (8,2) thực sự xxxxxx.xx thay vì xxxxxxxx.xx? 8 trong định nghĩa đề cập đến tổng số chữ số cả trước và sau dấu thập phân. –

1

Để thêm làm rõ, một số dấu phẩy động được lưu trữ trong máy tính hoạt động như được mô tả bằng các bài đăng khác tại đây, vì như được mô tả, nó được lưu ở định dạng nhị phân. Điều này có nghĩa là trừ khi giá trị của nó (cả phần tử giá trị và số mũ của giá trị) là các lũy thừa của hai giá trị, và không thể được biểu diễn chính xác.

Một số hệ thống, mặt khác lưu các số thập phân theo số thập phân (kiểu số thập phân SQL, và kiểu dữ liệu số và kiểu dữ liệu số Oracle), và sau đó biểu diễn bên trong của chúng là chính xác cho bất kỳ số nào sức mạnh của 10. Nhưng sau đó con số đó không phải là quyền hạn của 10 không thể được đại diện chính xác.

Các vấn đề liên quan