# **資料型態/轉型**
### 2020 資訊之芽
#### 2020/3/28
#### 實習生 袁紹奇
---
## Outline
* 資料型態(float, double)
* 控制輸出
* 轉型
---
## 資料型態??
----
### 資料型態
* 變數的儲存方式
* 不同型態的變數所占大小不同
* bit? byte?
* 8 bits = 1 byte
----
| 型別 | 意義 |
| --------- | --------------- |
| bool | boolean值(真值) |
| char | 字元 |
| int | 整數 |
| short | 短整數 |
| long | 長整數 |
| long long | 更長的整數 |
| float | 浮點數 |
| double | 倍準浮點數 |
---
### 布林 bool
* true OR false
* 1 和 0
* [George Boole](https://zh.wikipedia.org/wiki/%E4%B9%94%E6%B2%BB%C2%B7%E5%B8%83%E5%B0%94)
* 許多比較運算式的回傳值
* 其實沒有比int小
* 非0就是true
----
## 一個小例子
```cpp
bool a = 9527;
if(a)
cout << "yes";
```
---
## 可是,電腦只能存0和1阿
## >____<
----
## int是怎麼存的?
----
## int是怎麼存的?
世界上有10種人,一種是懂二進位的,另一種不懂
----
### 整數 int
* integer
* 二進位儲存
* 有號(signed)
* 範圍?!?!?!
----

----
### 整數 int
* 通常以4個bytes儲存
* sizeof(int)
* 範圍是$[−2^{31}$ ~ $2^{31}−1]$
* $2^{31}$ = 2147483648
* 無號(unsigned)?
----
## OVERFLOW!!!
```cpp
int a = 2147483647;
cout << a << endl; // 2147483647
a++;
cout << a << endl; // -2147483648
```
----
## wraps around?
```cpp
unsigned int a = 6666;
int i = -9527;
cout << i + i << endl; // -19054
cout << i + a << endl; // 4294964435
```
----

---
## 分數怎麼存?
----
## Recall
```cpp
cout << 5/2 << endl; // 會輸出2
```
----
### float/double
* 浮動的點點
* 4 bytes/ 8 bytes
* 沒有unsigned double?!

----
### 一些奇怪的double
* NAN
* INF
* e+/e-
----
## NAN
```cpp
double a = sqrt(-1.0); // #include <cmath> for sqrt
cout << a << endl;
// output: nan (not a number)
```
----
## INF
```cpp
double a = 2.0/0.0;
cout << a << endl;
// output: inf (infinite)
```
----
## e+/e-
```cpp
cout << 123456789.1234 << endl; // 1.23457e+008
cout << 0.00000000000000123 << endl; // 1.23e-015
//////// ***浮動的點點*** ////////
```
----
## 練習(演示)
練習輸入一個整數n,輸出以此為半徑的圓面積
pi = 3.14159
---
## 每次輸出的小數點位數不一樣?
----
## iomanip
* #include <iomanip>
* cout 預設為整數加小數點後共六位(整數部分優先)
* cout.precision() (設定位數)
* fixed (指定小數點後位數)
* setprecision() (設定位數)
----
```cpp
double a = 123.4567899527;
cout << a << endl; // 123.457 // 四捨五入?
cout << fixed << setprecision(8) << a << endl;
// 123.45678995
// fixed 會讓之後的precision變成設定小數點後位數
cout.precision(10);
cout << a; // 123.4567899527
```
---
練習:弧度量轉度度量

度度量 = 弧度量 * 360/2pi
假設 pi = 3.14159
輸出到小數點後四位
----
## solution
```cpp
#include <iostream>
#include <iomanip>
using namespace std;
int main(){
double pi = 3.14159;
int a;
double ans = 0.0;
cin >> a;
ans = a * 360 / 2 / pi;
cout << fixed << setprecision(4) << ans;
}
```
----
## 等等...
```cpp
ans = a * 360 / 2 / pi;
^
// 這邊有個int?
```
---
## 型態轉換
* 自己手動轉
* 編譯器幫你轉
* 不會改變變數型別
```cpp
// compile error
int wuhan[9527];
int feyan = wuhan[sqrt(9)*5+27];
// #include <math.h> for sqrt()
```
----
## 兩種轉型(手動轉)
```cpp
cout << (int)3.14159 << endl; // 3
cout << (float)5 / (float)2 << endl; // 2.5
cout << (float)(5/2) << endl; // 2
cout << (char)(97) << endl; // a
cout << static_cast <int>(3.14159) << endl;
cout << static_cast <float>(5) / static_cast <float>(2) << endl;
cout << static_cast <float>(5/2) << endl;
cout << static_cast <char>(97) << endl;
```
----
## 編譯器大哥幫忙
* 整數與浮點數相加
* 小數與大數相加
* 有號與無號相加
```cpp
cout << 3.14 + 1; // 4.14
cout << (int)(3.14) + (double)(1.2); // 4.2
cout << 5 / 2 + 0.5; // 2.5
cout << 5 / 2.0 + 0.5; // 3.0
cout << (unsigned int)INT_MAX + (int) 1; // 2147483648
```
----
## 型態轉換
* 位階小的和位階大的運算會被轉成大的
* bool < char < short < int < long < long long
* 有小數先轉小數
* float < double < long double
* 同位階的unsigned 比原本的大
---
## 練習
```cpp
cout << (unsigned int)1 + (double)-2.2 << endl;
cout << (unsigned)2147483647 + 1.0 << endl;
cout << (unsigned)10 - 20 << endl;
cout << (long long)-1 + (unsigned)0 << endl;
```
----
## 練習
```cpp
cout << (unsigned int)1 + (double)-2.2 << endl; // -1.2
cout << (unsigned)2147483647 + 1.0 << endl;
cout << (unsigned)10 - 20 << endl;
cout << (long long)-1 + (unsigned)0 << endl;
```
----
## 練習
```cpp
cout << (unsigned int)1 + (double)-2.2 << endl; // -1.2
cout << (unsigned)2147483647 + 1.0 << endl; // 2.14748e+009
cout << (unsigned)10 - 20 << endl;
cout << (long long)-1 + (unsigned)0 << endl;
```
----
## 練習
```cpp
cout << (unsigned int)1 + (double)-2.2 << endl; // -1.2
cout << (unsigned)2147483647 + 1.0 << endl; // 2.14748e+009
cout << (unsigned)10 - 20 << endl; // 4294967286
cout << (long long)-1 + (unsigned)0 << endl;
```
----
## 練習
```cpp
cout << (unsigned int)1 + (double)-2.2 << endl; // -1.2
cout << (unsigned)2147483647 + 1.0 << endl; // 2.14748e+009
cout << (unsigned)10 - 20 << endl; // 4294967286
cout << (long long)-1 + (unsigned)0 << endl; //-1
```
---
{"metaMigratedAt":"2023-06-15T05:39:41.097Z","metaMigratedFrom":"Content","title":"**資料型態/轉型**","breaks":true,"contributors":"[{\"id\":\"c5aa2397-41e9-4519-9c42-c485a8ba1b50\",\"add\":5912,\"del\":992}]"}