Dấu thập phân không được lưu trữ rõ ràng ở bất cứ đâu; đó là một vấn đề hiển thị.
Giải thích sau đây là một sự đơn giản hóa; Tôi đang bỏ qua rất nhiều chi tiết quan trọng và các ví dụ của tôi không nhằm thể hiện bất kỳ nền tảng nào trong thế giới thực. Nó sẽ cung cấp cho bạn một hương vị về cách các giá trị dấu phẩy động được biểu thị trong bộ nhớ và các vấn đề liên quan đến chúng, nhưng bạn sẽ muốn tìm các nguồn có thẩm quyền hơn như Điều mà mọi nhà khoa học máy tính nên biết về số học dấu phẩy động .
Bắt đầu bằng cách biểu thị một giá trị dấu phẩy động trong một biến thể của ký hiệu khoa học, sử dụng cơ sở 2 thay vì cơ sở 10. Ví dụ: giá trị 3.14159 có thể được biểu diễn dưới dạng
0,7853975 * 2 2
0,7853975 là ý nghĩa , hay còn gọi là mantissa; nó là một phần của số chứa các chữ số có nghĩa. Giá trị này được nhân với cơ sở 2 được nâng lên thành sức mạnh của 2 để có được 3,14159.
Số dấu phẩy động được mã hóa bằng cách lưu trữ ý nghĩa và số mũ (cùng với một bit dấu).
Bố cục 32 bit thông thường trông giống như sau:
3 32222222 22211111111110000000000
1 09876543 21098765432109876543210
+-+--------+-----------------------+
| | | |
+-+--------+-----------------------+
^ ^ ^
| | |
| | +-- significand
| |
| +------------------- exponent
|
+------------------------ sign bit
Giống như các kiểu số nguyên đã ký, bit thứ tự cao biểu thị dấu; 0 chỉ giá trị dương, 1 chỉ giá trị âm.
8 bit tiếp theo được sử dụng cho số mũ. Các số mũ có thể dương hoặc âm, nhưng thay vì đặt một bit dấu khác, chúng được mã hóa sao cho 10000000 đại diện cho 0, do đó 00000000 đại diện cho -128 và 11111111 đại diện cho 127.
Các bit còn lại được sử dụng cho ý nghĩa. Mỗi bit đại diện cho một công suất âm 2 đếm từ bên trái, vì vậy:
01101 = 0 * 2 -1 + 1 * 2 -2 + 1 * 2 -3 + 0 * 2 -4 + 1 * 2 -5
= 0,25 + 0,125 + 0,03125
= 0,40625
Một số nền tảng giả định bit dẫn "ẩn" trong ý nghĩa và luôn được đặt thành 1, vì vậy các giá trị trong phạm vi có ý nghĩa luôn nằm trong khoảng [0,5, 1). Điều này cho phép các nền tảng này lưu trữ các giá trị với độ chính xác cao hơn một chút (nhiều hơn ở bên dưới). Ví dụ của tôi không làm điều này.
Vì vậy, giá trị 3.14159 của chúng tôi sẽ được biểu diễn dưới dạng như
0 10000010 11001001000011111100111
^ ^ ^
| | |
| | + --- có ý nghĩa = 0,7853975 ...
| |
| + ------------------- số mũ = 2 (130 - 128)
|
+ ------------------------- dấu = 0 (tích cực)
giá trị = -1 (ký hiệu) * 2 (số mũ) * (có ý nghĩa)
giá trị = -1 0 * 2 2 * 0,7853975 ...
giá trị = 3,14159 ...
Bây giờ, một điều bạn sẽ nhận thấy nếu bạn cộng tất cả các bit trong ý nghĩa và đó là chúng không có tổng số 0,7853975; họ thực sự đi ra đến 0,78539747. Không có đủ bit để lưu trữ giá trị chính xác ; chúng tôi chỉ có thể lưu trữ một xấp xỉ. Số lượng bit trong ý nghĩa và xác định độ chính xác hoặc có bao nhiêu chữ số có nghĩa bạn có thể lưu trữ. 23 bit cho ta khoảng 6 chữ số thập phân chính xác. Các loại dấu phẩy động 64 bit cung cấp đủ số bit trong ý nghĩa và cung cấp độ chính xác khoảng 12 đến 15 chữ số. Nhưng hãy lưu ý rằng có những giá trị không thể được biểu diễn chính xác cho dù thế nàonhiều bit bạn sử dụng. Cũng giống như các giá trị như 1/3 không thể được biểu diễn trong một số hữu hạn các chữ số thập phân, các giá trị như 1/10 không thể được biểu diễn trong một số bit hữu hạn. Vì các giá trị là gần đúng, các phép tính với chúng cũng gần đúng và tích lũy các lỗi làm tròn.
Số lượng bit trong số mũ xác định phạm vi (giá trị tối thiểu và tối đa bạn có thể đại diện). Nhưng khi bạn tiến tới các giá trị tối thiểu và tối đa của bạn, kích thước của khoảng cách giữa các giá trị đại diện sẽ tăng lên. Nghĩa là, nếu bạn không thể biểu thị chính xác các giá trị trong khoảng từ 0,785394 đến 0,785398, thì bạn không thể biểu diễn chính xác các giá trị trong khoảng từ 7,85394 đến 7,85398, hoặc các giá trị trong khoảng từ 78.5394 đến 78.5398 hoặc các giá trị trong khoảng từ 785394.0 đến 785398.0. Hãy cẩn thận khi nhân các số rất lớn (về độ lớn) với các số rất nhỏ.