(Catatan: Saya akan menambahkan 'b' untuk menunjukkan angka biner di sini. Semua angka lainnya diberikan dalam desimal)
Salah satu cara untuk memikirkan hal-hal adalah dalam hal sesuatu seperti notasi ilmiah. Kami terbiasa melihat angka yang dinyatakan dalam notasi ilmiah seperti, 6.022141 * 10 ^ 23. Angka-angka floating point disimpan secara internal menggunakan format yang sama - mantissa dan eksponen, tetapi menggunakan kekuatan dua bukan sepuluh.
61.0 Anda dapat ditulis ulang sebagai 1.90625 * 2 ^ 5, atau 1.11101b * 2 ^ 101b dengan mantissa dan eksponen. Untuk mengalikannya dengan sepuluh dan (memindahkan titik desimal), kita dapat melakukan:
(1.90625 * 2 ^ 5) * (1.25 * 2 ^ 3) = (2.3828125 * 2 ^ 8) = (1.19140625 * 2 ^ 9)
atau dengan mantissa dan eksponen dalam biner:
(1.11101b * 2 ^ 101b) * (1.01b * 2 ^ 11b) = (10.0110001b * 2 ^ 1000b) = (1,00110001b * 2 ^ 1001b)
Perhatikan apa yang kami lakukan di sana untuk mengalikan angka. Kami mengalikan mantisa dan menambahkan eksponen. Kemudian, karena mantissa berakhir lebih dari dua, kami menormalkan hasilnya dengan menabrak eksponen. Ini seperti ketika kita menyesuaikan eksponen setelah melakukan operasi pada angka dalam notasi desimal ilmiah. Dalam setiap kasus, nilai-nilai yang kami kerjakan memiliki representasi terbatas dalam biner, dan nilai-nilai yang dihasilkan oleh operasi perkalian dan penambahan dasar juga menghasilkan nilai-nilai dengan representasi terbatas.
Sekarang, pertimbangkan bagaimana kita akan membagi 61 dengan 10. Kita akan mulai dengan membagi mantra, 1.90625 dan 1.25. Dalam desimal, ini menghasilkan 1,525, angka pendek yang bagus. Tapi apa ini jika kita mengubahnya menjadi biner? Kami akan melakukannya dengan cara biasa - mengurangkan kekuatan terbesar dari dua bila memungkinkan, seperti mengubah desimal bilangan bulat menjadi biner, tetapi kami akan menggunakan kekuatan negatif dua:
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 ...
Uh oh. Sekarang kita dalam masalah. Ternyata 1.90625 / 1.25 = 1.525, adalah pecahan berulang ketika dinyatakan dalam biner: 1.11101b / 1.01b = 1.10000110011 ... b Mesin kami hanya memiliki begitu banyak bit untuk menahan mantissa itu dan karenanya mereka hanya akan membulatkan fraksi dan menganggap nol melebihi titik tertentu. Kesalahan yang Anda lihat ketika Anda membagi 61 dengan 10 adalah perbedaan antara:
1.100001100110011001100110011001100110011 ... b * 2 ^ 10b
dan, katakan:
1.1000011001100110011001100110b * 2 ^ 10b
Pembulatan mantissa inilah yang menyebabkan hilangnya presisi yang kami kaitkan dengan nilai floating point. Bahkan ketika mantissa dapat diekspresikan dengan tepat (misalnya, ketika hanya menambahkan dua angka), kita masih bisa mendapatkan kerugian numerik jika mantissa membutuhkan terlalu banyak digit agar pas setelah menormalkan eksponen.
Kami benar-benar melakukan hal semacam ini sepanjang waktu ketika kami membulatkan angka desimal ke ukuran yang dapat dikelola dan hanya memberikan beberapa digit pertama saja. Karena kami menyatakan hasilnya dalam desimal, rasanya alami. Tetapi jika kita membulatkan desimal dan mengubahnya menjadi basis yang berbeda, itu akan terlihat sama jeleknya dengan desimal yang kita dapatkan karena pembulatan titik mengambang.