cgal - CGAL 4.12 的 Lazy_exact_nt 不准确?
问题描述
下面的测试函数在 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
解决方案
这是 CGAL 中的一个错误。mpfr_set_emin (-1073);
除非您自己也直接使用 MPFR,否则您可以通过在程序开头调用来轻松解决此特定值。但是,它可能无法解决所有此类问题(我们还缺少对 mpfr_subnormalize 的调用),例如Gmpq(DBL_TRUE_MIN)*3/2
. 最安全的是使用旧代码。为此,#if MPFR_VERSION_MAJOR >= 3
在文件 Gmpq.h 和 mpq_class.h 中找到一个测试,并将其替换为#if 0
. 我在CGAL 的 github 上提交了这个文件,所以我们不要忘记修复它。
推荐阅读
- jenkins - 如何检查包是否已从 Jenkins 管道上传到 Artifactory?
- bash - 使用存储在不同文件 awk 中的值
- node.js - 我应该如何在 React 中实现 Google 登录(使用 Express 后端)
- javascript - 将 CSS 样式应用于 Datatable 中的特定列
- sandbox - 在自定义规则中禁用沙箱
- reactjs - 未处理的拒绝 (SyntaxError):JSON 输入的意外结束
- android - 为什么我在 Google Play 的 Crash Stack 报告中看不到我的业务代码
- postgresql - sqlalchemy 中的复合 WHERE 子句
- reactjs - 如何使用httpget方法通过.net核心中的url传递对象?
- c# - 路线在邮递员中无法正常工作,因此不允许发布