◎基本概念
關於浮點數的規範必須先了解IEEE 754,float與double皆遵守IEEE 754,常見的有單精度float(32bits)和雙精度double (64bits)。
◎簡述IEEE754概念
單精度float(32bits),雙精度double(64bits),bits數分配 :
各格式表示 :
Sign : 正負
32bits ,exponent 數值所表示的指數如下表 :
0000 0000最小,1111 1111最大。
例 :
-0.75
=
=
Fraction : 有效數(小數位)
如上例,放置小數點後的數值。
3.例外
當exponent = 0 ,fraction為非0時IEEE允許有些數值以非正規形式的浮點數表示,比正規化更接近於0 。
32bit非正規形式
=
(-1)sign x (0.fraction) x 2 -126
◎精準度
精準度是看fraction存幾個bits。
float : 23 mantissa bits + 1 hidden bit :
轉為十進位
double : 52 mantissa bits + 1 hidden bit :
轉為十進位
◎結論
不論是單精度還是雙精度,它可以表示的小數還是有限的。每個 Compiler 提供之浮點數規格可能不盡相同,如果寫浮點數運算是要非常小心的。
了解一下下面程式碼的結果
關於浮點數的規範必須先了解IEEE 754,float與double皆遵守IEEE 754,常見的有單精度float(32bits)和雙精度double (64bits)。
◎簡述IEEE754概念
10進位正規化範例 :
2進位正規化範例 :
小數點前必只有一個一個1
單精度float(32bits),雙精度double(64bits),bits數分配 :
各格式表示 :
(-1)sign
x (1+ .fraction) x 2 exponent - exponent
bias
Sign : 正負
正為0,負為1
Exponent : 指數部分,正規化後的次方數
為達到快速比較指數大小(不用考慮正負)的目的,exponent採用數偏移值表示法(biased notation) 。
exponent bias= 2e-1 - 1(e = exponent Bit數)以單精準度(single precision)來說,32bit ,exponent Bit數 = 8 ,所以exponent bias = 127。以雙精準度(doubleprecision)來說,64bit ,exponent Bit數 = 11 ,所以exponent bias = 1023。
32bits ,exponent 數值所表示的指數如下表 :
0000 0000最小,1111 1111最大。
10進位
|
exponent值
|
實際
表示指數 |
|
0
|
0000 0000
|
-127
|
X
例外 |
1
|
0000 0001
|
-126
|
|
2
|
0000 0010
|
-125
|
|
.
|
.
|
||
127
|
0111 1111
|
0
|
bias
|
128
|
1000 0000
|
+1
|
|
.
|
.
|
||
254
|
1111 1110
|
+127
|
|
255
|
1111 1111
|
+128
|
X
例外 |
例 :
-0.75
=
(-1)sign
x (1+ .fraction) x 2 exponent - exponent
bias
=
(-1)1 x
(1+ .1 ) x 2126-127
內容是 :
Fraction : 有效數(小數位)
如上例,放置小數點後的數值。
3.例外
表示
|
exponent
|
fraction
|
0
|
0
|
0
|
非正規數
|
0
|
非0
|
正規數
|
1 ~ 2e - 2
|
任意
|
無限大
|
2e - 1
|
0
|
NaN(not a number)
|
2e - 1
|
非0
|
當exponent = 0 ,fraction為非0時IEEE允許有些數值以非正規形式的浮點數表示,比正規化更接近於0 。
32bit非正規形式
=
(-1)sign x (0.fraction) x 2 -126
Single precision
|
double precision
|
表示
|
||
exponent
|
fraction
|
exponent
|
fraction
|
|
0
|
0
|
0
|
0
|
±0
|
0
|
任意非0
|
0
|
任意非0
|
非正規化數
|
1 ~ 254
|
任意
|
0~2046
|
任意
|
正規化數
|
255
|
0
|
2047
|
0
|
無限大
|
255
|
任意非0
|
2047
|
任意非0
|
NaN
|
正規化最小
Sign exponent fraction
0
|
0000 0001
|
000 0000 0000 0000
0000 0000
|
= 1.0 x 2-126
≈ 1.18 x 10-38
正規化最大
Sign exponent fraction
0
|
1111 1110
|
111 1111 1111
1111 1111 1111
|
= 1.1111 1111 1111
1111 1111 111 x 2127
≈3.4 x 1038
非正規化最小
Sign exponent fraction
0
|
0000 0000
|
000 0000 0000
0000 0000 0001
|
= 0.0000 0000 0000
0000 0000 001 x 2-126
= 1.0 x 2-149
≈1.4 x 10-45
非正規化最大
Sign exponent fraction
0
|
0000 0000
|
1111 1111 1111
1111 1111 111
|
= 0.11111111111111111111111
x 2-126
≈1.18 x 10-38
◎精準度
精準度是看fraction存幾個bits。
float : 23 mantissa bits + 1 hidden bit :
轉為十進位
log224
= 7.2247198 digits
double : 52 mantissa bits + 1 hidden bit :
轉為十進位
log253
= 15.954589 digits
◎結論
類型
|
bit數
|
有效數
|
float
|
32
|
6~7
|
double
|
64
|
15~16
|
不論是單精度還是雙精度,它可以表示的小數還是有限的。每個 Compiler 提供之浮點數規格可能不盡相同,如果寫浮點數運算是要非常小心的。
了解一下下面程式碼的結果
#include "stdafx.h" #include <iostream> #include <limits> #include <iomanip> using namespace std; int main() { // a = b //float a = 1.12345678f; //float b = 1.12345679f; //a < b //float a = 1.1234567f; //float b = 1.1234568f; //a = b //double a = 1.1234567890123456; //double b = 1.1234567890123457; //a < b //double a = 1.123456789012344; //double b = 1.123456789012345; //a < b //double a = 1.12345678; //double b = 1.12345679; if (a > b) { cout << "a > b" << endl; } else if (a == b) { cout << "a == b" << endl; } else { cout << "a < b" << endl; } return 0; }
留言
張貼留言