<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() 產生的浮點誤差
```