问题
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