Mapping long double in C to Raku

179 views Asked by At

Say I have a C function

long double foo(long double *array, size_t n) {

// do something

}

How to call this function from Raku?

In rakudo specific types, there is mention of

Raku C type
long long in C
longlong longlong in C
ulong long and unsigned in C
ulonglong longlong and unsigned in C
size_t size_t and unsigned in C
ssize_t size_t in C
bool bool in C

So I thought if long double can be mapped as long num64, which was not the case.

1

There are 1 answers

1
librasteve On

The raku design docs (synopsis 09) call for a num128 type. Afaict this is not yet implemented in rakudo.

The implication is:

  1. raku can only handle num64 (double in C)
  2. you may need to write a C stub to coerce to from long double

Edit: per the comment, here is a worked example of how to write a stub that coerces double to/from long double (for ubuntu):

First write your stub file and put in eg. sqrt_double.c:

#include <math.h>

double sqrt_double(double num) {
    long double num_ld = (long double)num; // Coerce to long double
    long double result_ld = sqrtl(num_ld);  // Calculate square root
    return (double)result_ld;              // Coerce back to double
}

Then compile it to a SO:

gcc -shared -o libsqrt_double.so -fPIC sqrt_double.c -lm

It will appear in a file like 'libsqrt_double.so'

Then write your raku with Nativecall:

use NativeCall;

# Define the C library as a Raku module
sub sqrt_double(num64) returns num64 is native('./sqrt_double') {*} 

# Declare a Raku sub to call the C function
sub c_sqrt($value) {
    sqrt_double($value.Num).Num
}

# Call the Raku sub with a double value
my $res = c_sqrt(3.14);

say $res ** 2;    #3.1399999999999997

Note that the is native trait will automatically generate the .so filename according to the rules of your OS.