Dalam sebagian besar bahasa pemrograman, angka floating point diwakili banyak seperti notasi ilmiah : dengan eksponen dan mantra (juga disebut signifikansi). Angka yang sangat sederhana, katakanlah 9.2
, sebenarnya adalah fraksi ini:
5179139571476070 * 2 -49
Di mana eksponen -49
dan mantissa berada 5179139571476070
. Alasan mengapa tidak mungkin untuk mewakili beberapa angka desimal dengan cara ini adalah bahwa eksponen dan mantissa harus bilangan bulat. Dengan kata lain, semua pelampung harus berupa bilangan bulat dikalikan dengan kekuatan bilangan bulat 2 .
9.2
mungkin sederhana 92/10
, tetapi 10 tidak dapat dinyatakan sebagai 2 n jika n terbatas pada nilai integer.
Melihat Data
Pertama, beberapa fungsi untuk melihat komponen yang menghasilkan 32- dan 64-bit float
. Hapus ini jika Anda hanya peduli dengan output (contoh dalam Python):
def float_to_bin_parts(number, bits=64):
if bits == 32: # single precision
int_pack = 'I'
float_pack = 'f'
exponent_bits = 8
mantissa_bits = 23
exponent_bias = 127
elif bits == 64: # double precision. all python floats are this
int_pack = 'Q'
float_pack = 'd'
exponent_bits = 11
mantissa_bits = 52
exponent_bias = 1023
else:
raise ValueError, 'bits argument must be 32 or 64'
bin_iter = iter(bin(struct.unpack(int_pack, struct.pack(float_pack, number))[0])[2:].rjust(bits, '0'))
return [''.join(islice(bin_iter, x)) for x in (1, exponent_bits, mantissa_bits)]
Ada banyak kerumitan di balik fungsi itu, dan itu akan cukup jelas untuk dijelaskan, tetapi jika Anda tertarik, sumber daya penting untuk tujuan kita adalah modul struct .
Python float
adalah angka 64-bit, presisi ganda. Dalam bahasa lain seperti C, C ++, Java dan C #, presisi ganda memiliki tipe terpisah double
, yang sering diimplementasikan sebagai 64 bit.
Ketika kita memanggil fungsi itu dengan contoh kita 9.2
, inilah yang kita dapatkan:
>>> float_to_bin_parts(9.2)
['0', '10000000010', '0010011001100110011001100110011001100110011001100110']
Menafsirkan Data
Anda akan melihat saya telah membagi nilai kembali menjadi tiga komponen. Komponen-komponen ini adalah:
- Tanda
- Eksponen
- Mantissa (juga disebut Significand, atau Fraction)
Tanda
Tanda disimpan dalam komponen pertama sebagai bit tunggal. Sangat mudah dijelaskan: 0
berarti pelampung adalah angka positif; 1
berarti negatif. Karena 9.2
positif, nilai tanda kami adalah0
.
Eksponen
Eksponen disimpan di komponen tengah sebagai 11 bit. Dalam kasus kami 0b10000000010
,. Dalam desimal, itu mewakili nilai 1026
. Keunikan dari komponen ini adalah Anda harus mengurangi angka sama dengan 2 (# bit) - 1 - 1 untuk mendapatkan eksponen yang benar; dalam kasus kami, itu berarti mengurangi 0b1111111111
(angka desimal 1023
) untuk mendapatkan eksponen yang sebenarnya, 0b00000000011
(angka desimal 3).
Mantissa
Mantera disimpan dalam komponen ketiga sebagai 52 bit. Namun, ada kekhasan untuk komponen ini juga. Untuk memahami kekhasan ini, pertimbangkan nomor dalam notasi ilmiah, seperti ini:
6.0221413x10 23
Mantera akan menjadi 6.0221413
. Ingatlah bahwa mantissa dalam notasi ilmiah selalu dimulai dengan satu digit bukan nol. Hal yang sama berlaku untuk biner, kecuali bahwa biner hanya memiliki dua digit: 0
dan 1
. Jadi mantissa biner selalu dimulai dengan 1
! Ketika pelampung disimpan, 1
bagian depan biner mantissa dihilangkan untuk menghemat ruang; kita harus meletakkannya kembali di depan elemen ketiga kita untuk mendapatkan mantissa yang sebenarnya :
1,0010011001100110011001100110011001100110011001100110
Ini melibatkan lebih dari sekedar tambahan sederhana, karena bit yang disimpan dalam komponen ketiga kami sebenarnya mewakili bagian fraksional mantissa, di sebelah kanan titik radix .
Ketika berhadapan dengan angka desimal, kita "memindahkan titik desimal" dengan mengalikan atau membagi dengan kekuatan 10. Dalam biner, kita dapat melakukan hal yang sama dengan mengalikan atau membagi dengan kekuatan 2. Karena elemen ketiga kita memiliki 52 bit, kita membagi dengan 2 52 untuk memindahkannya 52 tempat ke kanan:
0,0010011001100110011001100110011001100110011001100110
Dalam notasi desimal, itu sama dengan membagi 675539944105574
oleh 4503599627370496
untuk mendapatkan 0.1499999999999999
. (Ini adalah salah satu contoh rasio yang dapat dinyatakan secara persis dalam biner, tetapi hanya kurang dalam desimal; untuk lebih jelasnya , lihat: 675539944105574/4503599627370496 .)
Sekarang kita telah mengubah komponen ketiga menjadi angka fraksional, menambahkan 1
memberi mantissa yang sebenarnya.
Memasang Kembali Komponen
- Tanda (komponen pertama):
0
untuk positif, 1
untuk negatif
- Eksponen (komponen tengah): Kurangi 2 (# bit) - 1 - 1 untuk mendapatkan eksponen yang benar
- Mantissa (komponen terakhir): Bagi dengan 2 (# bit) dan tambahkan
1
untuk mendapatkan mantissa yang sebenarnya
Menghitung Angka
Menyatukan ketiga bagian ini, kami diberi nomor biner ini:
1,0010011001100110011001100110011001100110011001100110 x 10 11
Yang kemudian dapat kita konversi dari biner ke desimal:
1.1499999999999999 x 2 3 (tidak eksak!)
Dan kalikan untuk mengungkapkan representasi akhir dari jumlah kami mulai dengan ( 9.2
) setelah disimpan sebagai nilai floating point:
9.1999999999999993
Mewakili sebagai Fraksi
9.2
Sekarang kita telah membangun nomornya, adalah mungkin untuk merekonstruksi menjadi pecahan sederhana:
1,0010011001100110011001100110011001100110011001100110 x 10 11
Pindahkan mantissa ke seluruh nomor:
10010011001100110011001100110011001100110011001100110 x 10 11-110100
Konversikan ke desimal:
5179139571476070 x 2 3-52
Kurangi eksponen:
5179139571476070 x 2 -49
Ubah eksponen negatif menjadi divisi:
5179139571476070/2 49
Gandakan eksponen:
5179139571476070/562949953421312
Yang sama dengan:
9.1999999999999993
9.5
>>> float_to_bin_parts(9.5)
['0', '10000000010', '0011000000000000000000000000000000000000000000000000']
Sudah Anda dapat melihat mantissa hanya 4 digit diikuti oleh banyak nol. Tapi mari kita pergi melalui langkah.
Merakit notasi ilmiah biner:
1,0011 x 10 11
Menggeser titik desimal:
10011 x 10 11-100
Kurangi eksponen:
10011 x 10 -1
Biner ke desimal:
19 x 2 -1
Eksponen negatif ke divisi:
19/2 1
Gandakan eksponen:
19/2
Sama dengan:
9.5
Bacaan lebih lanjut