Go 浮点型与复数类型详解📘

Go 浮点型与复数类型详解

一、核心重点(快速掌握)

序号 重点内容 备注说明
1 浮点类型:float32float64 分别表示单精度和双精度浮点数,对应 IEEE-754 标准
2 默认浮点字面量为 float64 若不显式指定类型,默认是 float64
3 支持科学计数法 1.23e4 表示 12300
4 浮点运算可能产生误差 不适用于高精度金融计算,建议使用 decimal 等库
5 复数类型:complex64complex128 基于 float32float64 构成的复数
6 使用内置函数操作复数 real()imag() 获取实部和虚部
7 NaN 和 Inf 的判断方式 使用 math.IsNaN()math.IsInf() 判断特殊值
8 避免直接比较浮点数相等 推荐使用差值小于某个极小值(如 1e-9)来判断近似相等

二、知识点详解(专题深入)

1、浮点类型(Floating Point Types)

Go 提供了两种浮点类型:

类型名 所占字节数 精度位数 IEEE-754标准
float32 4 约7位 单精度
float64 8 约15位 双精度

注意点

  • float64 是默认类型,大多数情况下推荐使用。
  • 对性能要求极高或内存受限时可考虑使用 float32

实例代码:

package main

import "fmt"

func main() {
	var a float32 = 3.1415926535
	var b float64 = 3.1415926535

	fmt.Printf("a = %.10f (float32)\n", a) // 输出精度损失
	fmt.Printf("b = %.10f (float64)\n", b) // 输出更精确
}

2、浮点数字面量表示法

Go 支持以下几种浮点数字面量格式:

表达方式 示例 描述
小数形式 3.14, -0.001 包含整数部分和小数部分
科学记数法 1.23e4, 3E-5 eE 表示指数
显式类型声明 float32(1.2) 强制转换为特定浮点类型

实例代码:

package main

import "fmt"

func main() {
	a := 1.23
	b := 1.23e4
	c := float32(1.23)

	fmt.Printf("a: %T\n", a) // float64
	fmt.Printf("b: %v\n", b) // 12300
	fmt.Printf("c: %T\n", c) // float32
}

技巧

  • 使用科学记数法可以简化极大或极小数值的书写。
  • 可以通过类型断言或转换控制变量类型。

3、浮点数的精度问题与陷阱

由于浮点数采用二进制表示,某些十进制小数无法精确表示,导致精度丢失。

实例代码:

package main

import "fmt"

func main() {
	a := 0.1 + 0.2
	fmt.Println(a == 0.3) // 输出 false!
}

注意点

  • 不要直接用 == 比较两个浮点数是否相等。
  • 推荐使用差值比较,例如:
const epsilon = 1e-9
if math.Abs(a - b) < epsilon {
    fmt.Println("a ≈ b")
}

技巧

  • 高精度场景建议使用 big.Float 或第三方库如 shopspring/decimal

4、复数类型(Complex Numbers)

Go 支持两种复数类型:

类型名 内部结构 总字节数
complex64 float32 + float32 8
complex128 float64 + float64 16

注意点

  • 默认复数字面量是 complex128
  • 使用 i 表示虚数单位。

实例代码:

package main

import "fmt"

func main() {
	var c1 complex64 = 3 + 4i
	var c2 complex128 = complex(5, 12) // 5+12i

	fmt.Println("c1 =", c1)
	fmt.Println("c2 =", c2)
}

5、复数的基本操作函数

Go 提供了一些内置函数用于操作复数:

函数名 功能描述
real(c) 返回复数 c 的实部
imag(c) 返回复数 c 的虚部
complex(r, i) 构造一个复数

实例代码:

package main

import "fmt"

func main() {
	c := complex(3, 4) // 创建复数 3+4i
	r := real(c)       // 实部 3
	i := imag(c)       // 虚部 4

	fmt.Printf("Real part: %v\n", r)
	fmt.Printf("Imaginary part: %v\n", i)
}

技巧

  • 使用 cmath 包进行复数数学运算(如平方根、指数、对数等)。

6、浮点数的特殊值处理(NaN、Inf)

Go 中使用 math 包定义了一些特殊浮点值和检测函数:

常量 / 函数 含义
math.NaN() 表示“非数字”(Not-a-Number)
math.Inf(1) 表示正无穷
math.IsNaN(x) 判断是否为 NaN
math.IsInf(x, 0) 判断是否为无穷

实例代码:

package main

import (
	"fmt"
	"math"
)

func main() {
	a := math.NaN()
	b := math.Inf(1)

	fmt.Println("IsNaN(a):", math.IsNaN(a)) // true
	fmt.Println("IsInf(b):", math.IsInf(b, 0)) // true
}

注意点

  • NaN 与任何值(包括自己)都不相等,必须使用 math.IsNaN() 判断。
  • 在除法、开方等操作中可能出现这些特殊值。

7、常见陷阱与注意事项汇总

陷阱/问题 解决方案/建议
浮点数精度丢失 避免直接比较,使用差值比较;高精度需求使用专用库
错误地使用 float32 导致精度不足 优先使用 float64
直接使用 == 比较浮点数 使用 math.Abs(a - b) < epsilon
忽略复数的构造方式 使用 complex(r, i) 更清晰可靠
复数未导入 math/cmplx 包进行复杂运算 若需三角函数、幂运算等,需引入 cmath
忽略 NaN 和 Inf 的存在 在除法、开方等操作后应做边界检查

✅ 总结

本章详细讲解了 Go 语言中的浮点类型和复数类型的定义、使用方法、常见陷阱及最佳实践。涵盖了如下内容:

  • float32float64 的区别与选择
  • 浮点数字面量的多种写法(包括科学记数法)
  • 浮点数的精度问题与比较技巧
  • 复数类型的定义与基本操作(实部、虚部、构造)
  • 特殊值(NaN、Inf)的使用与检测
  • 常见错误与规避策略

建议结合练习项目进一步巩固理解,如实现一个简单的计算器、向量运算器或信号处理模块,提升实际应用能力。若需继续学习字符串、布尔、数组等基础类型,请继续提问。

posted @ 2025-06-25 07:47  红尘过客2022  阅读(43)  评论(0)    收藏  举报