C++浮點型的存儲方式詳解

浮點型及其存儲方式

有些時候需要變量能存儲帶小數點的數,或者能存儲極大數或極小數。這類數可以用浮點(因小數點是“浮動的”而得名)格式進行存儲。C語言提供瞭3種浮點類型,對應三種不同的浮點格式。

當精度要求不嚴格時(小數點後少於六位),float類型是很適合的類型。double提供更高的精度, 對絕大多數程序來說夠用瞭。longdouble支持極高精度的要求,很少會用到。

C標準沒有說明float、double和long double類型提供的的精度到底是多少,因為不同計算機可以用不同方法存儲浮點數。大多數現代計算機遵循IEEE754標準(即IEC 60559) 的規范,所以這裡也將它作為一個示例。

一、IEEE浮點標準

由IEEE開發的IEEE標準提供瞭兩種主要的浮點數格式:單精度(32位) 和雙精度(64位)。數值以科學記數法的形式存儲,每一個數都由三部分組成:符號、指數和小數。指數部分的位數說明瞭數值的可能大小程度,而小數部分的位數說明瞭精度。單精度格式中,指數長度為8位,而小數部分占瞭23位。因此,單精度數可以表示的最大值大約是3.40×1038,其中精度是6個十進制數字。

IEEE標準還描述瞭另外兩種格式:單擴展精度雙擴展精度。標準沒有指明這些格式中的位數,但要求單擴展精度類型至少為43位,而雙擴展精度類型至少為79位。

類型 最小值 最大值 精度 備註
●float 1.175 49×10-38 3.402 82×1038 小數點後6位 單精度32位
●double 2.225 07×10-308 1.797 69×10308 小數點後15位 雙精度64位

上表給出瞭根據IEEE標準實現的浮點類型特征。[表中給出瞭規范化的最小正值, 非規范化的數可以更小。] long double類型沒有顯示在此表中, 因為它的長度隨著機器的不同而變化,而最常見的大小是80位和128位。

二、存儲方式

​ 對於浮點型數據,首先我們需要明白的一點是:浮點數和整型數的編碼方式是不一樣的,IEEE浮點標準采用如下形式來標識一個浮點數。

V = (-1)S M 2E

  • (-1)S 表示符號位,當S=0時,表示正數,當S=1時,表示負數。
  • M 表示有效數字,是一個二進制小數,其值大於等於1,小於2。
  • 2E 表示指數位。

在這裡插入圖片描述

下面,我將用float作為例子,double道理也是一樣的,隻是位數有所不同。

例如:十進制數:88.8125 —> 二進制為:101 1000.1101

然後將101 1000.1101化成上述公式M的形式,其范圍是[1,2),所以將小數點左移6位,得到1.0110001101×26(這裡不懂的話對比十進制,小數點左移一位乘以10,二進制則乘以2)。

最後得到S = 0、M = 1.0110001101、E = 6,但是事情並沒有那麼簡單,我們接著往下看。

IEEE 754對有效數字M和指數E的規定。

1、有效數字M:

1<=M<2,也就是說,M寫成1.xxx……的形式,其中xxx……表示小數部分。

IEEE 754規定,在計算機內部保存M時,默認這個數的第一位總是1,因此可以被舍去,隻保存小數部分。比如保存1.0110001101時,隻保存0110001101,後面的位數補0就可以瞭,等到讀取的時候,再把第一位的1補上去。

2、指數E:

首先,E為一個無符號整數(unsigned int)

如果E為8位,它的取值范圍為0~255;如果E為11位,它的取值范圍為0~2047。但是,我們知道,科學計數法是可以出現負數的,所以IEEE 754規定,存入內存的E是真實值加上一個中間數,對於8位的E,中間數是127,對於11位的E,中間數是1023。比如,26 的E是6,所以保存為32位浮點數時,必須保存為6+127=133,即10000101。

重點:

結合上述補充的信息完善例子

float:

十進制數:88.8125 二進制為:101 1000.1101 == 1.0110001101×26

  • 符號位:0
  • 指數位:6+127=133 二進制為:1000 0101
  • 小數位:1.0110001101去掉最高位1則為:0110001101

因此浮點數88.8125的IEEE浮點表示為:

—-0—-1000 0101—-011 0001 1010 0000 0000 0000

符號位- -指數域- – – – – – – – – – -小數域

根據指數域不同取值分為一下三種情況: 

1)E不全為0或不全為1(規格化值)

這是最常見情況,取出內存中的數時,指數E的計算值減去127(或1023),得到真實值,再將有效數字M前加上第一位的1。

2)E全為0(非規格化值)

這時,浮點數的指數E等於1-127(或1-1023)即為真實值,有效數字M不再加上第一位的1,而是還原為0.xxxxxxx的小數。這樣做是為瞭表示正負零,以及接近於0的很小的數字。

舉個例子:編碼為如下情形:

0 0000 0000 000 0000 0000 0000 0000 0001

即2(-23)×2(-126)=2(-149),轉成10進制大約等於1.4×10(-45),這就是單精度所能表達最小的正數瞭。

3)E全為1(特殊數值)

當指數域全為1時屬於這種情形。此時,如果小數域全為0且符號域S=0,則表示正無窮,如果小數域全為0且符號域S=1,則表示負無窮。如果小數域不全為0時,浮點數將被解釋為NaN, 即不是一個數(Not a Number) 。比如計算負數平方根或處理未初始化數據時。

總結

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: