11

我写了一个Raku脚本来调用标准库erf中的函数:C

use NativeCall;
sub erf(num64) returns num64 is native { * };

say [0.5,1,2,3,4,-0.9].map: {erf($_.Num)};

此脚本的输出

(0.5204998778130465 0.8427007929497149 0.9953222650189527 0.9999779095030014 0.9999999845827421 -0.7969082124228322)

与除 之外C的所有值的输出匹配。[0.5,1,2,3,4,-0.9]4

对于输出while给出. 4_C1.000000Raku0.9999999845827421

要测试 in 的输出4,请C运行以下代码:

#include <stdio.h> // Including header file for printf function
#include <math.h>  // Including header file for erf function

int main (){

  double param, result;
  param = 4.0;
  result = erf(param);
  printf("erf (%f) = %f\n", param, result);
  return 0;
}

知道发生了什么吗?我也需要1.0从 Raku 输出。

4

3 回答 3

8

对于 C 代码,更改%f%.99g以显示更多位数。这显示erf(4)返回 0.9999999845827420852373279558378271758556365966796875。

%f要求小数点后六位。该值被四舍五入以适应该格式。请求小数点后的数字并始终使用“固定”格式。请求有效数字并使用“通用”格式,在适当的时候切换到指数符号。%.numberfnumber%.numbergnumber

对于 Raku 代码,如果要输出“1.0”或“1.000000”,则需要对输出应用一些格式化请求。我不练习 Raku,但简短的搜索显示 Raku 具有printf您可以使用的类似功能,因此请求%f使用它的格式应该复制 C 输出。

于 2022-02-04T12:56:09.730 回答
7

另一个基于@Eric 关于精度的解释的版本:

my $fmt = '%.6f';
printf [$fmt ~ ' '] x 5 ~ $fmt ~ "\n", [0.5,1,2,3,4,-0.9].map: {erf($_.Num)};

[$fmt ~ ' '] x 5 ~ $fmt ~ "\n"构建格式字符串"%.6f %.6f %.6f %.6f %.6f %.6f\n"

输出

0.520500 0.842701 0.995322 0.999978 1.000000 -0.796908

甚至更多raiph提出,使用中运算符xx

printf "{'%.6f' xx 6} \n", [0.5,1,2,3,4,-0.9].map: {erf($_.Num)};
于 2022-02-04T13:16:03.927 回答
6

您正在将苹果与橙子进行比较。

use NativeCall;
sub erf(num64) returns num64 is native { * };

say .fmt("%f") for [0.5,1,2,3,4,-0.9].map: {erf($_.Num)}

0.520500
0.842701
0.995322
0.999978
1.000000
-0.796908

printf在 C 中使用,如果你使用.fmt(在 Raku 中更简单的说法sprintf),那么你也会得到1.0.

于 2022-02-04T13:07:23.157 回答