新闻中心
深入理解Go语言中NaN的比较行为

本文深入探讨了go语言中浮点数`nan`(not a number)的特殊比较行为。根据ieee 754浮点数标准,`nan`不等于任何值,包括其自身。文章解释了这一设计背后的原因,即`nan`代表着不可表示的数值,并提供了go语言示例来演示其比较特性。同时,介绍了使用`math.isnan()`函数进行`nan`检测的正确方法,并提及了`x != x`这种经典的`isnan`实现技巧。
什么是NaN?
在计算机科学中,NaN是“Not a Number”的缩写,意为“不是一个数字”。它是一种特殊的浮点数值,用于表示某些数学运算的结果无法用实数或无穷大来表示的情况。常见的导致NaN的运算包括:
- 0 / 0 (零除以零)
- ∞ - ∞ (无穷大减无穷大)
- sqrt(-1) (负数的平方根)
- 任何涉及NaN的操作(例如 NaN + 5 结果仍是 NaN)
在Go语言中,可以通过math.NaN()函数获取一个NaN值。
为何NaN不等于NaN?
这是NaN最令人困惑但也是其核心的特性:NaN不等于任何值,包括它自己。这一行为是由IEEE 754浮点数标准严格定义的。IEEE 754标准明确规定:
- −∞ = −∞
- +∞ = +∞
- x ≠ NaN,对于任何x,包括NaN自身。
设计理念
之所以这样设计,是因为NaN代表着一个“无效”或“不可表示”的数值状态。当一个运算结果是NaN时,它可能来源于多种不同的无效操作(例如,0/0和sqrt(-1)虽然都产生NaN,但它们代表的“无效”来源是不同的)。因此,系统无法保证两个NaN值代表的是同一个“不可表示”的数字。将它们视为不相等,可以避免在比较时产生误导性的结果。
Go语言中的NaN比较示例
在Go语言中,这一特性同样适用。下面的代码示例演示了NaN与自身以及与其他值的比较结果:
package main
import (
"fmt"
"math"
)
func main() {
nan1 := math.NaN()
nan2 := math.NaN()
posInf := math.Inf(1) // +Inf
negInf := math.Inf(-1) // -Inf
fmt.Printf("nan1: %f\n", nan1)
fmt.Printf("nan2: %f\n", nan2)
fmt.Printf("posInf: %f\n", posInf)
fmt.Printf("negInf: %f\n", negInf)
fmt.Println("--- 比较结果 ---")
// NaN与自身的比较
fmt.Printf("nan1 == nan1: %t\n", nan1 == nan1) // false
fmt.Printf("nan1 == nan2: %t\n", nan1 == nan2) // false
// NaN与其他数值的比较
fmt.Printf("nan1 == 0.0: %t\n", nan1 == 0.0) // false
fmt.Printf("nan1 == posInf: %t\n", nan1 == posInf) // false
// 无穷大值的比较(作为对比)
fmt.Printf("posInf == posInf: %t\n", posInf == posInf) // true
fmt.Printf("negInf == negInf: %t\n", negInf == negInf) // true
fmt.Printf("posInf == negInf: %t\n", posInf == negInf) // false
}运行上述代码,你会发现nan1 == nan1和nan1 == nan2的输出都是false,这正是IEEE 754标准所规定的行为。而+Inf和-Inf则可以与自身相等。
如何正确检测NaN?
由于NaN不等于自身,我们不能通过value == math.NaN()或value == value来直接判断一个浮点数是否为NaN(后者会返回false,但我们想要的是true来表示它是NaN)。
Kotlin Android 中文开发帮助文档 PDF版
这本书并不是一本语言参考书,但它是一个Android开发者去学习Kotlin并且使用在自己项目中的一个工具。我会通过使用一些语言特性和有趣的工具和库来解决很多我们在日常生活当中都会遇到的典型问题。 这本书是非常具有实践性的,所以我建议你在电脑面前跟着我的例子和代码实践。无论何时你都可以在有一些想法的时候深入到实践中去。 这本书适合你吗? 写这本书是为了帮助那些有兴趣 使用Kotlin语言来进行开发的Android开发者。 如果你符合下面这些情况,那这本书是适合你的: 你有相关Android开发和Andro
11
查看详情
Go语言标准库提供了专门的函数来检测NaN:math.IsNaN()。
package main
import (
"fmt"
"math"
)
func main() {
val1 := math.NaN()
val2 := 123.45
fmt.Printf("math.IsNaN(%f): %t\n", val1, math.IsNaN(val1)) // true
fmt.Printf("math.IsNaN(%f): %t\n", val2, math.IsNaN(val2)) // false
}math.IsNaN()函数会返回一个布尔值,准确指示给定的浮点数是否为NaN。
利用NaN特性的经典技巧
在许多系统和语言中,利用NaN不等于自身的特性,可以实现一个简单的isNaN函数:
// isNaN checks if a float64 value is NaN
func isNaN(f float64) bool {
return f != f
}
// 示例
func main() {
nanVal := math.NaN()
numVal := 10.0
fmt.Printf("isNaN(%f): %t\n", nanVal, isNaN(nanVal)) // true
fmt.Printf("isNaN(%f): %t\n", numVal, isNaN(numVal)) // false
}这个技巧非常巧妙,因为它直接利用了NaN的定义行为。当f是NaN时,f != f为真;当f是任何其他有限数或无穷大时,f != f为假。尽管这个技巧在Go语言中是可行的,但为了代码的清晰性和可读性,以及遵循标准库的最佳实践,强烈建议使用math.IsNaN()函数。
注意事项与总结
- 理解IEEE 754标准:NaN的特殊行为是IEEE 754浮点数标准的核心部分,理解这一标准对于处理浮点数至关重要。
- 避免直接比较NaN:永远不要使用==或!=运算符直接比较NaN值,因为它不会给出预期的结果。
- 使用math.IsNaN():在Go语言中,检测一个浮点数是否为NaN的唯一可靠和推荐方法是使用math.IsNaN()函数。
- NaN的传播性:任何涉及NaN的数学运算结果通常仍是NaN,这有助于在复杂的计算中追踪无效操作的来源。
通过理解NaN的这些特性,开发者可以更准确、更安全地处理Go语言中的浮点数计算,避免潜在的逻辑错误。
以上就是深入理解Go语言中NaN的比较行为的详细内容,更多请关注其它相关文章!
# 它是
# QQ群排名优化网站
# 营销推广策划书摘要
# 漯河电力设备网站建设
# 淄博网站建设第一章
# 山东公司网站定制推广
# 锦江区网站营销与推广
# 推广策划营销
# 微网站建设方案文库
# 百度营销怎么关闭推广
# seo编自适应模板
# 都是
# 仍是
# go
# 运算符
# 帮助文档
# 的是
# 不等于
# 这本书
# 这一
# 浮点数
# 标准库
# ai
# go语言
# 计算机
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
Win11怎么设置鼠标主按键_Win11鼠标左右键功能互换
怎样把文件彻底粉碎无法恢复_Windows下安全删除敏感数据【隐私保护】
在J*a中如何使用Exception包装底层异常_异常包装与信息传递方法说明
Node.js 中使用 node-cron 实现定时 API 数据抓取与处理
J*aScript中赋值与自增运算符的复杂交互与执行机制
小红书网页版入口链接分享 小红书官网直接进
厨房不锈钢水槽发黑生锈怎么处理_水槽用可乐+锡纸2分钟抛亮如新
在Socket.IO连接中实现Access Token自动更新与动态重连
word邮件合并后日期格式不对怎么改_Word邮件合并日期格式修改方法
如何在CSS中使用浮动制作导航栏_float实现水平菜单
反效果?《战地6》免费试玩开启后玩家数不升反降
vivo手机参数配置怎么增强信号_vivo手机参数配置信号增强方法
win11 Snap Layouts怎么用 Win11窗口布局与分屏多任务高效指南【必学】
PyTorch模型训练准确率不提升:诊断与修复常见指标计算错误
德邦快递查询平台 德邦快递物流信息查询入口
PySpark中高效提取字符串右侧可变长度数字:使用regexp_extract
12306怎么选座位选到安静区_12306选座安静区域选择策略
《噬血代码2》新预告片发布 展示游戏剧情
Windows电脑怎么截图最方便_系统自带截图工具的5种神仙用法【技巧】
抖音网页版企业服务中心登录入口_抖音网页版企业登录平台
J*aScript 字符串标签转换:使用正则表达式高效替换
在J*a中如何使用BigDecimal进行高精度计算_BigDecimal类应用指南
汽水音乐车机版横屏版7.1 汽水音乐车机版横屏版下载入口
TypeScript/J*aScript:高效查找数组中首个唯一ID对象
J*a里如何使用N*igableMap进行导航操作_可导航Map操作技巧解析
高德地图公交到站提醒失败如何解决 高德提醒权限设置
Linux如何构建多环境配置管理_Linux多环境配置方案
抓大鹅解压小游戏 抓大鹅摸鱼解压入口
大麦的“候补”是什么意思 大麦候补购票规则【详解】
离线运行Go语言之旅:本地部署与GOPATH配置指南
漫蛙2在线漫画入口 漫蛙正版漫画网页版直达
《明末:渊虚之羽》设计师谈设计角色:那会刚毕业 充满激情
PySpark中从现有列右侧提取可变长度字符创建新列的教程
虫虫漫画精品漫画官网_虫虫漫画精品漫画官网进入精品漫画
Composer的 "conflict" 字段有什么用_如何声明不兼容的包以避免依赖冲突
html怎么运行外部js文件中的函数_运html外js文件函数法【技巧】
想当下一个《2077》?《心之眼》Steam评价升至"多半好评"
Go语言中动态执行代码字符串的策略与实践
CSS Grid如何控制元素对齐_align-items与justify-items组合使用
MinIO大规模对象列表性能瓶颈深度解析与外部元数据管理策略
HTML长属性值处理:表单action路径优化与代码规范应对
蛙漫漫画官网在线入口 蛙漫全本漫画免费阅读平台
PHP中SSG-WSG API的AES加密实践:正确使用初始化向量
漫蛙MANWA漫画主页官方入口 漫蛙漫画最新在线阅读地址
Go语言中Map值调用指针接收器方法的限制与应对
J*aScript中在Map循环中检测并处理空数组元素
可靠CSGO开箱平台解析 CSGO开箱网合集
AO3官网镜像链接 Archive of Our Own同人文在线浏览
俄罗斯方块最新版入口 俄罗斯方块在线玩官网入口
Odoo 16:在表单视图中基于当前记录动态修改Tree视图属性


2025-11-24
浏览次数:次
返回列表