tags: tgirc早修book

浮點數

在程式設計中,小數被稱作浮點數

浮點數的表示方式

c++ 中的浮點數有兩種表示方式:十進位小數指數

十進位小數

一般常見的表示方式,是直接利用小數點來表示一個浮點數:

3.14159
48.763

像這樣,與平常寫數學的書寫方式非常相似。

指數

指數表示法概念類似 科學記號

2.5e-5

上面的範例中, 2.5e-5 就等於

2.5×105
e後方的整數表示 10 的次方數。

整數表示為浮點數

如果要將一個整數以浮點數型態表示,可以直接在整數後加上一個小數點 .

#include <iostream> #include <iomanip> using namespace std; int main() { cout << "integer: " << 2434 / 5 << "\n"; cout << "float: " << 2434. / 5. ; }

輸出結果:

integer: 486
float: 486.8 

float 與 double

要使用浮點數的話,可以用以下方式宣告一個 float 型態的變數:

float f = 3.14159;

而其餘加減乘除等運算方式,則與整數操作無異。

除了使用 float 之外,也可以使用 doublelong double 來宣告:

double d = 3.14159; long double ld = 3.14159;

double 除了能儲存比 float 更大範圍的數字外,精確度也會比較佳。

setprecision

如果今天要輸出 2434 / 7 ,很明顯的這會是一個無限循環小數。

cout << 2434. / 7. ;

輸出如下:

347.714

c++預設輸出至四捨五入共六位有效位數,所以雖然 2434 / 7 的結果是 347.714285714285... ,但只會顯示為 347.714

如果我們想要輸出到指定位數,可以這樣寫:

#include <iostream> #include <iomanip> using namespace std; int main() { cout << fixed << setprecision(9) << 2434. / 7. ; }

如上,先引入 <iomanip> 函式庫,然後使用 setprecision() 來設定位數。

輸出如下:

347.714285714

需要注意的是, setprecision() 的效果,會持續影響到後面的所有 cout
如果需要輸出不同位數,那就必須重新再設定一次 setprecision()

浮點數誤差

如果使用 float 來儲存一個很長的浮點數,然後把它輸出看看,如下:

float f = 3.333333333333333; cout << fixed << setprecision(15) << f;

輸出如下:

3.333333253860474

可以發現,除了整數部分與小數點後六位的這七位,其他的則與原本的值不一樣。

這就是所謂的 浮點數誤差 ,一個浮點數在固定位數之後就會與原本的值不一樣而產生誤差。

前面提到過的 doublefloat 準確,指的就是 double 可以儲存的準確位數比較多,要到更多位時才會產生浮點誤差。

各型態可以儲存的範圍如下:

float double long double
有效位數 6~7 15~16 18~19
可儲存範圍
1037
~
1038
10307
~
10308
104931
~
104932

要處理浮點數誤差,可以在浮點數後,加上一個非常小的數字,讓太小的數字進位,同時又不至於影響原本的數值。

float f = 4.8763 + 1e-8; // 10^-8 cout << fixed << setprecision(4) << f;

pow() , sqrt() 這些 <cmath> 中的函式,很多也是以浮點數來呈現結果的,所以也需要處理浮點數誤差。

cout << pow(2, 8) + 1e-8; //加上 1e-8 以處理 pow() 產生的浮點誤差