c++ - 检测和调整负零

标签 c++ algorithm negative-number

我有一些代码已经从 Java 移植到 C++

// since this point is a vector from (0,0,0), we can just take the
// dot product and compare
double r = point.dot(normal);
return (r>=0.0);

但在 C++ 中,当 r 等于 时,r 可以是 +0.0-0.0 -0.0 未通过检查。

我试图在下面的代码中调整负零,但它从未达到 DEBUG("Negative zero") 行。但是 r2 确实打印出等于 +0.0

// since this point is a vector from (0,0,0), we can just take the
// dot product and compare
double r = point.dot(normal);
if (std::signbit(r)){
    double r2 = r*-1;
    DEBUG("r=%f r=%f", r,r2);
    if (r2==0.0) {
        DEBUG("Negative zero");
        r = 0.0; //Handle negative zero
    }
}
return (r>=0.0);

有什么建议吗?

测试代码:

DEBUG("point=%s", point.toString().c_str());
DEBUG("normal=%s", normal->toString().c_str());
double r = point.dot(normal);
DEBUG("r=%f", r);
bool b = (r>=0.0);
DEBUG("b=%u", b);

测试结果:

DEBUG - point=Vector3D[ x=1,y=0,z=0 ]
DEBUG - normal=Vector3D[ x=0,y=-0.0348995,z=0.0348782 ]
DEBUG - r=0.000000
DEBUG - b=1
DEBUG - point=Vector3D[ x=1,y=0,z=0 ]
DEBUG - normal=Vector3D[ x=-2.78269e-07,y=0.0174577,z=-0.0174391 ]
DEBUG - r=-0.000000
DEBUG - b=0

海湾合作委员会:

Target: x86_64-linux-gnu
--enable-languages=c,c++,fortran,objc,obj-c++ 
--prefix=/usr 
--program-suffix=-4.6 
--enable-shared 
--enable-linker-build-id 
--with-system-zlib 
--libexecdir=/usr/lib 
--without-included-gettext 
--enable-threads=posix 
--with-gxx-include-dir=/usr/include/c++/4.6 
--libdir=/usr/lib 
--enable-nls 
--with-sysroot=/ 
--enable-clocale=gnu 
--enable-libstdcxx-debug 
--enable-libstdcxx-time=yes 
--enable-gnu-unique-object 
--enable-plugin 
--enable-objc-gc 
--disable-werror 
--with-arch-32=i686 
--with-tune=generic 
--enable-checking=release 
--build=x86_64-linux-gnu 
--host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) 

旗帜:

CXXFLAGS += -g -Wall -fPIC

回答:

我使用@amit 的回答来执行以下操作。

return (r>=(0.0-std::numeric_limits<double>::epsilon()));

这似乎有效。

最佳答案

嗯,使用 double 时的一般建议是记住它们不是精确的。因此,如果平等很重要 - 通常建议使用一些容差因子。

在你的情况下:

if (|r - 0.0| >= EPSILON)

其中 EPSILON 是您的容差系数,如果 r 不为 0.0 且间隔至少为 EPSILON,则结果为真。

关于c++ - 检测和调整负零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13767744/

相关文章:

c++ - 如何制作节点图以与 Dijkstra 的最短路径一起使用?

c++ - 带链接列表的哈希表中的前 10 个频率

c++ - 在计算所有可能路径问题时计算 nCr

c++ - 模板类无法正确构建

algorithm - 在matlab中查找所有可能的排列/组合以等于特定的和

algorithm - 什么是可用于有效查找对象是否与一组模式中的任何一个匹配的算法/结构?

c# - C# 和 sql 中的负日期

java - 如何根据单词范围检查输入单词的位置?

java - 2 的十六进制数补码在 Java 中转为十进制

r - 为什么两个向量之间的余弦相似度可以为负?