我看过类似的帖子:
以及许多其他相关的帖子。
我在 d3js 库中看到,它使用以下比较:
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
可以在 C/C++ 中使用它来比较double
和float
吗?
我看过类似的帖子:
以及许多其他相关的帖子。
我在 d3js 库中看到,它使用以下比较:
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
可以在 C/C++ 中使用它来比较double
和float
吗?
以下代码是否足够?
不。
如果不是,为什么?
因为它与==
(至少对于非边缘情况)相同。
这还不够,因为如果 a 或 b 为 NaN,则返回 true
这基本上是关于使用“几乎相等”可以以某种方式弥补对浮点计算不够了解以获得可靠结果的概念。“几乎相等”是一种先进的技术;它经常会咬你,因为它不具有传递性(即a
“几乎等于”b
和b
“几乎等于”c
并不意味着a
“几乎等于” c
)。如果您是一名认真的程序员,请学习浮点工作原理的基础知识。没有人会惊讶这(1/2)*2)
不是 1,但不知何故人们不理解它(1.0/10.0)*10.0
也不是 1(除非你的系统有十进制浮点数),并且出于完全相同的原因。这是教育的失败,学习它。(吐槽结束)
与容差进行比较的想法是,几乎完全相同的两个值可能希望被视为相同。如果你有2.000000000000
and 2.000000000001
,它们应该相等还是不相等?如果它们应该是,那么您的代码将失败。
你真的需要阅读这份文件:
https://ece.uwaterloo.ca/~dwharder/NumericalAnalysis/02Numerics/Double/paper.pdf
这是 Golberg 的论文 = 每个程序员都应该知道的关于浮点的知识。
你的错误是,你读的文章有
diff = A - B;
return (diff < EPSILON) && (-diff > EPSILON);
而且,你把EPSILON = 0
它变成
if (!(a > b) && !(a < b))
你不应该假设EPSILON
为0
. 因为您应该考虑一个位错误是我们称之为浮点/双精度比较EPSILON
。