<style> html, body, .ui-content { background-color: #333; color: #ddd; } body > .ui-infobar { display: none; } .ui-view-area > .ui-infobar { display: block; } .markdown-body h1{ color: #9CCEF2; } .markdown-body h2{ color: #B1D6CA; } .markdown-body h3{ color: #F5F6B6; } .markdown-body h4, .markdown-body h5, .markdown-body h6 { color: #ddd; } .markdown-body h1, .markdown-body h2 { border-bottom-color: #ffffff69; } .markdown-body h1 .octicon-link, .markdown-body h2 .octicon-link, .markdown-body h3 .octicon-link, .markdown-body h4 .octicon-link, .markdown-body h5 .octicon-link, .markdown-body h6 .octicon-link { color: #fff; } .markdown-body img { background-color: transparent; } .ui-toc-dropdown .nav>.active:focus>a, .ui-toc-dropdown .nav>.active:hover>a, .ui-toc-dropdown .nav>.active>a { color: white; border-left: 2px solid white; } .expand-toggle:hover, .expand-toggle:focus, .back-to-top:hover, .back-to-top:focus, .go-to-bottom:hover, .go-to-bottom:focus { color: white; } .ui-toc-dropdown { background-color: #333; } .ui-toc-label.btn { background-color: #191919; color: white; } .ui-toc-dropdown .nav>li>a:focus, .ui-toc-dropdown .nav>li>a:hover { color: white; border-left: 1px solid white; } .markdown-body blockquote { color: #bcbcbc; } .markdown-body table tr { background-color: #5f5f5f; } .markdown-body table tr:nth-child(2n) { background-color: #4f4f4f; } .markdown-body code, .markdown-body tt { color: #eee; background-color: rgba(230, 230, 230, 0.36); } a, .open-files-container li.selected a { color: #5EB7E0; } </style> ###### tags: `tgirc早修book` # 浮點數 在程式設計中,小數被稱作浮點數 ## 浮點數的表示方式 c++ 中的浮點數有兩種表示方式:<font color="F5F6B6">十進位小數</font> 與 <font color="F5F6B6">指數</font> ### 十進位小數 一般常見的表示方式,是直接利用小數點來表示一個浮點數: ``` 3.14159 48.763 ``` 像這樣,與平常寫數學的書寫方式非常相似。 ### 指數 指數表示法概念類似 *科學記號* : ``` 2.5e-5 ``` 上面的範例中, `2.5e-5` 就等於 $2.5 \times 10^{-5}$ 。 `e`後方的整數表示 10 的次方數。 ### 整數表示為浮點數 如果要將一個整數以浮點數型態表示,可以直接在整數後加上一個小數點 `.` 。 ```cpp= #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` 型態的變數: ```cpp= float f = 3.14159; ``` 而其餘加減乘除等運算方式,則與整數操作無異。 除了使用 `float` 之外,也可以使用 `double` 或 `long double` 來宣告: ```cpp= double d = 3.14159; long double ld = 3.14159; ``` `double` 除了能儲存比 `float` 更大範圍的數字外,精確度也會比較佳。 ## setprecision 如果今天要輸出 2434 / 7 ,很明顯的這會是一個無限循環小數。 ```cpp= cout << 2434. / 7. ; ``` 輸出如下: ``` 347.714 ``` c++預設輸出至四捨五入共六位有效位數,所以雖然 `2434 / 7` 的結果是 `347.714285714285...` ,但只會顯示為 `347.714` 如果我們想要輸出到指定位數,可以這樣寫: ```cpp= #include <iostream> #include <iomanip> using namespace std; int main() { cout << fixed << setprecision(9) << 2434. / 7. ; } ``` 如上,先引入 `<iomanip>` 函式庫,然後使用 `setprecision()` 來設定位數。 輸出如下: ``` 347.714285714 ``` 需要注意的是, `setprecision()` 的效果,會持續影響到後面的所有 `cout` 。 如果需要輸出不同位數,那就必須重新再設定一次 `setprecision()`。 ## 浮點數誤差 如果使用 `float` 來儲存一個很長的浮點數,然後把它輸出看看,如下: ```cpp= float f = 3.333333333333333; cout << fixed << setprecision(15) << f; ``` 輸出如下: ``` 3.333333253860474 ``` 可以發現,除了整數部分與小數點後六位的這七位,其他的則與原本的值不一樣。 這就是所謂的 *浮點數誤差* ,一個浮點數在固定位數之後就會與原本的值不一樣而產生誤差。 前面提到過的 `double` 比 `float` 準確,指的就是 `double` 可以儲存的準確位數比較多,要到更多位時才會產生浮點誤差。 各型態可以儲存的範圍如下: | | float | double | long double | | ---------- | ---------------------- | ------------------------ | -------------------------- | | 有效位數 | 6~7 | 15~16 | 18~19 | | 可儲存範圍 | $10^{-37}$ ~ $10^{38}$ | $10^{-307}$ ~ $10^{308}$ | $10^{-4931}$ ~ $10^{4932}$ | 要處理浮點數誤差,可以在浮點數後,加上一個非常小的數字,讓太小的數字進位,同時又不至於影響原本的數值。 ```cpp= float f = 4.8763 + 1e-8; // 10^-8 cout << fixed << setprecision(4) << f; ``` `pow()` , `sqrt()` 這些 `<cmath>` 中的函式,很多也是以浮點數來呈現結果的,所以也需要處理浮點數誤差。 ```cpp= cout << pow(2, 8) + 1e-8; //加上 1e-8 以處理 pow() 產生的浮點誤差 ```