big.int 转字符串必须用 text(10),不能依赖 string() 或 fmt.sprint;解析字符串须用 setstring(s, 10) 并检查 ok;转 int64 前必先 isint64(),否则会静默回绕。

big.Int 不能靠 fmt.Sprint 或类型断言转成可靠字符串,也不能用 int64() 直接取值——不检查范围就强转,结果不是错就是 panic。
SetString 解析超长数字字符串必须带进制且验 ok
从 JSON、文件或 API 拿到的几百位数字(如 "1234567890123456789012345678901234567890"),绝不能传给 strconv.ParseInt,它只认 int64 容器,一超就报 value out of range。
-
a.SetString(s, 10)的第二个参数是进制,不是可选;漏掉或写错(比如十六进制字符串"ff"却传10),a会保持零值,后续所有计算都静默失效 - 字符串含首尾空格、换行符(常见于
json.Unmarshal后的字段)会导致解析失败,务必先strings.TrimSpace(s) - 永远检查返回值:
if _, ok := a.SetString(s, 10); !ok { /* 处理错误 */ },忽略ok是线上静默故障高发原因
Text(10) 是唯一能拿到完整十进制字符串的方法
fmt.Println(a) 或 a.String() 在数极大时可能输出科学计数法(如 "1.23e+100"),这不是 bug,是设计行为——String() 为调试优化,不保证无格式。
- 要纯数字字符串(比如存 DB、传前端、做签名),必须用
a.Text(10);参数10是进制,不是小数位数 - 支持进制 2–62:
a.Text(16)得十六进制小写,a.Text(2)得二进制,无需额外转换 - 想转
[]byte?用a.Bytes(),但注意它是大端无符号编码,负数需配合a.Sign()和a.Abs(a).Bytes()
转 int64 / uint64 前必须用 IsInt64() 或 IsUint64()
直接调 a.Int64() 对超界值会回绕(wrap around),比如 9223372036854775808 变成 -9223372036854775808,毫无提示。
- 安全写法:
if a.IsInt64() { i := a.Int64() };IsUint64()同理 a.BitLen() 可作快速前置判断(正数),但不覆盖负数场景,仍推荐用 <code>IsInt64()- 别信
int64(a)这类强制转换——编译不过,big.Int不支持基础类型转换语法
JSON 场景下 big.Int 会先被 float64 破坏精度
如果原始 JSON 是 {"id": 123456789012345678901234567890}(没引号),Go 默认用 float64 接收,53 位精度上限一过,末几位就丢——这步不可逆,big.Int 再强也救不回来。
- 后端接收时,结构体字段必须声明为
string并加,string标签:ID string `json:"id,string"` - 或用
json.Number:ID json.Number `json:"id"`,再调ID.String()拿原始文本 - 前端必须发字符串:
{"id": "123456789012345678901234567890"},这是协议层约定,不是 Go 能单方面解决的
真正麻烦的从来不是“怎么写”,而是“在哪一步开始丢精度”——字符串解析漏 ok、输出用错 String()、JSON 传输没加引号,三处任一失守,后面所有高精度计算都是空中楼阁。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











