当前位置:首页 > 文章列表 > Golang > Go教程 > Go math/big 怎么读取大整数

Go math/big 怎么读取大整数

来源:17golang原创 2026-09-13 10:45:07 0浏览 收藏

在 Go 里,超过内置整数范围的值不要先放进 int64 再转换,直接交给 math/big.Int 更稳妥。最常见的读取入口是:十进制或其他进制文本用 SetString,流式输入用 fmt.Sscan,JSON 字段可直接让 json.Unmarshal 调用 UnmarshalJSON,大端字节则用 SetBytes

如果输入来自字符串,优先使用 SetString(s, 0) 并同时检查返回值;如果来自 JSON 或二进制协议,分别使用对应的反序列化方法。读取完成后用 String()Text(base) 输出,转回 int64 前先调用 IsInt64()

要点速览
  • SetString 要检查 ok,成功要求整个字符串都合法。
  • base=0 会按 0b0o0x 等前缀识别进制。
  • BytesSetBytes 表示无符号大端绝对值,不携带负号。

先按输入形态选择 math/big 读取入口

big.Int 是有符号多精度整数,零值可以直接使用。它的 API 采用指针接收者,读取和运算都要让目标对象接收结果。不要把 big.Int 当作普通数值类型直接做强制转换。

输入入口需要注意
文本SetString(s, base)返回值为 (*Int, bool)
fmt 流fmt.Sscan / fmt.Fscan底层调用 Int.Scan
JSONjson.Unmarshal目标必须是 *big.Int
大端字节SetBytes按无符号绝对值解释

用 SetString 读取大整数文本

配置文件、CSV 字段和表单值通常是字符串。固定十进制可以传 10;想同时接受十进制与 0x0o0b 前缀,则传 0。成功条件是整个字符串都符合指定进制,不能只解析前半段。

package main

import (
    "fmt"
    "math/big"
)

func readBigDecimal(s string) (*big.Int, error) {
    // base=10 只接受十进制,避免输入前缀改变协议含义。
    n, ok := new(big.Int).SetString(s, 10)
    if !ok {
        return nil, fmt.Errorf("非法大整数: %q", s)
    }
    return n, nil
}

func main() {
    n, err := readBigDecimal("18446744073709551617")
    if err != nil {
        panic(err)
    }
    fmt.Println(n.String()) // String 默认输出十进制文本。
}
Go math/big 大整数读取入口与 big.Int 的静态关系示意图
图1:Go math/big 大整数读取入口的原创结构示意图,文本、JSON 和大端字节分别连接到 big.Int。

这里不能只判断 n != nilok 才表示解析成功。失败时接收者的值没有可依赖的定义,因此应直接丢弃并返回错误。

流式输入和 JSON 让 big.Int 自己完成读取

big.Int 实现了 fmt.Scanner,所以可以把它交给 fmt.Sscanfmt.Fscan。这种方式适合空白分隔的文本流。JSON 场景则应传指针给 json.Unmarshal;不要先用 float64 接收,否则大整数可能在进入 big.Int 前已经失真。

var fromText big.Int
if _, err := fmt.Sscan("18446744073709551617", &fromText); err != nil {
    // 扫描错误要向上返回,不能把零值当成读取结果。
    return err
}

var fromJSON big.Int
if err := json.Unmarshal([]byte(`18446744073709551617`), &fromJSON); err != nil {
    // 直接解码到 big.Int,保留 JSON 数字的完整整数文本。
    return err
}

如果 JSON 字段是字符串而不是数字,先取字符串再用 SetString,并明确约定是否允许前缀。这样能把协议格式和进制规则放在同一处处理。

读取后怎么输出,避免转换时悄悄溢出

String() 等价于 Text(10),用于普通十进制输出;需要十六进制、二进制或更高进制时使用 Text(base)Text 的进制范围是 2 到 62,输出不会自动带 0x 前缀。协议要求固定字节时,Bytes() 返回大端字节,但它只表达绝对值。

func exportBig(n *big.Int) (string, []byte, error) {
    // 只有确认能放进 int64,才允许做窄化转换。
    if !n.IsInt64() {
        return "", nil, fmt.Errorf("数值超出 int64 范围")
    }
    decimal := n.String()
    hexText := n.Text(16)
    bytes := n.Bytes() // 负数的符号不在 bytes 中,协议需另存符号。
    return decimal + " / 0x" + hexText, bytes, nil
}
Go big.Int 输出到 String Text Bytes 和 int64 的静态边界示意图
图2:big.Int 输出与窄化转换的原创结构示意图,String、Text、Bytes 和 IsInt64 分别对应不同边界。

四个边界问题最容易让读取结果出错

  • 空串或尾部字符:SetString("123x", 10) 失败;不要把它当作成功解析了 123。
  • 进制前缀:base=10 不负责识别 0x,要识别前缀请传 0,或者先在协议层清洗。
  • 负数与字节:Bytes()SetBytes() 是无符号大端绝对值通道,负号需要单独设计。
  • 窄化转换:Int64() 在超范围时结果未定义,先用 IsInt64();同理,转无符号值前检查 IsUint64()

常见问题

SetString 的 base 应该写 0 还是 10?

输入协议固定为十进制就写 10;需要让标准前缀选择进制时写 0。两者都要检查返回的 ok

big.Int 能直接用 fmt.Println 输出吗?

可以。*big.Int 提供默认的十进制字符串表示;需要其他进制时显式调用 Text

为什么 SetBytes 读不出负数?

该方法把字节解释为大端无符号整数,返回的是绝对值。带符号协议应把符号位或符号字段单独解析。

读取成功后能直接调用 Int64 吗?

只有范围确认后才能调用。用 IsInt64 判断,超范围就继续保留 *big.Int 或返回错误。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Lovart品牌色总被改掉怎么办?Brand Kit作用范围与参考图冲突排查Lovart品牌色总被改掉怎么办?Brand Kit作用范围与参考图冲突排查
上一篇
Lovart品牌色总被改掉怎么办?Brand Kit作用范围与参考图冲突排查
Optional orElse 求值怎么配置或排查
下一篇
Optional orElse 求值怎么配置或排查
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    111次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    31次使用
  • OpenCompass大模型评测体系详解:功能、使用指南与应用场景
    OpenCompass
    OpenCompass是上海AI实验室推出的开源大模型评测平台,提供CompassKit、CompassHub和CompassRank三大核心组件,支持LLM及多模态模型的一站式标准化评估与排行榜查询。
    49次使用
  • AGI-Eval大模型评测平台:权威榜单、数据集与人机协同评测方案
    AGI-Eval
    AGI-Eval是由上海交大等高校联合发布的大模型评测社区,提供公正透明的LLM能力榜单、多领域评测集及Data Studio数据服务,助力AI模型性能评估与NLP科研开发。
    30次使用
  • SuperCLUE中文大模型评测基准:功能、能力维度与应用指南
    SuperCLUE
    SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
    265次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码