【问题标题】:Differing output between C++ and NativeCall in RakuRaku 中 C++ 和 NativeCall 之间的不同输出
【发布时间】:2019-10-27 15:49:55
【问题描述】:

我正在尝试为取自herecumulative distribution function 编写一个函数。

这是我的cpp 代码:

#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;

double normalCDF( double x )
{
   return  0.5 * ( 1.0 + erf( M_SQRT1_2 * x ) );

}

int main() {

    cout << normalCDF(4.8) << endl;    
    cout << normalCDF(5.4) << endl;
    cout << normalCDF(5.6) << endl;
    cout << normalCDF(5.8) << endl;
    cout << normalCDF(5.1) << endl;
    cout << normalCDF(-37.5) << endl;
    cout << normalCDF(-36.0) << endl;
    cout << normalCDF(-37.6) << endl;
    cout << normalCDF(-37.5) << endl;

    return 0;
    }

这是使用 gcc 6.3.0 在 linux 中编译时的输出

0.999999                                                                                                                
1                                                                                                                       
1                                                                                                                       
1                                                                                                                       
1                                                                                                                       
0                                                                                                                       
0                                                                                                                       
0                                                                                                                       
0 

我想使用 NativeCall 从 raku 调用相同的代码,所以我修改了代码

test.cpp

extern "C" double normalCDF( double x )
{
   return  0.5 * ( 1.0 + erf( M_SQRT1_2 * x ) );

}

创建了动态共享的.so库,并将nativecall代码编写为:

use NativeCall;

sub normalCDF(num64) returns num64 is native('libtest.so') { * };


say normalCDF((4.8).Num);
say normalCDF((5.4).Num);
say normalCDF((5.6).Num);
say normalCDF((5.8).Num);
say normalCDF((5.1).Num);
say normalCDF((-37.5).Num);
say normalCDF((-36.0).Num);
say normalCDF((-37.6).Num);
say normalCDF((-37.5).Num);

输出是:

0.999999206671848
0.9999999666795515
0.9999999892824097
0.9999999966842541
0.9999998301732593
0
0
0
0

为什么相同算法的输出不同,尽管数据容器按推荐使用。

系统信息:

  • Ubuntu 18.04 64bit 和 gcc 6.3.0
  • Rakudo 是 2019.07.1 版本。

【问题讨论】:

  • 您没有在 C++ 代码中以全精度打印浮点数,see here

标签: c++ math raku nativecall


【解决方案1】:

您需要以更高的精度打印浮点数。以下将为您提供最大精度:

#include <limits>
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;

double normalCDF( double x )
{
   return  0.5 * ( 1.0 + erf( M_SQRT1_2 * x ) );

}

int main() {

    typedef std::numeric_limits< double > dmax;
    cout.precision(dmax::max_digits10);

    cout << normalCDF(4.8) << endl;    
    cout << normalCDF(5.4) << endl;
    cout << normalCDF(5.6) << endl;
    cout << normalCDF(5.8) << endl;
    cout << normalCDF(5.1) << endl;
    cout << normalCDF(-37.5) << endl;
    cout << normalCDF(-36.0) << endl;
    cout << normalCDF(-37.6) << endl;
    cout << normalCDF(-37.5) << endl;

    return 0;
    }

请注意#include &lt;limits&gt;main 中的前两行,尽管第2 行很重要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-20
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    • 2012-06-29
    • 2015-06-04
    相关资源
    最近更新 更多