Go strconv.ParseFloat 遇到 NaN 和 Inf 怎么区分
处理配置文件、CSV 或接口字段时,strconv.ParseFloat 可能返回的不是普通数字,而是 NaN、正无穷或负无穷。它们都能落到 float64,但含义完全不同:NaN 表示结果不可定义,+Inf 与 -Inf 仍然有方向。判断时要先看 err,再用 math.IsNaN 和 math.IsInf,不要把所有非有限值混成一个“异常数字”。
NaN不等于自身,不能用v == v或普通等号识别。math.IsInf(v, 1)只判断正无穷,math.IsInf(v, -1)只判断负无穷。- 普通数字溢出时也可能得到 Inf,但同时带
strconv.ErrRange,必须先处理错误。
ParseFloat 的特殊值到底返回什么
官方 strconv 文档把特殊文本作为 ParseFloat 的合法输入:NaN 不区分大小写;Inf 和 Infinity 也不区分大小写,并允许带正负号。成功解析时,返回值位于第一个结果,err 为 nil。
| 输入 | 返回值 | 推荐判断 |
|---|---|---|
NaN、nan | NaN | math.IsNaN(v) |
Inf、+Infinity | 正无穷 | math.IsInf(v, 1) |
-Inf、-infinity | 负无穷 | math.IsInf(v, -1) |
这里的“合法”只说明文本符合解析器规则,不代表它适合直接进入业务计算。例如统计平均值时,NaN 可能污染后续结果;边界计算中的无穷也需要由业务决定是保留、拒绝还是转换为状态。

用 math.IsNaN 和 math.IsInf 分支判断
最稳妥的分类函数把解析失败与解析成功分开。解析失败时,返回值即使看起来像无穷,也不能跳过错误检查;只有 err == nil 后的 Inf 才是输入明确要求的特殊值。
package main
import (
"errors"
"fmt"
"math"
"strconv"
)
func classifyFloat(raw string) (string, error) {
// 不主动 TrimSpace,保持 ParseFloat 对输入边界的原始判断。
value, err := strconv.ParseFloat(raw, 64)
if err != nil {
var numErr *strconv.NumError
// 先区分范围错误,避免把普通数字溢出误报成合法 Inf。
if errors.As(err, &numErr) && errors.Is(numErr.Err, strconv.ErrRange) {
return "range-error", err
}
return "syntax-error", err
}
// NaN 不能用等号比较,必须调用 math.IsNaN。
if math.IsNaN(value) {
return "nan", nil
}
// sign=1 与 sign=-1 分别锁定正、负无穷。
if math.IsInf(value, 1) {
return "+inf", nil
}
if math.IsInf(value, -1) {
return "-inf", nil
}
return "finite", nil
}
func main() {
// 原始文本可来自配置或消息,分类结果交给上层业务处理。
for _, raw := range []string{"12.5", "NaN", "-Infinity", "1e10000"} {
kind, err := classifyFloat(raw)
fmt.Printf("%q => %s, err=%v\n", raw, kind, err)
}
}
math.IsInf(value, 0) 可以一次判断正负无穷,但需要知道方向时,使用 1 和 -1 更直观。分类函数还保留了原始错误,调用方可以记录 NumError.Num,而不必从展示文本反推输入。
把输入词和数值状态分开存
这类问题适合采用“解析层与业务层分离”的小模式:解析层只负责把文本转换成值和错误,业务层再决定 NaN 或 Inf 的策略。不要把 NaN 转成 0 来“让流程继续”,因为 0 是确定的数值,NaN 是未知或不可定义,两者会让后续统计产生不同结果。
在记录结构中可以同时保留 raw、kind 和可选的 value。这样日志或重试场景还能看到原始词,计算模块则只接收已经分类的结果。若业务只接受有限数字,就在这一层拒绝 nan、+inf、-inf,而不是散落在每个调用点。

几个容易写错的判断
- 不要写
value == math.NaN()。 IEEE 754 的 NaN 不等于任何值,包括它自己,直接调用math.IsNaN。 - 不要只判断
math.IsInf。 例如一个超出目标精度范围的普通数字可能返回 Inf 和ErrRange,这不是输入里的合法 Infinity。 - 不要默认忽略空格。 如果接口约定允许首尾空白,可以在调用 ParseFloat 前明确清洗;否则应保留严格输入,避免把数据问题隐藏起来。
- 注意
bitSize。 传 32 时函数仍返回float64,但按 float32 精度解析;传 64 才按 float64 精度解析。
常见问题
NaN 和空字符串都是解析失败吗?
不是。空字符串通常返回语法错误;NaN 是 ParseFloat 认可的特殊值,成功时 err == nil,应使用 math.IsNaN 识别。
Infinity 和 Inf 在 Go 中有什么区别?
对 ParseFloat 来说,两者都表示无穷,且匹配时不区分大小写;结果仍应通过 math.IsInf 判断方向。
能不能把 NaN 当成 0 保存?
只有业务明确规定缺失值映射为 0 时才可以,而且应在分类后显式转换;解析层不应擅自改变 NaN 的语义。
Linux inotify 监听目录移动后为什么原 watch 描述符会失效
- 上一篇
- Linux inotify 监听目录移动后为什么原 watch 描述符会失效
- 下一篇
- Go x509.SystemCertPool 在不同操作系统上为什么结果不同
-
- Golang · Go教程 | 13分钟前 |
- Go strconv.NumError 怎么拿到具体转换字段
- 301浏览 收藏
-
- Golang · Go教程 | 2小时前 | Timer · go · 性能优化 · time.After ·
- Go time.After 在高频循环中为什么会造成延迟对象堆积
- 313浏览 收藏
-
- Golang · Go教程 | 2小时前 |
- Go strconv.AppendQuote 怎么低分配地拼接带引号字符串
- 184浏览 收藏
-
- Golang · Go教程 | 3小时前 | 并发 · 定时器 · go · time.Timer time.NewTimer time.Stop time.Reset
- Go time.Timer 通道读不到事件时怎么判断定时器当前状态
- 173浏览 收藏
-
- Golang · Go教程 | 3小时前 | 定时任务 · 并发控制 · Go教程 · 资源释放 · Go Goroutine context 后台任务 time.Ticker Ticker.Stop
- Go time.Ticker 不再使用时怎么停止避免后台任务残留
- 297浏览 收藏
-
- Golang · Go教程 | 3小时前 | embed · Go教程 · html/template · 模板渲染 · Go html/template embed.FS ParseFS 模板嵌入
- Go html/template ParseFS 怎么从嵌入文件加载页面
- 271浏览 收藏
-
- Golang · Go教程 | 4小时前 | web安全 · Go教程 · html/template · 模板渲染 · Go web安全 html/template HTML转义 template.HTML
- Go html/template 如何安全渲染受信任的 HTML 片段
- 390浏览 收藏
-
- Golang · Go教程 | 4小时前 | go · 模板 · 安全 · html/template URL转义 Go模板
- Go html/template 中 URL 参数为什么会被转义
- 461浏览 收藏
-
- Golang · Go教程 | 4小时前 |
- Go text/template Clone 怎么为不同渠道复用模板
- 209浏览 收藏
-
- Golang · Go教程 | 4小时前 |
- Go text/template 设置 missingkey 后怎么控制缺字段行为
- 301浏览 收藏
-
- Golang · Go教程 | 6小时前 |
- Go multipart boundary 缺失时怎么定位表单解析失败
- 125浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 49次使用
-
- SuperCLUE
- SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
- 200次使用
-
- C-Eval
- 深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
- 136次使用
-
- AI Prompt Library
- 探索AI Prompt Library免费资源库,涵盖营销、写作及多场景AI提示词。兼容ChatGPT、Claude等工具,一键复制优化输出,提升工作效率。
- 68次使用
-
- Generrated
- Generrated汇集9300+张DALL·E生成图像及对应提示词,支持查看完整图集、对比DALL·E 2与3版本差异,是AI绘图新手学习Prompt设计与获取创作灵感的实用工具。
- 48次使用
-
- Java 性能优化上线清单:从定位、改造到灰度发布
- 2026-06-11 860浏览
-
- Spring Boot 压测验证:Gatling、JMeter 与性能回归门禁
- 2026-06-11 843浏览
-
- Java NMT 非堆内存排查:Direct Buffer、线程栈与 Metaspace 分析
- 2026-06-11 826浏览
-
- Spring Boot 容器内存优化:JVM 堆、非堆与 MaxRAMPercentage
- 2026-06-11 809浏览
-
- Tomcat 连接与线程参数调优:maxThreads、acceptCount 与 KeepAlive
- 2026-06-11 792浏览
