引入
数字是程序里最基本的数据——计数用整数,测量用浮点数,索引、排序、计算全都离不开。Go 的数字类型分整型和浮点型,没有隐式类型转换,不同类型之间必须显式转换。搞清楚每种类型的范围和精度,才能避免溢出和精度丢失。
正文
定义
定义
Go 数字分为整型(
int、int8int64、uint8uint64)和浮点型(float32、float64)。整型用于精确的整数运算,浮点型用于带小数的近似运算。math包提供常用的数学函数和常量。
语法
// 整型
var a int = 42
var b int64 = 1000000
// 浮点型
var pi float64 = 3.14159265
// 类型转换
var c float64 = float64(a)
var d int = int(pi)例子
整型运算
a := 10
b := 3
fmt.Println(a + b) // 13
fmt.Println(a - b) // 7
fmt.Println(a * b) // 30
fmt.Println(a / b) // 3(整数除法,截断小数)
fmt.Println(a % b) // 1(取余)整数除法会截断小数,10 / 3 结果是 3 而不是 3.333…。要得到小数结果,至少有一个操作数是浮点型。
浮点型运算
a := 10.0
b := 3.0
fmt.Println(a / b) // 3.3333333333333335浮点运算结果有小数,但精度不是无限的,可能出现尾数不精确的情况。
类型转换
// int 转 float64
i := 42
f := float64(i) // 42.0
// float64 转 int(截断小数部分)
f2 := 3.99
i2 := int(f2) // 3(不是四舍五入,是直接截断)
// int32 转 int64
var a int32 = 100
var b int64 = int64(a)Go 不会自动转换类型,即使是”安全”的转换(比如 int32 转 int64)也必须显式写。
math 包
import "math"
// 常用函数
math.Abs(-3.14) // 3.14
math.Max(1.5, 2.5) // 2.5
math.Min(1.5, 2.5) // 1.5
math.Ceil(3.2) // 4(向上取整)
math.Floor(3.8) // 3(向下取整)
math.Round(3.5) // 4(四舍五入)
math.Sqrt(16) // 4(平方根)
math.Pow(2, 10) // 1024(幂运算)
math.Log(math.E) // 1(自然对数)
// 常用常量
math.Pi // 3.141592653589793
math.E // 2.718281828459045
math.MaxInt64 // int64 最大值
math.MinInt64 // int64 最小值math 包的函数参数和返回值都是 float64,如果传入的是 int,需要先转成 float64。
数字和字符串互转
import "strconv"
// 字符串转数字
n, _ := strconv.Atoi("42") // int
f, _ := strconv.ParseFloat("3.14", 64) // float64
// 数字转字符串
s1 := strconv.Itoa(42) // "42"
s2 := strconv.FormatFloat(3.14, 'f', 2, 64) // "3.14"
// 用 fmt.Sprintf 也可以
s3 := fmt.Sprintf("%d", 42) // "42"
s4 := fmt.Sprintf("%.2f", 3.14) // "3.14"数字和字符串的转换用 strconv 包最正规,fmt.Sprintf 更灵活但稍微慢一点。
整型溢出
var a int8 = 127
// a = a + 1 // 编译报错:常量溢出
var b int8 = 127
b = b + 1 // 运行时 wrap around,b 变成 -128常量溢出在编译期就会报错,变量溢出在运行时会 wrap around(不会报错)。
常见写法
| 写法 | 说明 |
|---|---|
a := 42 | 整型,推断为 int |
f := 3.14 | 浮点型,推断为 float64 |
float64(i) | int 转 float64 |
int(f) | float64 转 int(截断) |
math.Abs(x) | 绝对值 |
math.Round(x) | 四舍五入 |
math.Sqrt(x) | 平方根 |
strconv.Atoi("42") | 字符串转 int |
strconv.Itoa(42) | int 转字符串 |
特点
- Go 没有隐式类型转换,
int和float64运算时必须统一类型 - 整数除法截断小数,不是四舍五入
float64转int是截断,不是四舍五入(3.99→3)math包的函数都接收和返回float64- 常量溢出编译报错,变量溢出运行时 wrap around
- 整型有不同位宽(8/16/32/64),不同类型之间也需要显式转换
strconv包是数字和字符串互转的标准工具
理解
Go 的数字类型最核心的点是没有隐式转换。int 和 float64 不能直接运算,int32 和 int64 也不能直接运算,必须显式转换。整数除法截断小数这一点容易踩坑,需要小数的结果记得用浮点数。math 包提供了常用的数学函数,但参数都是 float64,传 int 之前要先转类型。
引出
数字运算的结果经常需要和 true/false 做比较来判断条件。接下来看 Go 布尔值,了解 bool 类型以及比较运算和逻辑运算的用法。