CGAL 4.12的Lazy_exact_nt不准确?

时间:2018-05-18 19:32:21

标签: cgal

下面的测试函数与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

1 个答案:

答案 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提交了这个,所以我们不会忘记解决它。