Adakah yang bisa menjelaskan representasi float dalam memori?

20

Ini bukan pertanyaan rangkap karena saya membaca pertanyaan sebelumnya.

Adakah yang bisa membantu saya dalam memahami how float values are stored in the memory.

Keraguan saya di sini adalah nilai float berisi ' .'( for example 3.45) bagaimana '.'akan diwakili dalam memori?

Adakah yang bisa menjelaskan saya dengan diagram?

pengguna2720323
sumber
21
Bagaimana dengan sumber yang paling tidak diharapkan, Wikipedia? en.wikipedia.org/wiki/Floating_point#Internal_representation
9000
4
Dan Anda dapat menambahkan artikel utama: IEEE floating point
mouviciel
4
Jika Anda seperti saya, dan Anda suka belajar dengan bermain dengan berbagai hal, memasukkan input dan menerima output, dll, periksa situs ini: binaryconvert.com/convert_double.html
KChaloux
Ada berbagai macam format floating-point LEBAR, semuanya berbeda. Titik apung IEEE adalah yang paling umum saat ini, tetapi bukan satu-satunya. Ketika saya masih mahasiswa, saya harus belajar format floating-point CDC 6600, dan itu memiliki beberapa keunggulan dibandingkan IEEE, yang terbesar adalah 48 bit mantissa untuk presisi tunggal. IEEE terbatas pada sekitar 24 bit mantissa untuk presisi tunggal, itulah sebabnya setiap kelas metode numerik pengantar hari ini memberitahu siswa "Selalu gunakan ganda, bukan mengambang."
John R. Strohm
Lihat floating-point-gui.de dan ingat URL itu
Basile Starynkevitch

Jawaban:

44

Titik desimal tidak secara eksplisit disimpan di mana pun; itu masalah tampilan.

Penjelasan berikut adalah penyederhanaan; Saya meninggalkan banyak detail penting dan contoh saya tidak dimaksudkan untuk mewakili platform dunia nyata. Seharusnya memberi Anda rasa tentang bagaimana nilai floating-point direpresentasikan dalam memori dan masalah yang terkait dengannya, tetapi Anda akan ingin menemukan sumber yang lebih otoritatif seperti Apa Yang Harus Diketahui Setiap Ilmuwan Komputer Tentang Aritmatika Titik Apung .

Mulailah dengan mewakili nilai titik-mengambang dalam varian notasi ilmiah, menggunakan basis 2 bukan basis 10. Misalnya, nilai 3.14159 dapat direpresentasikan sebagai

    0.7853975 * 2 2

0,7853975 adalah yang penting , alias mantissa; itu adalah bagian dari angka yang mengandung angka signifikan. Nilai ini dikalikan dengan basis 2 dinaikkan ke kekuatan 2 untuk mendapatkan 3.14159.

Bilangan floating-point dikodekan dengan menyimpan signifikansi dan eksponen (bersama dengan bit tanda).

Layout 32-bit yang khas terlihat seperti berikut:

 3 32222222 22211111111110000000000
 1 09876543 21098765432109876543210
+-+--------+-----------------------+
| |        |                       |
+-+--------+-----------------------+
 ^    ^                ^
 |    |                |
 |    |                +-- significand 
 |    |
 |    +------------------- exponent 
 |
 +------------------------ sign bit

Seperti tipe integer yang ditandatangani, bit orde tinggi menunjukkan tanda; 0 menunjukkan nilai positif, 1 menunjukkan negatif.

8 bit berikutnya digunakan untuk eksponen. Eksponen bisa positif atau negatif, tetapi alih-alih memesan bit tanda lain, mereka dikodekan sedemikian sehingga 10000000 mewakili 0, jadi 00000000 mewakili -128 dan 11111111 mewakili 127.

Bit yang tersisa digunakan untuk signifikansi. Setiap bit mewakili kekuatan negatif dari 2 penghitungan dari kiri, jadi:

    01101 = 0 * 2 -1 + 1 * 2 -2 + 1 * 2 -3 + 0 * 2 -4 + 1 * 2 -5 
          = 0,25 + 0,125 + 0,03125 
          = 0,40625

Beberapa platform mengasumsikan bit terkemuka "tersembunyi" di dalam signifand yang selalu ditetapkan ke 1, sehingga nilai-nilai di signifand selalu di antara [0,5, 1). Ini memungkinkan platform ini untuk menyimpan nilai dengan presisi yang sedikit lebih besar (lebih banyak tentang itu di bawah). Contoh saya tidak melakukan ini.

Jadi nilai kami dari 3.14159 akan direpresentasikan sebagai sesuatu seperti

    0 10000010 11001001000011111100111
    ^ ^ ^
    | | |
    | | + --- signifikansi = 0,7853975 ...
    | |
    | + ------------------- eksponen = 2 (130 - 128)
    |
    + ------------------------- tanda = 0 (positif)

    nilai = -1 (tanda) * 2 (eksponen) * (signifikan)
    nilai = -1 0 * 2 2 * 0,7853975 ...
    nilai = 3.14159 ...

Sekarang, sesuatu yang Anda akan perhatikan jika Anda menambahkan semua bit dalam signifikan adalah bahwa mereka tidak total 0,7853975; mereka benar-benar keluar ke 0.78539747. Tidak ada bit yang cukup untuk menyimpan nilai dengan tepat ; kita hanya bisa menyimpan aproksimasi. Jumlah bit dalam signifikan dan menentukan presisi , atau berapa banyak digit signifikan yang dapat Anda simpan. 23 bit memberi kita sekitar 6 digit desimal presisi. Tipe floating point 64-bit menawarkan bit yang cukup di signifikan dan memberikan sekitar 12 hingga 15 digit presisi. Namun ketahuilah bahwa ada nilai-nilai yang tidak dapat direpresentasikan dengan tepat bagaimanapun caranyabanyak bit yang Anda gunakan. Sama seperti nilai-nilai seperti 1/3 tidak dapat direpresentasikan dalam jumlah terbatas dari angka desimal, nilai-nilai seperti 1/10 tidak dapat direpresentasikan dalam jumlah bit terbatas. Karena nilai-nilai merupakan perkiraan, perhitungan dengan mereka juga merupakan perkiraan, dan kesalahan pembulatan menumpuk.

Jumlah bit dalam eksponen menentukan kisaran (nilai minimum dan maksimum yang dapat Anda wakili). Tetapi ketika Anda bergerak menuju nilai minimum dan maksimum Anda, ukuran kesenjangan antara nilai yang diwakili meningkat. Yaitu, jika Anda tidak bisa secara tepat merepresentasikan nilai antara 0.785397 dan 0.785398, maka Anda juga tidak bisa mewakili nilai antara 7.85397 dan 7.85398, atau nilai antara 78.5397 dan 78.5398, atau nilai antara 785397.0 dan 785398.0. Hati-hati ketika mengalikan angka yang sangat besar (dalam hal besarnya) dengan angka yang sangat kecil.

John Bode
sumber
"tetapi alih-alih memesan sedikit tanda lain" Apa yang Anda gambarkan adalah perilaku persis bilangan bulat yang ditandatangani.
Simon
6

Tidak .disimpan sama sekali. Pertama, Anda harus memahami notasi teknik, yang memiliki faktor presisi-tetap dan eksponen bilangan bulat: 1adalah 1,0 · 10 0 = 1.0E0, 2 adalah 2.0E0, 10 adalah 1.0E1dll. Ini memungkinkan untuk notasi yang sangat singkat dari sejumlah besar. Satu miliar 1.0E9. Faktor sebelum Ebiasanya dinotasikan sebagai jumlah tetap presisi: 1.00000E9. Hasil dari ini adalah bahwa angka satu miliar dan satu = 1.000.000.001 dan satu miliar keduanya sama dalam notasi ini, ketika presisi tidak cukup besar. Perhatikan juga bahwa faktor tidak pernah membutuhkan nol di depan. Sebaliknya, eksponen dapat dikurangi hingga tidak lagi menjadi kasus.

Dalam memori, angka floating point diwakili sama: Satu bit memiliki tanda, beberapa bit membentuk faktor sebagai angka presisi tetap ("mantissa"), bit yang tersisa membentuk eksponen. Perbedaan yang signifikan dengan notasi rekayasa basis-10 adalah bahwa tentu saja sekarang eksponen memiliki basis 2. Ukuran pasti dari setiap bagian tergantung pada standar titik apung yang Anda gunakan.

amon
sumber
3
Ini adalah "notasi ilmiah". "Rekayasa notasi" adalah ketika eksponen dibatasi ke kelipatan 3.
Clement J.
7
Basis 2 yang digunakan sangat penting. Ini menentukan nilai mana yang dapat disimpan dengan tepat dan mana yang tidak, dan bahkan jika Anda tidak dapat diganggu untuk mengembangkan intuisi yang nilainya (saya tahu saya tidak bisa), Anda setidaknya harus ingat bahwa angka desimal sama sekali tidak berguna cara berpikir tentang mengapung.
1
@ Delnan: Jika itu membantu, setiap bit di mantissa adalah setengah dari bit yang lebih tinggi. Jadi, pelampung dapat menyimpan jumlah kekuatan negatif dari dua: 1/2, 1/4, 1/8, 1/16, 1/32, 1/64, 1/128, dan seterusnya, hingga batas mantissa . Jadi epsilon dalam 32-bit floatadalah 2^-22 * exponent, atau sekitar 1/4194304.
greyfade