微信限制:不能放置链接,代码样式比较奇怪,发布后不能更新。。。
推荐 阅读原文(并建议用浏览器打开,因为微信自带浏览器内核渲染也有问题):
很久没写文章了,最近抽时间拼凑一篇短文,记录一下 比较两个(二进制)浮点数是否相等 的几种方法(虽然本文使用 C++ 演示,但原理和语言无关)。
本文主要参考了 “浮点数专家” Bruce Dawson 写的 Comparing Floating Point Numbers, 2012 Edition,也推荐他 关于浮点数的其他文章(最近还一直在更新 ?)。
本文提到的
Equals()
/AlmostEqualsAbs()
/AlmostEqualsRel()
/AlmostEqualsUlp()
函数的具体实现参考almost_equals.h
(在线演示)?
绝对相等?不靠谱
比较两个数是否相等,最直观的 比较方法 就是直接使用 ==
进行比较:
f1 == f2 // Equals()
根据 IEEE 754 浮点数标准,浮点数 (其中 b 为 固定的基数,± 为 符号位,p 为 尾数,e 为 指数)表示为 符号位-指数-尾数 形式:
十进制浮点数(
b == 10
)就是 数学中常用的 科学计数法 (scientific notation)二进制浮点数(
b = 2
)常用于 计算机中的表示和存储,其中 单精度 (single-precision) 对应 32 位,双精度 (double-precision) 对应 64 位
在 C++ 中,
0.1
属于 双精度浮点数,0.1f
属于 单精度浮点数。为什么计算机使用二进制浮点数?因为基于现有的 CPU 架构,二进制运算效率更高。
虽然在数学上,任意十进制数和二进制数可以 相互转换,它们的 浮点数表示形式 也可以相互转换:
在二进制科学计数法中,十进制数 0.1
的尾数 p 是 1.100110011...
(0011
循环)但是,有限精度 的二进制浮点数 不能准确表示 所有的十进制数(在线转换工具):