浮點數運算

常見

浮點數表達方式

之前大家應該有在前面的章節看到過 floatdouble,這兩個資料型態都是拿來存浮點數的!那要如何表達一個浮點數呢?以下以 double 為例:

double a = 0.0025;

以數學寫法表示是一種方法,而另外一種則是科學記號:

double a = 2.5e-3;
補充

大數也可以用科學記號,之後用各種演算法的時候常常會需要訂一個常數作為最大值,這時候就可以用科學記號,會比打很多個零之後還要慢慢算有幾個零還要快很多。但是要注意科學符號表示法的資料型態是浮點數,要用 int 強制轉型,要不然拿來宣告陣列長度之類的會出事。

const int N = 1e6; // 1000000

除法要注意

浮點數的加、減、乘法都跟整數一樣,但是除法好像不太一樣?!

cout << 5 / 2 << '\n';
cout << 5.0 / 2.0 << '\n';

這兩個輸出看起來似乎沒有差別,但是執行後會發現一個是 2,一個是 2.5,這是因為整數運算中 / 的答案是會被自動無條件捨去,但浮點數運算則是會保留小數點。

輸出的位數

有的時候題目會指定你輸出某個小數到小數點第 2 位之類的,那要怎麼辦呢?C++有一個函式叫做 setprecision()

cout << fixed << setprecision(2) << 4.0 / 3.0; //1.33

其中,後面括號放的是要保留的位數(以上面的例子來說就是保留 2 位),這個設定會持續到後面的每一筆輸出,所以如果要改的話要重新設定。

fixed 是幹什麼的呢?在一些情況下,C++ 會輸出包含科學記號的數字,這時候 fixed 就是用來關閉科學記號的。

浮點數誤差

當你嘗試將上面舉的例子多輸出幾位時你會發現一些奇怪的事:

cout << fixed << setprecision(20)  << 4.0 / 3.0;

你會發現輸出是 1.33333333333333325932 而不是 1.33333333333333333333,這是因為浮點數的精度有限,所以在計算的時候會有一點誤差,關於電腦裡儲存浮點數的方式有興趣的可以參考 這篇文章

doublefloat 的差別正是 double 能存的精準位數比較多。那要怎麼解決呢?其實只要在這個數字後面加一個很小的數字(例如 10 的 -8 次方),讓後面的數字進位就好了!

注意

前面教過的一些數學函式如 powsqrt 等也都牽涉浮點數運算,所以也要處理誤差!

小測驗

程式 cout << 1.0 + 2.0; 會輸出什麼結果?