【问题标题】:Incorporate C library function into Perl6 with NativeCall使用 NativeCall 将 C 库函数合并到 Perl6
【发布时间】:2018-12-27 03:56:39
【问题描述】:

我正在尝试在 Perl6 中使用 C 的 math.h 中的 lgamma

如何将其合并到 Perl6 中?

我试过了

use NativeCall;

sub lgamma(num64 --> num64) is native(Str) {};

say lgamma(3e0);

my $x = 3.14;
say lgamma($x);

这适用于第一个数字(Str),但对于第二个数字 $x 则失败,并给出错误:

This type cannot unbox to a native number: P6opaque, Rat
  in block <unit> at pvalue.p6 line 8

我想非常简单地做到这一点,比如在 Perl5 中:use POSIX 'lgamma';,然后是 lgamma($x),但我不知道如何在 Perl6 中做到这一点。

【问题讨论】:

  • 你能把整个错误贴出来吗?
  • @jjmerelo 我已更新帖子以更完整地显示错误
  • 在声明$x时尝试使用num64原生类型:my num64 $x = 3.14.Num。如果没有 num64 声明符,它似乎也可以工作:my $x = 3.14.Num
  • 你也可以使用3.14e0创建一个Num字面量
  • 我想is native(Str) 不会像你认为的那样做。 (它也没有像我认为的那样做,因为我对它的作用没有任何想法,除了它对我没有意义。:))我怀疑它变成了 is native('') 的等价物我想反过来与is native 相同。有关详细信息,请参阅the is native doc。同样,“这适用于第一个数字(Str)”也不正确,因为第一个数字(3e0)不是字符串/Str,而是Num

标签: raku nativecall


【解决方案1】:

本机值的错误并不总是很清楚。

基本上是说 Rat 不是 Num。

3.14 是一只老鼠。 (理性)

say 3.14.^name; # Rat
say 3.14.nude.join('/'); # 157/50

每次调用 Num 时,您都可以将其强制转换为 Num。

lgamma( $x.Num )

这似乎不太好。


我只会将本机子组件包装在另一个将所有实数强制为 Num 的子组件中。
(实数除复数外都是数字)

sub lgamma ( Num(Real) \n --> Num ){
  use NativeCall;
  sub lgamma (num64 --> num64) is native {}

  lgamma( n )
}

say lgamma(3);    # 0.6931471805599453
say lgamma(3.14); # 0.8261387047770286

【讨论】:

  • “\n”是什么意思?我以前见过,但找不到它的意思
  • @con 这是你声明一个没有印记的“变量”的方式 ($@%)。在签名中,它有点像将其声明为 raw :( \n ) :( $n is raw )。我主要在这里使用它,因为代码很短,并且不需要使用$ 声明它所提供的保护。
【解决方案2】:

您的$x 没有类型。如果你使用任何类型,比如num64,它会说:

Cannot assign a literal of type Rat (3.14) to a native variable of type num. You can declare the variable to be of type Real, or try to coerce the value with 3.14.Num or Num(3.14)

所以你就是这样做的:

my  num64 $x = 3.14.Num;

这会将数字完全转换为lgamma 所需的表示形式

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-31
    相关资源
    最近更新 更多