(Lưu ý: Tôi sẽ nối 'b' để chỉ ra số nhị phân ở đây. Tất cả các số khác được đưa ra dưới dạng thập phân)
Một cách để suy nghĩ về mọi thứ là về một cái gì đó như ký hiệu khoa học. Chúng ta thường thấy những con số được biểu thị bằng ký hiệu khoa học như, 6.022141 * 10 ^ 23. Số dấu phẩy động được lưu trữ bên trong bằng cách sử dụng một định dạng tương tự - mantissa và số mũ, nhưng sử dụng lũy thừa của hai thay vì mười.
61.0 của bạn có thể được viết lại thành 1.90625 * 2 ^ 5 hoặc 1.11101b * 2 ^ 101b với mantissa và số mũ. Để nhân số đó với mười và (di chuyển dấu thập phân), chúng ta có thể làm:
(1.90625 * 2 ^ 5) * (1.25 * 2 ^ 3) = (2.3828125 * 2 ^ 8) = (1.19140625 * 2 ^ 9)
hoặc với mantissa và số mũ trong nhị phân:
(1.11101b * 2 ^ 101b) * (1.01b * 2 ^ 11b) = (10.0110001b * 2 ^ 1000b) = (1.00110001b * 2 ^ 1001b)
Lưu ý những gì chúng tôi đã làm ở đó để nhân số. Chúng tôi nhân số bọ ngựa và thêm số mũ. Sau đó, vì lớp phủ kết thúc lớn hơn hai, chúng tôi đã bình thường hóa kết quả bằng cách trả số mũ. Nó giống như khi chúng ta điều chỉnh số mũ sau khi thực hiện một thao tác trên các số theo ký hiệu khoa học thập phân. Trong mỗi trường hợp, các giá trị mà chúng tôi đã làm việc có biểu diễn hữu hạn ở dạng nhị phân và do đó, các giá trị đầu ra bằng phép nhân và phép cộng bổ sung cơ bản cũng tạo ra các giá trị có biểu diễn hữu hạn.
Bây giờ, hãy xem xét cách chúng tôi chia 61 cho 10. Chúng tôi sẽ bắt đầu bằng cách chia bọ ngựa, 1.90625 và 1.25. Trong số thập phân, số này cho 1.525, một số ngắn đẹp. Nhưng đây là gì nếu chúng ta chuyển đổi nó thành nhị phân? Chúng tôi sẽ làm theo cách thông thường - trừ đi sức mạnh lớn nhất của hai bất cứ khi nào có thể, giống như chuyển đổi số thập phân nguyên sang nhị phân, nhưng chúng tôi sẽ sử dụng lũy thừa âm của hai:
1,525 - 1 * 2 ^ 0 -> 1
0,525 - 1 * 2 ^ -1 -> 1
0,025 - 0 * 2 ^ -2 -> 0
0,025 - 0 * 2 ^ -3 -> 0
0,025 - 0 * 2 ^ -4 -> 0
0,025 - 0 * 2 ^ -5 -> 0
0,025 - 1 * 2 ^ -6 -> 1
0,009375 - 1 * 2 ^ -7 -> 1
0,0015625 - 0 * 2 ^ -8 -> 0
0,0015625 - 0 * 2 ^ -9 -> 0
0,0015625 - 1 * 2 ^ -10 -> 1
0,0005859375 - 1 * 2 ^ -11 -> 1
0,00009765625 ...
À ồ. Bây giờ chúng tôi đang gặp rắc rối. Hóa ra 1.90625 / 1.25 = 1.525, là phân số lặp lại khi được biểu thị dưới dạng nhị phân: 1.11101b / 1.01b = 1.10000110011 ... b Máy của chúng tôi chỉ có rất nhiều bit để giữ mantissa và vì vậy chúng sẽ chỉ làm tròn phân số và giả sử số không vượt quá một điểm nhất định. Lỗi bạn thấy khi bạn chia 61 cho 10 là sự khác biệt giữa:
1.100001100110011001100110011001100110011 ... b * 2 ^ 10b
và, giả sử:
1.100001100110011001100110b * 2 ^ 10b
Chính việc làm tròn lớp phủ này dẫn đến mất độ chính xác mà chúng ta liên kết với các giá trị dấu phẩy động. Ngay cả khi mantissa có thể được thể hiện chính xác (ví dụ: khi chỉ thêm hai số), chúng ta vẫn có thể bị mất số nếu mantissa cần quá nhiều chữ số để khớp sau khi bình thường hóa số mũ.
Chúng tôi thực sự làm điều này mọi lúc khi chúng ta làm tròn số thập phân đến kích thước có thể quản lý và chỉ đưa ra một vài chữ số đầu tiên của nó. Bởi vì chúng tôi biểu thị kết quả bằng số thập phân, nó cảm thấy tự nhiên. Nhưng nếu chúng ta làm tròn một số thập phân và sau đó chuyển đổi nó sang một cơ sở khác, nó sẽ trông xấu xí như số thập phân chúng ta nhận được do làm tròn điểm nổi.