How to use BigFloats with ccall?

I want to call a C library that uses MPFR in my Julia code. The issue is, I can’t make it work: if I manipulate a BigFloat declared in Julia within the C code, it becomes NaN. Here is an example:

#include <gmp.h>
#include <mpfr.h>

void add_val(mpfr_t a)
{
  mpfr_t tmp;
  mpfr_init2(tmp, 42);
  mpfr_add(a, a, tmp, MPFR_RNDD);
}

which I compile with

gcc -O2 -fPIC -Wno-unused-result -c file.c -o file.o
gcc -O2 -fPIC -Wno-unused-result -shared file.o -o lib.so -lmpfr -lgmp

and call in:

using Libdl

lib = Libdl.dlopen("./lib.so")
symb = Libdl.dlsym(lib, :add_val)

a = BigFloat(2.)
ccall(symb, Cvoid, (Ref{BigFloat},), a)

After this snippet of code, a is NaN. Is there something I am doing wrong?
(I am a very new user of MPFR, and don’t know it very well)

I don’t see an obvious problem with your code — that’s how base/mpfr.jl does it.

mpfr_init2(tmp, 42) initializes a mpfr number with 42bits precision, and sets its value to NaN.
You need to assign a value to it first, e.g. set it to 10 with

mpfr_set_si(tmp, 10, MPFR_RNDN)
4 Likes

This worked, thanks! So the problem was a lack of doc reading for me.

1 Like

I don’t know, and you seem to have an answer already, I just wanted to propose look into ArbNumerics.jl It’s ArbFloat type is faster then Julia’s BigFloat/MPFR.

At least for many things and not just because the default is 106 bits, also faster at any precision, e.g. Julia’s default 256 bits. Why I found it intriguing that you chose 42 bits. Why do different libraries choose their defaults, e.g. Julia 256, and why you 42?

Note, you could use the underlying C library of ArbNumerics.jl if you need to.

Also if you’re calling to C, from Julia, does it make sense to send down the Julia type or get Julia types back?

I would like to know why you prefer MPFR, since I’ve suggested it be dropped from Julia.

Thanks for the suggestion! I am however limited, as the library I want to use only supports MPFR, therefore I need to do this with BigFloats. The 42 bits precision was completely arbitrary, and since I’m new to all of this I can’t tell why certain people make certain choices…

I’m not sure I understood this part… From what I understand, mpfr_t corresponds exactly to Ref{BigFloat}, so I don’t see the problem.