[英]Detecting and adjusting for negative zero
我有一些代碼從 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
時,檢查失敗。
我試圖在下面的代碼中調整負零,但它從未到達 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
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()));
這似乎有效。
我有一些代碼已經從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
它-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()));
這似乎可行。
我有一些代碼已經從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
它-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()));
這似乎可行。
我有一些代碼已經從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
它-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()));
這似乎可行。
我有一些代碼已經從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
它-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()));
這似乎可行。
我有一些代碼已經從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
它-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()));
這似乎可行。
我有一些代碼已經從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
它-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()));
這似乎可行。
這些可以解決問題 - 但編譯器可能會對其進行優化:
如果 (-v == 0.0) v = 0.0;
如果 (v == -0.0) v = 0.0;
所以我認為這更好:
if (v < DBL_EPSILON && v > -DBL_EPSILON)
v = 0.0;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.