我想写的是numpy
的linspace
函数.
由于循环在编译代码中速度更快,我try 在c
中编写并从Raku调用.
// C code
#include <stdio.h>
#ifdef _WIN32
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT extern // if c++ code, requires extern "C"
#endif
DLLEXPORT void c_linspace(double start, double step, int num, double* vals) {
for (int i = 0; i < num; i++)
{
vals[i] = start;
start += step;
}
}
// Raku code
sub c_linspace(num64, num64, int32, CArray[num64])
is native( MYDYN) { * };
sub raku_linspace($start, $end, $num, :$endpoint = True, :$retstep = False) {
my $step = $endpoint ?? ($end - $start)/($num - 1) !! ($end-$start)/($num);
my $vals = CArray[num64].allocate($num);
c_linspace($start.Num, $step.Num, $num.Int, $vals);
$retstep ?? ($vals.list, $step) !! $vals.list
}
工作正常.但判断结果的精确度,例如:
Raku给
say raku_linspace(1,3,300000)[200] # gives 1.0013333377777869
而numpy
给了
import numpy as np
arr = np.linspace(1,3,300000)[200]
print(arr) # gives 1.0013333377777927
为什么在精确度上会有这样的差异?我的期望是double
应该保持15位小数的精确度.
文档https://docs.raku.org/language/nativetypes提到的double
被映射到num64
.
还提到了Rakudo特定的类型https://docs.raku.org/language/nativetypes,其中提到了long
和longlong
.那么long double
在乐库映射到了什么地方呢?它似乎不是num64
.
System information: Windows 10 64位 GCC 13.2.0
Edit:
看起来问题直接出现在c
中,原因是浮点错误,而不是通过本机调用.因为运行C得到了Raku所提供的东西.
然而,在本地是否有机制来处理long double
或long long
,最好是举个例子?
也是what could be done,以使此函数具有与numpy
相同的精度.任何指向我可以阅读和try 的文档的指针.