Incorporate C library function into Perl6 with NativeCall

为君一笑 提交于 2019-12-23 19:29:45

问题


I am attempting to use lgamma from C's math.h in Perl6.

How can I incorporate this into Perl6?

I have tried

use NativeCall;

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

say lgamma(3e0);

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

This works for the first number (a Str) but fails for the second, $x, giving the error:

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

I want to do this very simply, like in Perl5: use POSIX 'lgamma'; and then lgamma($x) but I don't see how to do that in Perl6.


回答1:


The errors with native values isn't always clear.

Basically it is saying that a Rat isn't a Num.

3.14 is a Rat. (Rational)

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

You could just always coerce the value to Num everytime you call it.

lgamma( $x.Num )

That doesn't seem so great.


I would just wrap the native sub in another one that coerces all Real numbers to Num.
(Real is all Numeric except Complex)

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



回答2:


Your $x has no type. If you use any type for it, say num64, it will say:

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)

So you do exactly that:

my  num64 $x = 3.14.Num;

This converts the number exactly to the representation that is required by lgamma



来源:https://stackoverflow.com/questions/53939570/incorporate-c-library-function-into-perl6-with-nativecall

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!