【发布时间】:2015-05-16 06:32:27
【问题描述】:
我知道浮点运算和精度损失的常见问题,所以这不是关于为什么0.1 + 0.2 != 0.3 等的常见问题。
相反,我实际上想在 C++ 中实现一个二进制谓词(以 100% 符合标准的方式),它实际上实现了一个真正的数学 equivalence relationship(即自反、传递和对称) ),这样如果两个双精度值在所有方面都表示完全相同的值,它们就属于同一个等价类,区分像 0.0 和 -0.0 这样的极端情况,但将所有 NaN 值视为在同一个等价类中。 (特别是,默认的== 不是我想要的,因为在NaN 的情况下它是非自反的,并且不区分0.0 和否定的-0.0,我想在不同的等价类,因为它们实际上是不同的值并导致不同的运行时行为)。
不依赖于任何类型的双关语或任何实现定义的行为的最短和最简单的方法是什么?到目前为止,我得到了:
#include <cmath>
bool equiv(double x, double y)
{
return (x == y && (x != 0.0 || std::signbit(x) == std::signbit(y))) ||
(std::isnan(x) && std::isnan(y));
}
我相信这可以处理我之前了解和描述的极端情况,但是还有其他我遗漏的不能处理的极端情况吗?并且上述二元谓词是否保证根据 C++ 标准定义等价关系,或者任何行为未指定、实现定义等?
【问题讨论】:
-
NaN 可以有不同的“NaN 有效载荷”,尽管您可能并不关心,但它们按位不同。
-
-
@Trantorian 你有没有想过用定点小数来代替?
-
-0 和 0 在数学上是等价的。
-
x != 0.0可能是多余的,但在我看来是正确的
标签: c++ floating-point