在學習C的過程當中,遇到了這個問題,查了一下,下面是轉載內容。網絡
上面咱們說了,浮點數的小數點是不固定的,若是每一個人都按照本身的愛好存儲在電腦裏,那不就亂套了嗎?那麼怎麼在計算機中存儲這種類型的數字呢?象這類古老的問題前人早都爲咱們作好了相應的規範,無規矩不成方圓嗎。咱們平時所說的浮點數的存儲規範,就是由IEEE指定的,具體的規範文件是:IEEE Standard 754 for Binary Floating-Point Arithmetic。你們能夠很容易的從網絡上下載到這篇文檔。ide
下面,偶就大體的描述一下,感興趣的「同志」們能夠閱讀原文。學習
--------------------------------------------------------
聲明:
此文爲原創,歡迎轉載,轉載請保留以下信息
做者:afreez 北京-中關村
聯繫方式:afreez.gan@gmail.com (歡迎與做者交流)
初次發佈時間:
初次發佈在: http://blog.csdn.net/ganxingming/
不經本人贊成,不得用語商業或贏利性質目的,不然,做者有權追究相關責任!
---------------------------------------------------------
在c語言中,單精度(float)數據類型爲32bits,具體的以下圖所示:文檔
整個32bits分三部分,即get
Sign:符號位,1 bit,0爲正,1爲負;it
Exponent(bias):指數部分,8 bits,存儲格式爲移碼存儲(後面還會說明),偏移量爲127;
Mantissa(fraction):尾數部分。
對應的雙精度(double)類型的格式爲:
一樣,64位也被分爲了三部分,對照單精度,不用我說就能夠理解各個部分的含義了吧?
是否是有點迷糊了,不要怕,理論這個東西最能忽悠人了,看起來很高深,其實也就是個屁大的事,舉個例子就很容易明白了。
舉例說明,如3.24x103,則對應的部分爲,Sign爲0,3爲指數部分(注意計算機裏面存儲的不是3,這裏僅僅爲了說明),3.24爲尾數。咱們知道,計算機「笨」的要死,只認識0和1,那麼到底一個浮點數值在計算機存儲介質中是如何存儲的呢?
例如,咱們要想偷窺浮點類型的值4.25在計算機硬盤中存儲的廬山真面目,請跟我來:首先把4.25轉換成二進制的表達方式,即100.01,在詳細點,變成1.0001x22,好了,對號入座把。
Sign=0;
Exponent(bias)=2+127=129 (偏移量爲127,就是直接加上個127了);
Mantissa=1.0001-1.0=0001(規格化後,小數點前老是整數1,全世界人都知道前面是1不是0,因此省略不寫了,即尾數部分不包括整數部分;當別人問你,爲何23 bit的尾數部分能夠表示24位的精度,知道怎麼回答了吧。 靠,什麼,沒有看懂,再仔細讀兩便就知道了)。
對照上面的圖示,相信你已經看明白了吧?相信你的智商。爲了加深認識,再來一個。若是給定你一個二進制數字串,01000000100010000000000000000000,並告訴你這是一個float類型的值,讓你說出它是老幾,知道怎麼算了吧?若是不知道,看下面的圖,我就不廢話解釋了。
爲了更深刻的理解浮點數的格式。咱們使用C語言來作一件事。在C語言的世界裏,強制類型轉換,你們應該都很熟悉了。例如:
…
float f=4.6;
int i;
…
i = (int)(f+0.5); // i=5
..
下面咱們不使用強制類型轉化,咱們本身來計算f轉換成×××應該等於幾?
把主要代碼帖出來,以下:
//取23+1位的尾數部分
int ival= ((*(int *)(&fval)) & 0x07fffff) | 0x800000;
// 提取指數部分
int exponent = 150 - (((*(int *)(&fval)) >> 23) & 0xff);
if (exponent < 0)
ival = (ival<< -exponent);
else
ival = (ival >> exponent);
// 若是小於0,則將結果取反
if ((*(int *)&fval) & 0x80000000)
ival = -ival;
好好琢磨琢磨吧,看明白了,就說明你基本明白了浮點數的存儲格式,若是沒有看明白,接着看,知道明白爲止。
轉載地址:http://blog.csdn.net/ganxingming/article/details/1449526