下面的测试函数与CGAL 4.9.1一样正常工作,但CGAL 4.12的计算不准确。任何可能导致问题的想法(详见下文)?
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
typedef CGAL::Exact_predicates_exact_constructions_kernel K;
typedef K::FT dbl;
void test4()
{
// 1. Create the smallest possible double and verify
double smallDouble(1.0);
while(smallDouble/2.0>0) smallDouble/=2.0;
if(smallDouble/2.0==0) cout<<"can't divide smallDouble anymore, as expected"<<endl;
// 2. Make it a dbl (K::FT)
dbl a(smallDouble);
// 3. Let b be even smaller ( smaller than the smallest double )
dbl b(a/2.0);
// 4. Show interval and try fit_in_double
cout<<"a.approx()="<<a.approx()<<endl;
cout<<"b.approx()="<<b.approx()<<endl;
double d;
if(CGAL::internal::fit_in_double(b,d))
{
cout<<"Yes, b fits in double d: "<<d<<endl;
}
else
{
cout<<"Before b.exact(): b does not fit back into double (as expected)"<<endl;
}
// 5. Call exact and try fit_in_double again
cout<<"\nCalling exact()"<<endl;
b.exact();
cout<<"a.approx()="<<a.approx()<<endl;
cout<<"b.approx()="<<b.approx()<<endl;
if(CGAL::internal::fit_in_double(b,d))
{
cout<<"Yes, after exact() b fits in double d: "<<d<<" - Huh, not as expected!"<<endl;
}
else
{
cout<<"NOK after exact()"<<endl;
}
if(b<a) cout<<"b<a, as expected"<<endl;
else cout<<"b >= a, not expected"<<endl;
double c(to_double(b));
cout<<"c="<<c<<endl;
if(c==b) cout<<"c==b, not as expected"<<endl;
}
CGAL4.9.1的输出是
can't divide smallDouble anymore, as expected
a.approx()=[4.94066e-324;4.94066e-324]
b.approx()=[0;4.94066e-324]
Before b.exact(): b does not fit back into double (as expected)
Calling exact()
a.approx()=[4.94066e-324;4.94066e-324]
b.approx()=[0;4.94066e-324]
NOK after exact()
b<a, as expected
c=0
CGAL4.12的输出是
can't divide smallDouble anymore, as expected
a.approx()=[4.94066e-324;4.94066e-324]
b.approx()=[0;4.94066e-324]
Before b.exact(): b does not fit back into double (as expected)
Calling exact()
a.approx()=[4.94066e-324;4.94066e-324]
b.approx()=[4.94066e-324;4.94066e-324]
Yes, after exact() b fits in double d: 4.94066e-324 - Huh, not as expected!
b >= a, not expected
c=4.94066e-324
c==b, not as expected
详细信息:Ubuntu 18.04,gcc 7.3。我使用脚本CGAL412 / Scripts / scripts / cgal_create_cmake_script来创建CMakeLists.txt,因此编译器选项应该是正确的。 CGAL4.12已使用
从源代码编译而来cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/CGAL412 ../..
make
make install
答案 0 :(得分:1)
这是CGAL中的错误。除非您自己直接使用MPFR,否则您可以通过在程序开头调用mpfr_set_emin (-1073);
轻松解决此特定值。但是,它可能无法解决所有此类问题(我们也缺少对mpfr_subnormalize的调用),例如Gmpq(DBL_TRUE_MIN)*3/2
。最安全的是使用旧代码。为此,在文件Gmpq.h和mpq_class.h中找到测试#if MPFR_VERSION_MAJOR >= 3
,并将其替换为#if 0
。
我在CGAL's github提交了这个,所以我们不会忘记解决它。