typora/note/Go/数据类型.md
2024-12-12 10:48:55 +08:00

191 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

### 整型
- 平台无关整型
- 平台相关整型
- 区别在于整数类型在不同 CPU 架构或操作系统下面,它们的长度是否是一致
#### 平台无关整型
- 任何CPU架构下长度都是一致的
- 有符号整数 int8-int64
- 无符号整数 uint8-unint64
- 本质差别在于最高二进制位bit 位)是否被解释为符号位
![](https://blog-heysq-1255479807.cos.ap-beijing.myqcloud.com/blog/wiki/go/zhengxing1.jpg)
#### 平台相关整型
- int
- uint
- uintptr
- 可以调用unsafe.Sizeof(变量) 方法来获取对应平台占用的大小
![](https://blog-heysq-1255479807.cos.ap-beijing.myqcloud.com/blog/wiki/go/zhengxing2.jpg)
#### 整型溢出
- 整型运算结果超出表示的范围
- 溢出的结果依然在整型表示范围
- 结果与预期结果不符
```go
var s int8 = 127
s += 1 // 预期128实际结果-128
var u uint8 = 1
u -= 2 // 预期-1实际结果255
```
#### 整型字面值与格式化输出
- 二进制
- 八进制
- 十进制
- 十六进制
```go
d1 := 0b10000001 // 二进制,以"0b"为前缀在go1.13之后的版本才生效
d2 := 0B10000001 // 二进制,以"0B"为前缀在go1.13之后的版本才生效
b := 0700 // 八进制,以"0"为前缀
e1 := 0o700 // 八进制,以"0o"为前缀
e2 := 0O700 // 八进制,以"0O"为前缀
a := 53 // 十进制
c1 := 0xaabbcc // 十六进制,以"0x"为前缀
c2 := 0Xddeeff // 十六进制,以"0X"为前缀
```
#### 支持在字面值中增加数字分隔符"-"
- 在go1.13之后的版本才生效
```go
a := 5_3_7 // 十进制: 537
b := 0b_1000_0111 // 二进制位表示为10000111
c1 := 0_700 // 八进制: 0700
c2 := 0o_700 // 八进制: 0700
d1 := 0x_5c_6d // 十六进制0x5c6d
```
### 浮点数
- float32 32位单精度浮点数
- float64 64位双精度浮点数
- 默认值0.0
- Go提供的浮点数都是平台无关的
#### 浮点数二进制表示
- IEEE 754算术标准
- 单精度 32位
- 双精度 64位
- 扩展单精度 43位以上
- 扩展双精度 79位以上
- 二进制表示方式
![](https://blog-heysq-1255479807.cos.ap-beijing.myqcloud.com/blog/wiki/go/ieee754.jpg)
#### 浮点数阶码和尾数
![](https://blog-heysq-1255479807.cos.ap-beijing.myqcloud.com/blog/wiki/go/jiema.jpg)
#### 十进制小数转换成二进制计算方式
- 乘2取整的竖式计算
- 小数部分每次乘2结果大于1记1结果小于1记0
- 剩下的小数部分再乘2记录方式同上
- 直到结果等于小数部分为0
![](https://blog-heysq-1255479807.cos.ap-beijing.myqcloud.com/blog/wiki/go/shushijisuan.jpg)
#### 十进制形式的浮点值 139.8125转换为IEEE754单精度二进制
##### 二进制转换
- 整数部分转换为二进制 `10001011b`
- 小数部分转换为二进制 `1101b`
- 原来的`139.8125`变为`10001011.1101`
##### 移动小数点直到整数部分仅有1个1
- `10001011.1101b` => `1.00010111101b`
- 小数点移动7位
- 尾数为`00010111101b`
##### 计算阶码
- 阶码 = 指数 + 偏移值指数就是小数点移动的位数偏移值为2^(e-1)-1e就是阶码部分的bit位数32位精度e为8,64精度e为11
- 阶码 = 7 + 127为134d`10000110b`
##### 符号位阶码和尾数填充尾数位不够的话补0
- 符号位 0
- 阶码 10000110
- 尾数 00010111101(000000000000)补充12个0
- 二进制139.8125的表示方式就是`0b_0_10000110_00010111101_000000000000`
```go
func main() {
var f float32 = 139.8125
bits := math.Float32bits(f)
fmt.Printf("%b\n", bits)// 高危补0表示符号位
// 1000011000010111101000000000000
}
```
#### 字面值与格式化输出
##### 字面值
- 十进制表示浮点值的形式
```go
3.1415
.15 // 整数部分如果为0整数部分可以省略不写
81.80
82. // 小数部分如果为0小数点后的0可以省略不写
```
- 科学计数法
```go
v
6674.28e-2 // 6674.28 * 10^(-2) = 66.742800
.12345E+5 // 0.12345 * 10^5 = 12345.000000
```
- 16进制科学计数法整数和小数部分用的都是16进制但是指数部分依然是10进制
```go
0x2.p10 // 2.0 * 2^10 = 2048.000000
0x1.Fp+0 // 1.9375 * 2^0 = 1.937500
```
##### 格式化
- %f格式化
```go
var f float64 = 123.45678
fmt.Printf("%f\n", f) // 123.456780
```
- 输出科学计数法形式
```go
var f float64 = 123.45678
fmt.Printf("%e\n", f) // 1.234568e+02 十进制科学计数法
fmt.Printf("%x\n", f) // 0x1.edd3be22e5de1p+06 16进制科学计数法
```
### 复数
- complex64实部与虚部都是float32
- complex128实部与虚部都是float64
- 如果一个复数没有显示赋予类型则默认类型为complex128
#### 字面值与初始化
- 通过字面值直接初始化
```go
var c = 5 + 6i
var d = 0o123 + .12345E+5i // 83+12345i
```
- `complex` 函数,方便创建一个 complex128 类型值
```go
var c = complex(5, 6) // 5 + 6i
var d = complex(0o123, .12345E+5) // 83+12345i
```
- 通过预定义函数 `real`和`imag`来获取一个复数的实部和虚部
```go
var c = complex(5, 6) // 5 + 6i
r := real(c) // 5.000000
i := imag(c) // 6.000000
```
### 创建自定义的数值类型
- type MyInt int32
- MyInt底层仍然是int32数值性质也与int32相同
- 但是Go的类型安全规则限定MyInt和int32仍是完全不同的两种类型无法进行相互复制和计算
- 赋值和计算需显示类型转换
### 通过类型别名来定义数值类型
- type MyInt = int32
- 通过类型别名语法定义的新类型与原类型别无二致,可以完全相互替代