我有一些代码已从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中,可以是+0.0或-0.0,当r等于时-0.0它将失败检查。
r
+0.0
-0.0
我试图在下面的代码中将负零值进行调整,但它从未命中DEBUG(“ Negative zero”)行。但是r2打印等于+0.0。
r2
// 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
GCC:
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()));
这似乎可行。
好吧,使用doubles 时的一般建议是记住它们是不精确的。因此,如果平等很重要-通常建议使用一些容忍因子。
double
在您的情况下:
if (|r - 0.0| >= EPSILON)
哪里EPSILON是您的公差系数,如果r不是0.0,且EPSILON间隔至少一定,则将为true 。
EPSILON