1樓:匿名使用者
目前c/c++編譯器標準都遵照ieee制定的浮點數表示法來進行float,double運算。這種結構是一種科學計數法,用符號、指數和尾數來表示,底數定為2——即把一個浮點數表示為尾數乘以2的指數次方再添上符號。下面是具體的規格:
符號位 階碼 尾數 長度
float 1 8 23 32
double 1 11 52 64
以下通過幾個例子講解浮點數如何轉換為二進位制數
例一:已知:double型別38414.4。
求:其對應的二進位制表示。
分析:double型別共計64位,摺合8位元組。由最高到最低位分別是第63、62、61、……、0位:
最高位63位是符號位,1表示該數為負,0表示該數為正;
62-52位,一共11位是指數位;
51-0位,一共52位是尾數位。
步驟:按照ieee浮點數表示法,下面先把38414.4轉換為十六進位制數。
把整數部和小數部分開處理:整數部直接化十六進位制:960e。小數的處理:
0.4=0.5*0+0.25*1+0.125*1+0.0625*0+……
實際上這永遠算不完!這就是著名的浮點數精度問題。所以直到加上前面的整數部分算夠53位就行了。隱藏位技術:最高位的1不寫入記憶體(最終保留下來的還是52位)。
如果你夠耐心,手工算到53位那麼因該是:38414.4(10)=1001011000001110.0110011001100110011001100110011001100(2)
科學記數法為:1.001011000001110 0110011001100110011001100110011001100,右移了15位,所以指數為15。或者可以如下理解:
1.001011000001110 0110011001100110011001100110011001100×2^15
於是來看階碼,按ieee標準一共11位,可以表示範圍是-1024 ~ 1023。因為指數可以為負,為了便於計算,規定都先加上1023(2^10-1),在這裡,階碼:15+1023=1038。
二進位制表示為:100 00001110;
符號位:因為38414.4為正對應 為0;
合在一起(注:尾數二進位制最高位的1不要):
01000000 11100010 11000001 110 01100 11001100 11001100 11001100 11001100
例二:已知:整數3490593(16進製表示為0x354321)。
求:其對應的浮點數3490593.0的二進位制表示。
解法如下:
先求出整數3490593的二進位制表示:
h: 3 5 4 3 2 1 (十六進位制表示)
b: 0011 0101 0100 0011 0010 0001 (二進位制表示)
│←───── 21────→│
即: 1.1010101000011001000012×221
可見,從左算起第一個1後有21位,我們將這21為作為浮點數的小數表示,單精度浮點數float由符號位1位,指數域位k=8位,小數域位(尾數)n=23位構成,因此對上面得到的21位小數位我們還需要補上2個0,得到浮點數的小數域表示為:
1 0101 0100 0011 0010 0001 00
float型別的偏置量bias=2k-1-1=28-1-1=127,但還要補上剛才因為右移作為小數部分的21位,因此偏置量為127+21=148,就是ieee浮點數表示標準:
v = (-1)s×m×2e
e = e-bias
中的e,此前計算bias=127,剛好驗證了e=148-127=21。
將148轉為二進位制表示為10010100,加上符號位0,最後得到二進位制浮點數表示1001010010101010000110010000100,其16進製表示為:
h: 4 a 5 5 0 c 8 4
b: 0100 1010 0101 0101 0000 1100 1000 0100
|←──── 21 ─────→ |
1|←─8 ─→||←───── 23 ─────→ |
這就是浮點數3490593.0(0x4a550c84)的二進位制表示。
例三:0.5的二進位制形式是0.1
它用浮點數的形式寫出來是如下格式
0 01111110 00000000000000000000000
符號位 階碼 小數位
正數符號位為0,負數符號位為1
階碼是以2為底的指數
小數位表示小數點後面的數字
下面我們來分析一下0.5是如何寫成0 01111110 00000000000000000000000
首先0.5是正數所以符號位為0
再來看階碼部分,0.5的二進位制數是0.1,而0.1是1.0*2^(-1),所以我們總結出來:
要把二進位制數變成(1.f)*2^(exponent)的形式,其中exponent是指數
而由於階碼有正負之分所以階碼=127+exponent;
即階碼=127+(-1)=126 即 01111110
餘下的小數位為二進位制小數點後面的數字,即00000000000000000000000
由以上分析得0.5的浮點數儲存形式為0 01111110 00000000000000000000000
注:如果只有小數部分,那麼需要右移小數點. 比如右移3位才能放到第一個1的後面, 階碼就是127-3=124.
例四 (20.59375)10 =(10100.10011 )2
首先分別將整數和分數部分轉換成二進位制數:
20.59375=10100.10011
然後移動小數點,使其在第1,2位之間
10100.10011=1.010010011×2^4 即e=4
於是得到:
s=0, e=4+127=131, m=010010011
最後得到32位浮點數的二進位制儲存格式為:
0100 1001 1010 0100 1100 0000 0000 0000=(41a4c000)16
例五:-12.5轉為單精度二進位制表示
12.5:
1. 整數部分12,二進位制為1100; 小數部分0.5, 二進位制是.1,先把他們連起來,從第一個1數起取24位(後面補0):
1100.10000000000000000000
這部分是有效數字。(把小數點前後兩部分連起來再取掉頭前的1,就是尾數)
2. 把小數點移到第一個1的後面,需要左移3位(1.10010000000000000000000*2^3), 加上偏移量127:
127+3=130,二進位制是10000010,這是階碼。
3. -12.5是負數,所以符號位是1。把符號位,階碼和尾數連起來。注意,尾數的第一位總是1,所以規定不存這一位的1,只取後23位:
1 10000010 10010000000000000000000
把這32位按8位一節整理一下,得:
11000001 01001000 00000000 00000000
就是十六進位制的 c1480000.
例六:2.025675
1. 整數部分2,二進位制為10; 小數部分0.025675, 二進位制是.0000011010010010101001,先把他們連起來,從第一個1數起取24位(後面補0):
10.0000011010010010101001
這部分是有效數字。把小數點前後兩部分連起來再取掉頭前的1,就是尾數: 00000011010010010101001
2. 把小數點移到第一個1的後面,左移了1位, 加上偏移量127:127+1=128,二進位制是10000000,這是階碼。
3. 2.025675是正數,所以符號位是0。把符號位,階碼和尾數連起來:
0 10000000 00000011010010010101001
把這32位按8位一節整理一下,得:
01000000 00000001 10100100 10101001
就是十六進位制的 4001a4a9.
例七:(逆向求十進位制整數)一個浮點二進位制數手工轉換成十進位制數的例子:
假設浮點二進位制數是 1011 1101 0100 0000 0000 0000 0000 0000
按1,8,23位分成三段:
1 01111010 10000000000000000000000
最後一段是尾數。前面加上"1.", 就是 1.10000000000000000000000
下面確定小數點位置。由e = e-bias,階碼e是01111010,加上00000101才是01111111(127),
所以他減去127的偏移量得e=-5。(或者化成十進位制得122,122-127=-5)。
因此尾數1.10(後面的0不寫了)是小數點右移5位的結果。要復原它就要左移5位小數點,得0.0000110, 即十進位制的0.046875 。
最後是符號:1代表負數,所以最後的結果是 -0.046875 。
注意:其他機器的浮點數表示方法可能與此不同. 不能任意移植。
再看一例(類似例七):
比如:53004d3e
二進位制表示為:
01010011000000000100110100111110
按照1個符號 8個指數 23個小數位劃分
0 10100110 00000000100110100111110
正確的結果轉出來應該是551051722752.0
該怎麼算?
好,我們根據ieee的浮點數表示規則劃分,得到這個浮點數的小數位是:
00000000100110100111110
那麼它的二進位制表示就應該是:
1.000000001001101001111102 × 239
這是怎麼來的呢? 別急,聽我慢慢道來。
標準化公式中的m要求在規格化的情況下,取值範圍116610
即e=166,由此算出e=e-bias=166-127=39,就是說將整數二進位制表示轉為標準的浮點數二進位制表示的時候需要將小數點左移39位,好,我們現在把它還原得到整數的二進位制表示:
1 00000000100110100111110 0000000000000000
1│←───── 23─────→│← 16─→│
23+16=39,後面接著就是小數點了。
拿出計算器,輸入二進位制數1000000001001101001111100000000000000000
轉為十進位制數,不正是:551051722752麼!
通過這例六例七,介紹了將整數二進位制表示轉浮點數二進位制表示的逆過程,還是希望大家不但能掌握轉化的方法,更要理解轉化的基本原理。
二進位制8位能表示的數用十六進位制表示的範圍是
二進位制8位能表示的數用十六進位制表示的範圍是 7f h到 80 h。16進位制有16個數,0 15,用二進位制表示15的方法就是1111,從而可以推斷出,16進位制用2進位制可以表現成0000 1111,顧名思義,也就是每四個為一位。即二進位制數到十六進位制數的轉換方法為從小數點開始,分別向左 右...
二進位制八進位制十進位制十六進位制表二進位制十進位制八進位制十六進位制的對應表
1 二進位制 數 八進位制數 十六進 制數轉十進位制數 有一個公式 二進位制數 八進位制數 十六進位制數的各位數字分別乖以各自的基數的 n 1 次方,其和相加之和便是相應的十進位制數。個位,n 1 十位,n 2.舉例 110b 1 2的2次方 1 2的1次方 0 2的0次方 0 4 2 0 6d 1...
十六位二進位制數的最小值十進位制表示
十六位二進位制數的最小值,視情況而定。如果看為無符號數,則為0 如果看為有符號數,則為 32768。16進位制最大能表示10進位制數是多少?1個位元組 最大0xff 255 存 儲型別byte和char 2個位元組 最大0xff ff 65535 儲存型別shot int 4個位元組 最大0xff ...