浮點數,是指小數點在數據中的位置可以左右移動的數據。它通常被表示成:
N = M* RE
這里的M(Mantissa)被稱為浮點數的尾數,R(Radix)被稱為階碼的基數,E(Exponent)被稱為階的階碼。計算機中一般規定R為2、8或16、是一個確定的常數,不需要在浮點數中明確表示出來。因此,要表示浮點數,一是要給出尾數M的值,通常用定點小數形式表示,它決定了浮點數的表示精度,即可以給出的有效數字的位數。二是要給出階碼,通常用整數形式表示,它指出的是小數點在數據中的位置,決定了浮點數的表示范圍。浮點數也要有符號位。在計算機中,浮點數通常被表示成如下格式:
| Ms | E | M |
Ms是尾數的符號位,即浮點數的符號位,安排在最高一位;
E 是階碼,緊跟在符號位之后,占用m位,含階碼的一位符號;
M 是尾數,在低位部分,占用n位。
在 IEEE 標准中,浮點數是將特定長度的連續字節的所有二進制位分割為特定寬度的符號域,指數域和尾數域三個域,其中保存的值分別用於表示給定二進制浮點數中的符 號,指數和尾數。這樣,通過尾數和可以調節的指數(所以稱為"浮點")就可以表達給定的數值了。具體的格式參見下面的圖例:

在上面的圖例中:
第一個域為符號域。其中 0 表示數值為正數,而 1 則表示負數。
第二個域為指數域,對應於我們之前介紹的二進制科學計數法中的指數部分。其中單精度數為 8 位,雙精度數為 11 位。以單精度數為例,8 位的指數為可以表達 0 到 255 之間的 255 個指數值。但是,指數可以為正數,也可以為負數。為了處理負指數的情況,實際的指數值按要求需要加上一個偏差(Bias)值作為保存在指數域中的值,單精 度數的偏差值為 127,而雙精度數的偏差值為 1023。比如,單精度的實際指數值 0 在指數域中將保存為 127;而保存在指數域中的 64 則表示實際的指數值 -63。 偏差的引入使得對於單精度數,實際可以表達的指數值的范圍就變成 -127 到 128 之間(包含兩端)。我們不久還將看到,實際的指數值 -127(保存為 全 0)以及 +128(保存為全 1)保留用作特殊值的處理。這樣,實際可以表達的有效指數范圍就在 -127 和 127 之間。
通過上面的格式,我們下面舉例看下-12.5在計算機中存儲的具體數據:
Address+0 Address+1 Address+2 Address+3
Contents 0xC1 0x48 0x00 0x00 接下來我們驗證下上面的數據表示的到底是不是-12.5,從而也看下它的轉換過程。
由於浮點數不是以直接格式存儲,他有幾部分組成,所以要轉換浮點數,首先要把各部分的值分離出來。
Address+0 Address+1 Address+2 Address+3
格式 SEEEEEEE EMMMMMMM MMMMMMMM MMMMMMMM
二進制 11000001 01001000 00000000 00000000
16進制 C1 48 00 00
可見:
S: 為1,是個負數。
E:為 10000010 轉為10進制為130,130-127=3,即實際指數部分為3.
M:為 10010000000000000000000。 這里,在底數左邊省略存儲了一個1,使用 實際底數表示為 1.10010000000000000000000
到此,我們吧三個部分的值都拎出來了,現在,我們通過指數部分E的值來調整底數部分M的值。調整方法為:如果指數E為負數,底數的小數點向左移,如果指數E為正數,底數的小數點向右移。小數點移動的位數由指數E的絕對值決定。
這里,E為正3,使用向右移3為即得:
1100.10000000000000000000
至次,這個結果就是12.5的二進制浮點數,將他換算成10進制數就看到12.5了,如何轉換,看下面:
小數點左邊的1100 表示為 (1 × 23) + (1 × 22) + (0 × 21) + (0 × 20), 其結果為 12 。
小數點右邊的 .100… 表示為 (1 × 2-1) + (0 × 2-2) + (0 × 2-3) + ... ,其結果為.5 。
以上二值的和為12.5, 由於S 為1,使用為負數,即-12.5 。
所以,16進制 0XC1480000 是浮點數 -12.5 。
以下為C/C++ code 查看計算機內存
template<typename T>
void Bits(T const& e)
{
int n(sizeof(T));
char* ch=(char*)&e;
for(int i(n-1),j;i>=0;--i)
{
for(j=7;j>=0;--j)
ch[i]&(char(1)<<j) ? std::cout<<1 : std::cout<<0;
std::cout<<'';<<"/n";
}
int main()
{
float a=3.14;
} std::cout
float b=-0.3;
double c=0.5;
Bits(a);
Bits(b);
Bits(c);
return0;
}
附:擴展參考文章:
