当前位置:首页 > 文章列表 > Golang > Go教程 > Go strconv.ParseFloat 遇到 NaN 和 Inf 怎么区分

Go strconv.ParseFloat 遇到 NaN 和 Inf 怎么区分

来源:17golang原创 2026-09-09 18:44:53 0浏览 收藏

处理配置文件、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、nanNaNmath.IsNaN(v)
Inf、+Infinity正无穷math.IsInf(v, 1)
-Inf、-infinity负无穷math.IsInf(v, -1)

这里的“合法”只说明文本符合解析器规则,不代表它适合直接进入业务计算。例如统计平均值时,NaN 可能污染后续结果;边界计算中的无穷也需要由业务决定是保留、拒绝还是转换为状态。

Go strconv.ParseFloat 将 NaN、Inf 和 Infinity 映射为不同 float64 特殊值的静态关系图
图1:ParseFloat 的输入词、float64 特殊值与 math 判断函数之间的静态对应关系。

用 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,而不是散落在每个调用点。

Go 浮点文本解析层、math.IsNaN 与 math.IsInf 判断层和业务状态层的边界关系图
图2:将原始文本、ParseFloat 错误、float64 特殊值和业务状态分成清晰边界,避免错误类型混用。

几个容易写错的判断

  • 不要写 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 的语义。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Linux inotify 监听目录移动后为什么原 watch 描述符会失效Linux inotify 监听目录移动后为什么原 watch 描述符会失效
上一篇
Linux inotify 监听目录移动后为什么原 watch 描述符会失效
Go x509.SystemCertPool 在不同操作系统上为什么结果不同
下一篇
Go x509.SystemCertPool 在不同操作系统上为什么结果不同
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之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推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    667次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    684次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    731次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    699次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    532次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码