計(jì)算機(jī)中浮點(diǎn)數(shù)的表示

浮點(diǎn)數(shù)轉(zhuǎn)二進(jìn)制浮點(diǎn)數(shù)

整數(shù)部分:

  1. 整數(shù)部分不斷除以2,保存商和余數(shù)侈离。
  2. 判斷商是否等于0树绩,如果等于0到第3步萨脑,否則回到第1步。
  3. 將每一步得到的余數(shù)倒序保存饺饭,得到整數(shù)部分的二進(jìn)制表示渤早。

小數(shù)部分:

  1. 小數(shù)部分不斷乘以2,保存結(jié)果的整數(shù)和小數(shù)瘫俊。
  2. 判斷結(jié)果的整數(shù)是否等于1鹊杖,如果等于1到第3步悴灵,否則回到第1步。
  3. 將每一步結(jié)果的所有整數(shù)順序保存骂蓖,就得到小數(shù)的二進(jìn)制表示

例如:浮點(diǎn)數(shù) 4.8125
整數(shù)部分:

4/2     = 2     0
2/2     = 1     0
1/2     = 0     1
所以整數(shù)部分 4 的二進(jìn)制為 100

小數(shù)部分:

0.8125*2    = 1.625     1
0.625*2     = 1.25      1
0.25*2      = 0.5       0
0.5*2       = 1.0       1
所以小數(shù)部分 0.8125 的二進(jìn)制位 1101

將整數(shù)與小數(shù)部分連接起來就是 100.1101积瞒,即4.8125=100.1101_2

再如:浮點(diǎn)數(shù) 0.05
因?yàn)橹挥行?shù)所以只處理小數(shù)部分:

0.05*2      = 0.1 0
0.1*2       = 0.2 0
0.2*2       = 0.4 0
0.4*2       = 0.8 0

0.8*2       = 1.6 1
0.6*2       = 1.2 1
0.2*2       = 0.4 0
0.4*2       = 0.8 0

0.8*2       = 1.6 1
0.6*2       = 1.2 1
0.2*2       = 0.4 0
0.4*2       = 0.8 0

0.8*2       = 1.6 1 
......      無限循環(huán)


所以0.05的二進(jìn)制 = 0.0000 1100 1100 1100 1100 1100 1101 .... 

可以看到二進(jìn)制小數(shù)是無法準(zhǔn)確表示浮點(diǎn)數(shù)的,所以就有了精度一說.
單精度浮點(diǎn)數(shù)用32位二進(jìn)制表示如下:

符號(hào)位1位  階碼8位  小數(shù)位23位
單精度.jpg

雙精度浮點(diǎn)數(shù)用64位二進(jìn)制表示如下:

符號(hào)位1位  階碼11位  小數(shù)位52位
雙精度.png

由上可知登下,
單精度浮點(diǎn)數(shù)精度為 pow(2,23) = 8388608 = 0.8388608 x pow(10,7)
所以單精度浮點(diǎn)數(shù)對(duì)應(yīng)的10進(jìn)制精度為 7 位多
雙精度浮點(diǎn)數(shù)精度為 pow(2,52)-1 = 4503599627370496 = 0.4503599627370496 x pow(10,16)
所以雙精度浮點(diǎn)數(shù)對(duì)應(yīng)的10進(jìn)制精度為 16 位多

浮點(diǎn)數(shù)的計(jì)算機(jī)表示 (IEEE754標(biāo)準(zhǔn))

移碼(又叫增碼)是由補(bǔ)碼的符號(hào)位取反得到赡鲜,一般用指數(shù)的移碼減去1來做浮點(diǎn)數(shù)的階碼,
引入的目的是便于浮點(diǎn)數(shù)運(yùn)算時(shí)的對(duì)階操作庐船。為了保證浮點(diǎn)數(shù)的機(jī)器零為全0银酬。

對(duì)于定點(diǎn)整數(shù),計(jì)算機(jī)一般采用補(bǔ)碼的來存儲(chǔ)筐钟。
正整數(shù)的符號(hào)位為 0揩瞪,反碼、補(bǔ)碼篓冲、原碼都一樣李破。
負(fù)整數(shù)的符號(hào)位為 1,原碼壹将、反碼和補(bǔ)碼的表示各不相同嗤攻,

由原碼變成反碼和補(bǔ)碼有如下規(guī)則:

  1. 原碼符號(hào)位為1不變,整數(shù)的每一位二進(jìn)制數(shù)位取反得到反碼诽俯;
  2. 反碼符號(hào)位為1不變妇菱,反碼數(shù)值位最低位加1得補(bǔ)碼。
比如暴区,以一個(gè)字節(jié) 8bits 來表示 -3闯团,
那么-3的各種碼,原碼-->反碼-->補(bǔ)碼--->移碼
原碼:[ ? 3 ] = 1 000001 1仙粱,最高位1位符號(hào)位
反碼:[ ? 3 ] = 1 111110 0房交,原碼符號(hào)位不變,其他位取反
補(bǔ)碼:[ ? 3 ] = 1 111110 1伐割,反碼符號(hào)為不變候味,最低位加1
移碼:[ ? 3 ] = 0 111110 1,補(bǔ)碼符號(hào)為取反

浮點(diǎn)數(shù)二進(jìn)制表示:
V=(-1)^s*(1.M)*2^E

s:符號(hào)位隔心,0正數(shù)白群,1負(fù)數(shù)
M:小數(shù)部分,使用原碼表示
E:階碼济炎,使用其原碼+127表示或者用其移碼-1表示川抡,

比如十進(jìn)制4.5的單精度浮點(diǎn)數(shù)的二進(jìn)制 = 100.1_2 表示為上述公式則為
4.5=(-1)^0*(1.001)*2^2
看到這里的E2,那么它在計(jì)算機(jī)實(shí)際存儲(chǔ)為 2 + 127 = 129 = 10000001_2

根據(jù)上面的公式各部分表示的規(guī)則得到一個(gè)32位浮點(diǎn)數(shù)表示如下表:

符號(hào)位s:1位 階碼E:2~9位 小數(shù)位M:10~32位
0 2+127=129 001
0 10000001 00100000000000000000000

符號(hào)位為0表示是正數(shù),所以4.5的二進(jìn)制存儲(chǔ)為0 10000001 00100000000000000000000,即1000000100100000000000000000000_2 = 0x40900000

以下tool.c是一個(gè)測(cè)試工具:

// tool.c
#include <stdio.h>
#include <stdlib.h>
// 打印一個(gè)計(jì)算機(jī)存儲(chǔ)的浮點(diǎn)數(shù)值
void print_bin_to_float(unsigned long hex){
    float* fp=(float*)&hex;
    printf("%lx,%f\n",hex,*fp);
}
// 打印一個(gè)浮點(diǎn)數(shù)在計(jì)算機(jī)存儲(chǔ)的十六進(jìn)制表示
void print_float_to_bin(float f){
    unsigned long* pf = (unsigned long*)&f;;
    printf("%f,0x%lx\n",f,*pf);

}
// 反轉(zhuǎn)字符串
char * reverse_str(char *str, long len){
    char    *start = str;
    char    *end = str + len - 1;
    char    ch;

    if (str != NULL)
    {
        while (start < end)
        {
            ch = *start;
            *start++ = *end;
            *end-- = ch;
        }
    }
    return str;
}
// 十六進(jìn)制轉(zhuǎn)二進(jìn)制字符串
char * hex_to_bin(unsigned long long hex,int bin_max_len){
    printf("0x%llx,hex_to_bin:\n",hex);
    char bin_ar[1024] = {0};
    long count = 0;
    unsigned long long quotient = 0;
    int remainder = 0;
    do{
        quotient = hex / 2;   
        remainder = hex % 2;
        //轉(zhuǎn)換成顯示的數(shù)字字符 
        char save = '0' + remainder;
        bin_ar[count] = save;

        hex = quotient;
        count ++;

    } while (quotient != 0);
    while (count < bin_max_len){ 
        bin_ar[count] = '0';
        count ++;
    }
    char *result = reverse_str(bin_ar,count);
    printf("0b%s\n",result);
    printf("\n");
    return result;
}
int main(){
    print_float_to_bin(4.5);        // 0x40900000
    print_float_to_bin(0.5);        // 0x3f000000
    print_float_to_bin(0.05);       // 0x3d4ccccd
    print_float_to_bin(0.15625);    // 0x3e200000

    /*
    4.5
    0x40900000,hex_to_bin:
    0b01000000100100000000000000000000
    */
    hex_to_bin(0x40900000,32);

    return 0;
}



下面是我們把上述二進(jìn)制轉(zhuǎn)為二進(jìn)制浮點(diǎn)數(shù)

4.5
0x40900000 十六進(jìn)制表示
sign    exponent    fraction
0       10000001    00100000000000000000000
0       129         00100000000000000000000
階碼 129-127 = 2
0       2           00100000000000000000000
先向右移動(dòng)小數(shù)點(diǎn)2位
0       2           00.100000000000000000000
在向首位補(bǔ)1
0       2         1 00.100000000000000000000
結(jié)果 100.100000000000000000000

如果得到階碼是負(fù)數(shù)比如下面的0.50.05崖堤,規(guī)則是先在首位補(bǔ)1侍咱,然后向左移動(dòng)小數(shù)點(diǎn),不夠補(bǔ)0

0.5
0x3f000000 十六進(jìn)制表示
sign    exponent    fraction
0       01111110    00000000000000000000000
0       01111110    00000000000000000000000
0       126         00000000000000000000000
階碼 126-127 = -1
0       -1          00000000000000000000000
先在左側(cè)補(bǔ)1
0       -1        1 00000000000000000000000
再向左移動(dòng)小點(diǎn)1位
0       -1      0.1 00000000000000000000000
結(jié)果就是 0.1 00000000000000000000000

0.05
0x3d4ccccd 十六進(jìn)制表示
sign    exponent    fraction
0       01111010    10011001100110011001101
0       122         10011001100110011001101
階碼 122-127 = -5
0       -5          10011001100110011001101
先在左側(cè)補(bǔ)1
0       -5        1 10011001100110011001101
再向左移動(dòng)小點(diǎn)5位密幔,不夠插入0
0   -1      0.00001 10011001100110011001101

結(jié)果就是 0.0000110011001100110011001101

綜上我們知道
階碼為正小數(shù)點(diǎn)右移楔脯,先移動(dòng)小數(shù)點(diǎn)再補(bǔ)1
階碼為負(fù)小數(shù)點(diǎn)左移胯甩,先補(bǔ)1再移動(dòng)小數(shù)點(diǎn)昧廷,不足補(bǔ)0

二進(jìn)制浮點(diǎn)數(shù)轉(zhuǎn)10進(jìn)制浮點(diǎn)數(shù),這里是單精度偎箫,雙精度同理

0.15625
0x3e200000
sign    exponent    fraction
0       01111100    01000000000000000000000
0       01111100    01000000000000000000000
0       124         01000000000000000000000
0       -3          01000000000000000000000
先在左側(cè)補(bǔ)1
0       -3          1 01000000000000000000000
再向左移動(dòng)小點(diǎn)3位木柬,不夠插入0
0       -3          0.001 01000000000000000000000
結(jié)果就是 0.00101000000000000000000000 = 0.00101



根據(jù)公式定義:
V=(-1)^s*1.M*2^E

0.15625二進(jìn)制表示如下:
V=(-1)^0*1.01*2^{-3}

轉(zhuǎn)換如下:
sign=+1
exponent = (-127) + 124 = -3
fraction = 1*2^0 + 0*2^{-1} + 1 * 2^{-2} = 1.25
value= (+1) * 1.25 * 2^{-3} = +0.15625

參考

IEEE754 Wiki
單精度浮點(diǎn)數(shù)
雙精度浮點(diǎn)數(shù)
浮點(diǎn)數(shù)表示
二進(jìn)制浮點(diǎn)數(shù)在線轉(zhuǎn)換

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市淹办,隨后出現(xiàn)的幾起案子眉枕,更是在濱河造成了極大的恐慌,老刑警劉巖怜森,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件速挑,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡副硅,警方通過查閱死者的電腦和手機(jī)姥宝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恐疲,“玉大人腊满,你說我怎么就攤上這事×魑疲” “怎么了糜烹?”我有些...
    開封第一講書人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵违诗,是天一觀的道長(zhǎng)漱凝。 經(jīng)常有香客問我,道長(zhǎng)诸迟,這世上最難降的妖魔是什么茸炒? 我笑而不...
    開封第一講書人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮阵苇,結(jié)果婚禮上壁公,老公的妹妹穿的比我還像新娘。我一直安慰自己绅项,他們只是感情好紊册,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般囊陡。 火紅的嫁衣襯著肌膚如雪芳绩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,158評(píng)論 1 308
  • 那天撞反,我揣著相機(jī)與錄音妥色,去河邊找鬼。 笑死遏片,一個(gè)胖子當(dāng)著我的面吹牛嘹害,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吮便,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼笔呀,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了髓需?” 一聲冷哼從身側(cè)響起凿可,我...
    開封第一講書人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎授账,沒想到半個(gè)月后枯跑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡白热,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年敛助,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屋确。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纳击,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出攻臀,到底是詐尸還是另有隱情焕数,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布刨啸,位于F島的核電站堡赔,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏设联。R本人自食惡果不足惜善已,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望离例。 院中可真熱鬧换团,春花似錦、人聲如沸宫蛆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至想虎,卻和暖如春衰絮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背磷醋。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工猫牡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人邓线。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓淌友,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親骇陈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子震庭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容