big.float 除法必须用 quo() 而非 div(),且需显式设置精度、通过 setstring() 字符串初始化,避免类型错误、精度退化和隐式误差。

big.Float 除法必须用 Quo(),不是 Div()
Go 的 big.Float 没有 Div() 方法,调用它会直接编译失败。这是最常踩的坑——误以为它和 big.Int.Div() 对称,结果卡在语法错误上。
正确做法是用 Quo(),它接收两个 *big.Float 参数,把被除数除以除数,结果写入调用者自身:
-
z.Quo(x, y)等价于z = x / y,返回z(支持链式) - 不能写成
d.Div(fact(i)):一是方法不存在,二是fact(i)返回*big.Int,类型不匹配 - 若除数是
*big.Int,必须先转成*big.Float:new(big.Float).SetInt(f)
精度必须显式设置,否则结果不可靠
big.Float 默认精度是 0 或 64 位(取决于初始化方式),远低于“高精度”预期。没设 SetPrec() 就算用字符串初始化,后续运算也会快速退化为 float64 级别精度。
- prec 单位是二进制位,不是小数位数:设
256≈ 77 位十进制有效数字 - 所有参与运算的
*big.Float实例都得设足够 prec,否则低精度 operand 会拖垮整个结果 - 推荐统一初始化:
new(big.Float).SetPrec(256).SetString("3.14159...") - 避免用
SetFloat64()初始化,比如SetFloat64(0.1)会带入二进制浮点误差,失去高精度意义
字符串初始化是唯一可靠入口
任何从 float64、int64 等基础类型转过来的值,都会丢失精度或引入误差。要真正实现任意精度,原始数值必须走字符串路径。
- 用
SetString("123.456"),不是SetFloat64(123.456) -
SetString()返回(*big.Float, bool),第二个返回值必须检查,失败时返回nil且不 panic - 支持科学计数法:
"1.23e-5"合法,但"1,000.0"或" 3.14 "(含空格)会静默失败 - 从 JSON 或用户输入读取后,务必
strings.TrimSpace()再传给SetString()
零除和并发是隐藏雷区
Quo() 遇到除数为 0 时不会 panic,而是返回 +Inf、-Inf 或 NaN,生产环境必须提前校验。
- 检查除数是否为零:
y.Sign() != 0(Sign()返回 -1/0/1) -
big.Float不是并发安全的:多个 goroutine 同时调Add()或Quo()会导致数据竞争 - 高频循环中反复
new(big.Float)分配内存,性能比复用对象慢 3–5 倍;建议预分配并重置:term.SetPrec(prec).SetString("1") - 比较两个
*big.Float是否相等,不能用==,要用Cmp()
Quo() 的参数顺序和类型约束,比看起来更严格——错一个环节,结果就不是“高精度”,只是“看起来很长的错数”。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











