浮點數在內存中的存儲方式(全網最詳細,來來來!!!!)


各位博客朋友大家好,相信有很多小伙伴在剛接觸數據類型的時候,都會糾結浮點數據是如何在內存中存儲,現在我們一起去探討這個問題?如果覺得有什么錯誤,歡迎各位小伙伴指出,好了,開始吧!!!

 

對於浮點類型數據,首先我們需要明白一點就是:浮點數和整數的編碼方式是差異甚大的

是嗎?我們舉個例子

#include <stdio.h>

int main()

{

       int a = 9;

       float *pFloat = (float *)&a;

       printf("%f\n",*pFloat);

      

       float b = 9.0;

       float *p = &b;

       printf("%f\n",*p);

      

       return 0;

}

 

運行結果:

 

 

 

從以上結果得知浮點數的存儲方式和整數是不一樣的。

那么,浮點數據是如何存儲的呢?

根據國際標准IEEE(電子與電氣工程協會)規定,任何浮點數的二進制數存儲都要遵循以下公式進行轉換:

       NUM = (-1) ^ s * M * 2 ^ E

來來來我們解釋一下:

       S : 當S為1時,表示為負浮點數,當S為0時,表示正浮點數

       M: 表示有效數 ,1<=M<2

      2^E: 表示指數

 

相信有同學看到上面的公式已經心情開始浮躁了,我自己當初也是和你們一樣,心浮氣躁,嗯,這不對的,這得改,所以同學們,我們要耐得住寂寞,讓我們保持着

平靜的心態繼續往下探索吧!!!!

首先了解一下浮點在內存的存儲方式,請看圖~~

 

 

 

那問題來了,s表示符號位,0為正數,1為負數,那好辦,這個位要么0,要么1,當然負數的存儲方式是不一樣的,我們本章節討論的是正浮點的情況,浮點的存儲方式,所以s為0

那e是什么呢?這八位存儲的內容又是什么?

首先我們先確定e(指數域的二進制表示)是如何得來的,計算的e的結果需要用以下公式

e = E + Bias

E : 從上面公式知道E為指數

E的計算方式如下:

       我們以135.5這個浮點數為標本

    (1) 取整數135轉換為二進制(不知道自己用計算器或者百度)為10000111

    (2) 取小數0.5轉換為二進制(方法為小數乘2取整數,不懂百度)為 0.5 * 2 = 1.0,所以小數位1,

          舉個例子:如果小數是0.375,計算方式為

            0.375 * 2 = 0.75         0

            0 . 75 * 2 = 1.5             1

            0.5 * 2 = 1.0                 1

            所以0.375轉換為二進制數值為 0.011 就是 011

 

  (3)那么可以得出135.5的二進制為10000111.1

  (4)將這個數值套進公式

    10000111.1 = (-1)^0 * (1.00001111)*2 ^ 7

   所以得出E的值為7

 

Bias : 是一個等於2^k-1 – 1的偏置值(k為指數域位數,對於32位浮點數是8,對於64位浮點數而言是11,因為我的是32位系統,所以k值為8),通過此方法可以得出Bias的值為

2^8-1 – 1 = 127

 

那么e = 7+127 = 134 轉換為二進制為 10000110

 

M : 小數部分 , 從上方可以得出結果為 00001111

 

好了,這樣就可以將  s ,     e ,                      M

                                  0       10000110      00001111 000000000000000

共32位.

所以得出結果,135.5在內存中的存儲方式如下

 0000 0000 低地址    0

1000 0000     -128(最高位1為負數)

0000 0111       7

0100 0011 高地址  67

                    

嗯,接下來驗證奇跡的時刻來了,寫個代碼測試以下

 

#include <stdio.h>

 

int main()

{

       float m = 135.5;

       char *a = (char *)&m;

      

       printf("0x%p = %d\n",a,*a);

       printf("0x%p = %d\n",a+1,*(a+1));

       printf("0x%p = %d\n",a+2,*(a+2));

       printf("0x%p = %d\n",a+3,*(a+3));

      

       return 0;

}

 

運行結果如下

 

 

 

從結果可以得出我們的認證是正確的,哦,對了,還可以知道我這個系統是小端模式

 

最后附錄自己分析的鬼畫符~~~~~

 

 

 

 

 

本人 測試的操做系統為32位的ubuntu 14.04

 

好了這就是今天所有的內容,拜拜,有什么疑問或者建議的小朋友,記得請留言呦,讓我們一起進步。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM