区分零和负零

10

我在代码中遇到一种情况,一个函数返回一个double类型的值,这个值可能是0、负0或其他值。我需要区分0和负0,但默认的double比较方法不能区分。由于double类型的格式,C++不允许使用位运算符比较double类型的值,因此我不知道该怎么办。如何区分这两个值?


为什么需要消除这些歧义? - doctorlove
嗯,不确定我是否正确理解了问题。您需要比较两个“double”吗?并区分正/负值或者只想将它们视为“零”? - Kiril Kirov
3
例如,1e-300 / -1e300 - Oliver Charlesworth
7
比较确切的相等性通常是正确的。而负零是为特定使用情况设计的。为了利用负零,您必须检测它。 - David Heffernan
2
@BenjaminBannier 这并不是那个问题的重复。事实证明,那个问题起初根本就不涉及负零,它只是一个普通的负数,在默认精度下,打印时看起来像负零。 - user743382
显示剩余5条评论
3个回答

18

9
由于双精度浮点数的格式,C++不允许使用位运算符比较双精度浮点数,因此我不确定该如何进行。

首先,C++并没有对/类型规定任何标准。

假设您正在谈论IEEE 754的binary32和binary64格式,则它们专门设计为在将其位模式解释为整数时保持其顺序,以便非FPU可以对其进行排序;这就是它们具有偏置指数的原因。

许多SO帖子讨论此类比较;这里是最相关的一个。一个简单的检查方法是

bool is_negative_zero(float val)
{
   return ((val == 0.0f) && std::signbit(val));
}

这是可行的,因为0.0f == -0.0f,但在像atan2这样的地方,符号会产生影响,或者当除以-0而不是+0导致相应的无穷大时。

-3

要在C语言中明确测试a是否等于-0,请按照以下步骤进行:

if (*((long *)&a) == 0x8000000000000000) {
    //  a is -0
}

2
只有在您知道平台使用该字节序的IEC 60559表示,并且longdouble大小相同时,才能这样做... - Toby Speight

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接