浮点数的二进制表示学习笔记
基礎(chǔ)知識(shí):
十進(jìn)制轉(zhuǎn)十六進(jìn)制;
十六進(jìn)制轉(zhuǎn)二進(jìn)制;
IEEE制定的浮點(diǎn)數(shù)表示規(guī)則;
了解:
目前C/C++編譯器標(biāo)準(zhǔn)都遵照IEEE制定的浮點(diǎn)數(shù)表示法來(lái)進(jìn)行float,double運(yùn)算。這種結(jié)構(gòu)是一種科學(xué)計(jì)數(shù)法,用符號(hào)、指數(shù)和尾數(shù)來(lái)表示,底數(shù)定為2——即把一個(gè)浮點(diǎn)數(shù)表示為尾數(shù)乘以2的指數(shù)次方再添上符號(hào)。下面是具體的規(guī)格:
?????????????符號(hào)位?????階碼??????尾數(shù)?????長(zhǎng)度
float???????????1??????????8????????23??????32
double????????? 1?????????11??????? 52????? 64
?
以下通過(guò)幾個(gè)例子講解浮點(diǎn)數(shù)如何轉(zhuǎn)換為二進(jìn)制數(shù)
例一:
已知:double類型38414.4。
求:其對(duì)應(yīng)的二進(jìn)制表示。
分析:double類型共計(jì)64位,折合8字節(jié)。由最高到最低位分別是第63、62、61、……、0位:
????最高位63位是符號(hào)位,1表示該數(shù)為負(fù),0表示該數(shù)為正;
????62-52位,一共11位是指數(shù)位;
????51-0位,一共52位是尾數(shù)位。
?????步驟:按照IEEE浮點(diǎn)數(shù)表示法,下面先把38414.4轉(zhuǎn)換為十六進(jìn)制數(shù)。
??? ?把整數(shù)部和小數(shù)部分開(kāi)處理:整數(shù)部直接化十六進(jìn)制:960E。小數(shù)的處理:
0.4=0.5*0+0.25*1+0.125*1+0.0625*0+……
?????實(shí)際上這永遠(yuǎn)算不完!這就是著名的浮點(diǎn)數(shù)精度問(wèn)題。所以直到加上前面的整數(shù)部分算夠53位就行了。隱藏位技術(shù):最高位的1不寫入內(nèi)存(最終保留下來(lái)的還是52位)。
????如果你夠耐心,手工算到53位那么因該是:38414.4(10)=1001011000001110.0110011001100110011001100110011001100(2)
科學(xué)記數(shù)法為:1.0010110000011100110011001100110011001100110011001100,右移了15位,所以指數(shù)為15?;蛘呖梢匀缦吕斫?#xff1a;
1.0010110000011100110011001100110011001100110011001100×2^15
?????于是來(lái)看階碼,按IEEE標(biāo)準(zhǔn)一共11位,可以表示范圍是-1024?~?1023。因?yàn)橹笖?shù)可以為負(fù),為了便于計(jì)算,規(guī)定都先加上1023(2^10-1),在這里,階碼:15+1023=1038。二進(jìn)制表示為:100?00001110;
????符號(hào)位:因?yàn)?span lang="EN-US">38414.4為正對(duì)應(yīng)?為0;
????合在一起(注:尾數(shù)二進(jìn)制最高位的1不要):
01000000?11100010?11000001?110?01100? 11001100? 11001100? 11001100? 11001100
?
例二:
已知:整數(shù)3490593(16進(jìn)制表示為0x354321)。
求:其對(duì)應(yīng)的浮點(diǎn)數(shù)3490593.0的二進(jìn)制表示。?
解法如下:
先求出整數(shù)3490593的二進(jìn)制表示:
?H:?? ?3???? 5??? 4?? ?3??? 2?? ? 1???(十六進(jìn)制表示)
?B:?? 0011 ?0101 0100 0011 0010 ?0001?(二進(jìn)制表示)
????????│←─────??21────→│
?
即:?
???????????????1.1010101000011001000012×221
可見(jiàn),從左算起第一個(gè)1后有21位,我們將這21為作為浮點(diǎn)數(shù)的小數(shù)表示,單精度浮點(diǎn)數(shù)float由符號(hào)位1位,指數(shù)域位k=8位,小數(shù)域位(尾數(shù))n=23位構(gòu)成,因此對(duì)上面得到的21位小數(shù)位我們還需要補(bǔ)上2個(gè)0,得到浮點(diǎn)數(shù)的小數(shù)域表示為:
???????? 1 0101 0100 0011 0010 0001 00
?
float類型的偏置量Bias=2k-1-1=28-1-1=127,但還要補(bǔ)上剛才因?yàn)橛乙谱鳛樾?shù)部分的21位,因此偏置量為127+21=148,就是IEEE浮點(diǎn)數(shù)表示標(biāo)準(zhǔn):
????????????????????????? V = (-1)s×M×2E
??????????????????? E = e-Bias
中的e,此前計(jì)算Bias=127,剛好驗(yàn)證了E=148-127=21。
?
將148轉(zhuǎn)為二進(jìn)制表示為10010100,加上符號(hào)位0,最后得到二進(jìn)制浮點(diǎn)數(shù)表示1001010010101010000110010000100,其16進(jìn)制表示為:
?H:?? ??4?????? ?A????? ?5????????? 5????? ?? 0???????? C??????? ?8?????? ?4??
?B:??0100?? 1010?? 0101? ? 0101 ? 0000?? 1100? 1000?? 0100
??????????????????? |←────??????21????????─────→???|
???? 1|←─8?? ─→||←─────???????23???????─────→ |
?
這就是浮點(diǎn)數(shù)3490593.0(0x4A550C84)的二進(jìn)制表示。
?
例三:
0.5的二進(jìn)制形式是0.1
它用浮點(diǎn)數(shù)的形式寫出來(lái)是如下格式
?
0??????????????? 01111110???????????????? 00000000000000000000000
符號(hào)位???????????階碼???????????????????????小數(shù)位
正數(shù)符號(hào)位為0,負(fù)數(shù)符號(hào)位為1
階碼是以2為底的指數(shù)
小數(shù)位表示小數(shù)點(diǎn)后面的數(shù)字
下面我們來(lái)分析一下0.5是如何寫成0 01111110 00000000000000000000000
首先0.5是正數(shù)所以符號(hào)位為0
再來(lái)看階碼部分,0.5的二進(jìn)制數(shù)是0.1,而0.1是1.0*2^(-1),所以我們總結(jié)出來(lái):
要把二進(jìn)制數(shù)變成(1.f)*2^(exponent)的形式,其中exponent是指數(shù)
而由于階碼有正負(fù)之分所以階碼=127+exponent;
即階碼=127+(-1)=126?即?01111110
余下的小數(shù)位為二進(jìn)制小數(shù)點(diǎn)后面的數(shù)字,即00000000000000000000000
由以上分析得0.5的浮點(diǎn)數(shù)存儲(chǔ)形式為0 01111110 00000000000000000000000??
注:如果只有小數(shù)部分,那么需要右移小數(shù)點(diǎn).?比如右移3位才能放到第一個(gè)1的后面,?階碼就是127-3=124.
例四?? (20.59375)10 =(10100.10011?)2
首先分別將整數(shù)和分?jǐn)?shù)部分轉(zhuǎn)換成二進(jìn)制數(shù):?
20.59375=10100.10011?
然后移動(dòng)小數(shù)點(diǎn),使其在第1,2位之間?
10100.10011=1.010010011×2^4???即e=4?
于是得到:?
S=0,?E=4+127=131,?M=010010011?
最后得到32位浮點(diǎn)數(shù)的二進(jìn)制存儲(chǔ)格式為:?
0100 1001 1010 0100 1100 0000 0000 0000=(41A4C000)16
?
?
例五:
-12.5轉(zhuǎn)為單精度二進(jìn)制表示
12.5:?
1.?整數(shù)部分12,二進(jìn)制為1100;?小數(shù)部分0.5,?二進(jìn)制是.1,先把他們連起來(lái),從第一個(gè)1數(shù)起取24位(后面補(bǔ)0):?
1100.10000000000000000000?
這部分是有效數(shù)字。(把小數(shù)點(diǎn)前后兩部分連起來(lái)再取掉頭前的1,就是尾數(shù))?
2.?把小數(shù)點(diǎn)移到第一個(gè)1的后面,需要左移3位(1.10010000000000000000000*2^3),?加上偏移量127:127+3=130,二進(jìn)制是10000010,這是階碼。?
3. -12.5是負(fù)數(shù),所以符號(hào)位是1。把符號(hào)位,階碼和尾數(shù)連起來(lái)。注意,尾數(shù)的第一位總是1,所以規(guī)定不存這一位的1,只取后23位:?
1 10000010 10010000000000000000000?
把這32位按8位一節(jié)整理一下,得:?
11000001 01001000 00000000 00000000?
就是十六進(jìn)制的?C1480000.?
例六:
2.025675?
1.?整數(shù)部分2,二進(jìn)制為10;?小數(shù)部分0.025675,?二進(jìn)制是.0000011010010010101001,先把他們連起來(lái),從第一個(gè)1數(shù)起取24位(后面補(bǔ)0):?
10.0000011010010010101001?
這部分是有效數(shù)字。把小數(shù)點(diǎn)前后兩部分連起來(lái)再取掉頭前的1,就是尾數(shù): 00000011010010010101001?
2.?把小數(shù)點(diǎn)移到第一個(gè)1的后面,左移了1位,?加上偏移量127:127+1=128,二進(jìn)制是10000000,這是階碼。?
3. 2.025675是正數(shù),所以符號(hào)位是0。把符號(hào)位,階碼和尾數(shù)連起來(lái):?
0 10000000 00000011010010010101001?
把這32位按8位一節(jié)整理一下,得:?
01000000 00000001 10100100 10101001?
就是十六進(jìn)制的?4001A4A9.??
例七:
(逆向求十進(jìn)制整數(shù))一個(gè)浮點(diǎn)二進(jìn)制數(shù)手工轉(zhuǎn)換成十進(jìn)制數(shù)的例子:?
假設(shè)浮點(diǎn)二進(jìn)制數(shù)是?1011 1101 0100 0000 0000 0000 0000 0000?
按1,8,23位分成三段:?
1?01111010?10000000000000000000000?
最后一段是尾數(shù)。前面加上"1.",?就是?1.10000000000000000000000?
下面確定小數(shù)點(diǎn)位置。由E = e-Bias,階碼E是01111010,加上00000101才是01111111(127),?
所以他減去127的偏移量得e=-5。(或者化成十進(jìn)制得122,122-127=-5)。
因此尾數(shù)1.10(后面的0不寫了)是小數(shù)點(diǎn)右移5位的結(jié)果。要復(fù)原它就要左移5位小數(shù)點(diǎn),得0.0000110,?即十進(jìn)制的0.046875?。
最后是符號(hào):1代表負(fù)數(shù),所以最后的結(jié)果是?-0.046875?。
注意:其他機(jī)器的浮點(diǎn)數(shù)表示方法可能與此不同.?不能任意移植。
?
再看一例(類似例七):
比如:53004d3e
二進(jìn)制表示為:
01010011000000000100110100111110
按照1個(gè)符號(hào)??? 8個(gè)指數(shù)?? ???????23個(gè)小數(shù)位劃分
0????????????? 10100110???????? 00000000100110100111110
正確的結(jié)果轉(zhuǎn)出來(lái)應(yīng)該是551051722752.0
該怎么算?
好,我們根據(jù)IEEE的浮點(diǎn)數(shù)表示規(guī)則劃分,得到這個(gè)浮點(diǎn)數(shù)的小數(shù)位是:
?00000000100110100111110
那么它的二進(jìn)制表示就應(yīng)該是:
1.000000001001101001111102?×?239
這是怎么來(lái)的呢??別急,聽(tīng)我慢慢道來(lái)。
標(biāo)準(zhǔn)化公式中的M要求在規(guī)格化的情況下,取值范圍1<M<(2-ε)
正因?yàn)槿绱?#xff0c;我們才需要對(duì)原始的整數(shù)二進(jìn)制表示做偏移,偏移多少呢?偏移2E。
這個(gè)“E”怎么算?上面的239怎么得來(lái)的呢?浮點(diǎn)數(shù)表示中的8位指數(shù)為就是告訴這個(gè)的。我們知道:
E = e-Bias
那么根據(jù)指數(shù)位:
101001102=>16610
即e=166,由此算出E=e-Bias=166-127=39,就是說(shuō)將整數(shù)二進(jìn)制表示轉(zhuǎn)為標(biāo)準(zhǔn)的浮點(diǎn)數(shù)二進(jìn)制表示的時(shí)候需要將小數(shù)點(diǎn)左移39位,好,我們現(xiàn)在把它還原得到整數(shù)的二進(jìn)制表示:
1 00000000100110100111110 0000000000000000
1│←─────?23─────→│←?16─→│
23+16=39,后面接著就是小數(shù)點(diǎn)了。
拿出計(jì)算器,輸入二進(jìn)制數(shù)1000000001001101001111100000000000000000
轉(zhuǎn)為十進(jìn)制數(shù),不正是:551051722752么!
通過(guò)這例六例七,介紹了將整數(shù)二進(jìn)制表示轉(zhuǎn)浮點(diǎn)數(shù)二進(jìn)制表示的逆過(guò)程,還是希望大家不但能掌握轉(zhuǎn)化的方法,更要理解轉(zhuǎn)化的基本原理。
?
聲明:由于博客文本編輯功能沒(méi)有word強(qiáng)大,加上時(shí)間緊,所以在排版上的不足希望大家見(jiàn)諒。
最后祝大家學(xué)習(xí)愉快!!!?
與50位技術(shù)專家面對(duì)面20年技術(shù)見(jiàn)證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的浮点数的二进制表示学习笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 嵌入式Linux系统BSP的设计与实现
- 下一篇: RS232与RS485的功能与区别