Go strconv.ParseFloat 遇到 NaN 和 Inf 怎么区分
来源:17golang原创
时间:2026-09-09 18:44:53 501浏览 收藏
处理配置文件、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 的语义。
-
860 收藏
-
843 收藏
-
826 收藏
-
809 收藏
-
792 收藏
-
301 收藏
-
313 收藏
-
184 收藏
-
173 收藏
-
Golang · Go教程 | 3小时前 | 定时任务 · 并发控制 · Go教程 · 资源释放 · Go Goroutine context 后台任务 time.Ticker Ticker.Stop297 收藏
-
271 收藏
-
Golang · Go教程 | 4小时前 | web安全 · Go教程 · html/template · 模板渲染 · Go web安全 html/template HTML转义 template.HTML390 收藏
-
461 收藏
-
209 收藏
-
301 收藏
-
Golang · Go教程 | 6小时前 | 标准库 · go · 模板 · FuncMap · 模板函数 · Go Parse text/template FuncMap execute Funcs319 收藏
-
125 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习