
复数字面量写法不对,cmplx 函数根本不会被调用
Go 里没有内置复数类型字面量语法(比如 Python 的 3+4j),必须显式用 complex64 或 complex128 构造。写成 3 + 4i 会直接编译报错:undefined: i。
正确写法只有两种:complex(3, 4)(生成 complex128)或 complex64(complex(3, 4))。别试图用字符串拼接或 float 转换,cmplx 包所有函数只认这两个底层类型。
-
cmplx.Sqrt对complex64和complex128各有一版重载,但参数类型不匹配时不会自动转换 - 混用类型容易触发隐式转换失败,比如把
complex64变量传给期望complex128的cmplx.Pow,编译器会报错而非警告 - 科学计算中建议统一用
complex128,complex64在 FFT 或大量复向量运算时才有意义,且需确认下游库支持
cmplx.Abs 返回的是模长,不是实部或幅角
新手常误以为 cmplx.Abs(z) 是取“绝对值”所以该返回实数部分,其实它算的是 √(re² + im²),结果是 float64。如果你要实部、虚部、幅角或共轭,得用对应函数:real(z)、imag(z)、cmplx.Phase(z)、cmplx.Conj(z)。
-
cmplx.Phase返回值范围是 [-π, π],不是 [0, 2π),做角度差计算时要注意跨象限问题 -
cmplx.Abs对接近零的复数稳定,但cmplx.Log在原点附近会返回NaN+-Inf,需提前检查cmplx.Abs(z) == 0 - 别对
cmplx.Abs结果再套math.Abs——它已经是非负浮点数,多此一举还可能引入精度误差
用 cmplx.Polar 转极坐标前,先确认你真需要它
cmplx.Polar(r, θ) 是从模长和幅角构造复数,反向操作是 cmplx.Abs + cmplx.Phase。但极坐标在 Go 里没原生支持,所有运算仍要转回直角坐标系。频繁来回转换不仅慢,还会累积浮点误差。
立即学习“go语言免费学习笔记(深入)”;
- FFT、滤波器设计等场景,输入输出通常约定为直角坐标,
cmplx.Polar仅适合初始化特定频点(如cmplx.Polar(1, math.Pi/4)) -
θ参数单位是弧度,不是角度——传90会得到完全错误的结果,必须先除以180/math.Pi - 当
r为负时,cmplx.Polar会自动等价于cmplx.Polar(-r, θ+π),这个行为符合数学定义,但容易让人困惑,建议 r 始终传非负值
和 C/Fortran 科学库对接时,cmplx 不处理内存布局
Go 的 complex128 在内存中就是两个连续 float64(实部在前),和 C 的 double _Complex 兼容,但 cmplx 包本身不提供指针操作或 slice 视图转换。想把 []complex128 传给 CGO 封装的 FFT 库,得手动转成 *C.double 并确保长度对齐。
- 别用
unsafe.Slice直接把[]complex128当作[]float64用——虽然内存结构一致,但 Go 1.21+ 对这种转换加了严格检查,运行时 panic -
cmplx所有函数都是纯计算,不涉及分配,但像cmplx.Exp这类函数在大模长下容易溢出,返回+Inf或NaN,而 C 库可能有更精细的渐进缩放策略 - 如果项目重度依赖 BLAS/LAPACK,与其硬套
cmplx,不如用gonum.org/v1/gonum/mat,它内部已处理好复数矩阵的内存和算法适配










