检测并调整为负零 [英] Detecting and adjusting for negative zero

查看:140
本文介绍了检测并调整为负零的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些code已经端口从Java到C ++

I have some code that has been port from Java to 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 ++ 研究可以是 +0.0 -0.0 ,当研究等于 -0.0 失败的检查。

But in C++ r can be either +0.0 or -0.0, when r equals -0.0 it fails the check.

我试着在下面的code调整为负零,但它从来没有击中DEBUG(负零)行。但 R2 可以打印出等于 +0.0

I've tried to adjust for negative zero in the code below but it never hits the DEBUG("Negative zero") line. But r2 does print out equal to +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);

任何建议?

测试code:

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

答:

我用@阿密特的回答做到以下几点。

I've used @amit's answer to do the following.

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

这似乎工作。

Which seems to work.

推荐答案

那么,使用 s被记住他们不是精确的,当一个通用的建议。因此,如果平等是很重要的 - 使用一些糖耐量因子通常建议

Well, a generic suggestion when using doubles is remembering they are not exact. Thus, if equality is important - using some tolerance factor is usually advised.

在你的情况:

if (|r - 0.0| >= EPSILON)

其中, EPSILON 是糖耐量因子,将是否产生真正的研究不是0.0,至少 EPSILON 的间隔。

where EPSILON is your tolerance factor, will yield true if r is not 0.0, with at least EPSILON interval.

这篇关于检测并调整为负零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆