Isi:
Gambar: http://pikabu.ru/
Perkenalan
Pada hari-hari pertama mempelajari Java, saya menemukan jenis primitif yang aneh seperti bilangan floating point. Saya langsung tertarik dengan fitur-fiturnya dan, terlebih lagi, cara penulisannya dalam kode biner (yang saling berhubungan). Tidak seperti rentang bilangan bulat lainnya, bahkan dalam rentang yang sangat kecil (misalnya, dari 1 hingga 2) jumlahnya tidak terhingga. Dan karena ukuran memori yang terbatas, mustahil untuk mengekspresikan kumpulan ini. Jadi bagaimana cara mereka dinyatakan dalam biner dan bagaimana cara kerjanya? Sayangnya, penjelasan di
wiki dan artikel keren tentang Habré
di sini tidak memberi saya pemahaman yang lengkap, meskipun mereka meletakkan dasar. Realisasinya baru muncul setelah membaca
artikel analisis ini keesokan paginya setelah membacanya.
Tamasya ke dalam sejarah
(
diambil dari artikel di Habré ini ) Pada tahun 60-70an, ketika komputer berukuran besar dan program berukuran kecil, masih belum ada standar tunggal untuk penghitungan, serta standar untuk menyatakan bilangan floating point itu sendiri. Setiap komputer melakukannya secara berbeda, dan masing-masing memiliki kesalahannya sendiri. Namun pada pertengahan tahun 70-an, Intel memutuskan untuk membuat prosesor baru dengan dukungan aritmatika yang “ditingkatkan” sekaligus melakukan standarisasi. Profesor William Kahan dan John Palmer (bukan, bukan penulis buku tentang bir) dilibatkan untuk mengembangkannya. Ada beberapa drama, tapi standar baru dikembangkan. Sekarang standar ini disebut IEEE754
Format angka titik mengambang
Bahkan dalam buku pelajaran sekolah, setiap orang dihadapkan pada cara yang tidak biasa dalam menulis bilangan yang sangat besar atau sangat kecil berbentuk
1.2 × 10 3 atau
1.2 E3 , yaitu sama dengan
1.2 × 1000 = 1200 . Ini disebut metode notasi eksponensial. Dalam hal ini, kita berurusan dengan ekspresi suatu bilangan menggunakan rumus:
N=M×n p , di mana
- N = 1200 - angka yang dihasilkan
- M = 1,2 - mantissa - bagian pecahan, tanpa memperhitungkan ordo
- n = 10 adalah bilangan pokok keteraturan. Dalam hal ini dan ketika kita tidak berbicara tentang komputer, basisnya adalah angka 10
- p = 3 - derajat basa
Seringkali, basis ordo diasumsikan 10
dan hanya mantissa dan nilai basis yang ditulis, dipisahkan dengan huruf
E. Dalam contoh kita, saya memberikan entri yang setara
1.2 × 10 3 dan
1.2 E3 Jika semuanya sudah jelas, dan kita telah menyelesaikan perjalanan nostalgia ke dalam kurikulum sekolah, maka sekarang saya sarankan untuk melupakan ini, karena ketika membentuk bilangan floating point kita berhadapan dengan pangkat dua, bukan puluhan, mis.
n = 2 , seluruh rumus harmonis
1.2E3 rusak dan itu benar-benar merusak otak saya.
Tanda tangan dan gelar
Jadi apa yang kita punya? Hasilnya, kita juga memiliki bilangan biner, yang terdiri dari
mantissa - bagian yang akan kita pangkatkan dan pangkat itu sendiri. Selain itu, seperti halnya tipe integer, bilangan floating-point memiliki sedikit yang menentukan tanda - apakah bilangan tersebut positif atau negatif. Sebagai contoh, saya mengusulkan untuk mempertimbangkan tipe
float
yang terdiri dari 32 bit. Dengan bilangan presisi ganda,
double
logikanya sama, hanya saja jumlah bitnya dua kali lebih banyak. Dari 32 bit, yang paling signifikan pertama dialokasikan ke tanda, 8 bit berikutnya dialokasikan ke eksponen - pangkat yang akan kita naikkan mantissa, dan 23 bit sisanya - ke mantissa. Untuk mendemonstrasikannya, mari kita lihat sebuah contoh:
Bit pertama sangat sederhana. Jika nilai bit pertama
adalah 0 , maka angka yang kita peroleh akan
positif . Jika bitnya
1 , maka angkanya akan
negatif . Blok 8 bit berikutnya adalah blok eksponen. Eksponennya ditulis sebagai bilangan
delapan bit biasa , dan untuk mendapatkan derajat yang diperlukan kita perlu mengurangi
127 dari bilangan yang dihasilkan . Dalam kasus kita, delapan bit eksponennya adalah
10000001 . Ini sesuai dengan angka
129 . Jika Anda memiliki pertanyaan tentang cara menghitungnya, maka gambar menunjukkan jawaban singkatnya. Versi yang diperluas dapat diperoleh di kursus aljabar Boolean mana pun.
1×2 7 + 0×2 6 + 0×2 5 + 0×2 4 + 0×2 3 + 0×2 2 + 0×2 1 + 1×2 0 = 1×128 + 1×1 = 128+ 1=129 Tidak sulit untuk menghitung bahwa angka maksimum yang dapat kita peroleh dari 8 bit ini adalah
11111111 2 = 255 10 (subskrip
2 dan
10 berarti sistem bilangan biner dan desimal) Namun jika kita hanya menggunakan nilai eksponen positif (
dari 0 hingga 255 ), maka angka yang dihasilkan akan memiliki banyak angka sebelum koma, tetapi tidak setelahnya? Untuk mendapatkan nilai derajat negatif, Anda perlu mengurangi
127 dari eksponen yang dihasilkan . Jadi, kisaran derajatnya adalah
dari -127 hingga 128 . Dengan menggunakan contoh kita, gelar yang dibutuhkan adalah
129-127 = 2 . Mari kita ingat nomor ini untuk saat ini.
Mantissa
Sekarang tentang mantissa. Ini terdiri dari 23 bit, tetapi pada awalnya selalu ada unit lain yang tersirat, yang bitnya tidak dialokasikan. Hal ini dilakukan karena alasan kemanfaatan dan keekonomian. Bilangan yang sama dapat dinyatakan dalam pangkat yang berbeda dengan menambahkan angka nol pada mantissa sebelum atau sesudah koma. Cara termudah untuk memahaminya adalah dengan eksponen desimal:
120.000 = 1,2×10 5 = 0,12×10 6 = 0,012×10 7 = 0,0012×10 8 dst. Namun, dengan memasukkan nomor tetap di kepala mantissa, kami akan menerima nomor baru setiap saat. Anggap saja sebelum 23 bit kita akan ada satu lagi dengan satu. Biasanya bagian ini dipisahkan dari bagian lainnya dengan sebuah titik, namun tidak berarti apa-apa. Itu lebih nyaman 1. 1110000000000000000000000
Sekarang mantissa yang dihasilkan perlu dinaikkan pangkatnya dari kiri ke kanan, mengurangi pangkatnya satu per satu pada setiap langkah. Kita mulai dengan nilai pangkat yang kita peroleh dari hasil perhitungan yaitu
2 (sengaja saya memilih contoh sederhana agar tidak menuliskan setiap nilai pangkat dua dan tidak menghitungnya pada tabel di atas ketika bit yang bersangkutan adalah nol)
1×2 2 + 1×2 1 + 1×2 0 + 1×2 -1 = 1×4 + 1×2 + 1×1 + 1×0.5 = 4+2+1+0.5 = 7.5 dan mendapat hasilnya
7.5 , kebenarannya bisa dicek misalnya di
link ini
Hasil
Bilangan floating-point standar
float
terdiri dari 32 bit, bit pertama adalah tanda (+ atau -), delapan bit berikutnya adalah eksponen, 23 bit berikutnya adalah mantissa Dengan tanda - jika bit 0 adalah bilangan positif. Jika bit 1 negatif.
Secara eksponensial - kita ubah bitwise menjadi angka desimal (bit pertama dari kiri adalah
128 , yang kedua adalah
64 , yang ketiga adalah
32 , yang keempat adalah
16 , yang kelima adalah
8 , yang keenam adalah
4 , yang ketujuh adalah
2 , yang kedelapan adalah
1 ), kurangi
127 dari angka yang dihasilkan , kita mendapatkan derajat yang akan kita gunakan untuk memulai.
Menurut mantissa - ke 23 bit yang ada di depan kita menambahkan bit lain dengan nilai 1 dan dari situ kita mulai menaikkan pangkat yang kita terima, mengurangi pangkat ini dengan setiap bit berikutnya.
Itu saja semuanya, anak-anak! PS: Sebagai pekerjaan rumah, dengan menggunakan artikel ini, tinggalkan di komentar versi Anda mengapa kesalahan presisi terjadi pada sejumlah besar operasi aritmatika dengan bilangan floating point
GO TO FULL VERSION