4

I installed gmp and mpfr on my environment. Now I can successfully

#include <gmpxx.h>
#include <mpfr.h>
#include <mpf2mpfr.h>

Now, say that I initialize an mpf_class with some value:

mpf_class x = 0.73;

How can I use mpfr to get the sin of this number? I just need an mpf_class in, an mpf_class out. Something like:

mpf_class y = sin(x)

Which obviously doesn't work. I noticed that there is a mpfr_sin function, which I called like this:

mpfr_sin(x, y, MPFR_RNDN);

But that didn't work as well. So what am I supposed to do? Am I doing something wrong?

Thank you

Matteo Monti
  • 8,362
  • 19
  • 68
  • 114
  • Use `x.get_mpf_t()`? Shouldn't the order of the headers be reversed? – Marc Glisse Nov 14 '14 at 22:46
  • I tried `mpfr_sin(y.get_mpf_t(), x.get_mpf_t(), MPFR_RNDN);` and it just fails with the error `no matching function call for mpfr_sin`. Am I doing something wrong..? – Matteo Monti Nov 15 '14 at 00:57

1 Answers1

3

mpf2mpfr.h is probably not what you want. It contains plenty of #define to replace mpf names with mpfr names in everything that follows. If you wanted a chance of having it work in your case, you would have to include mpf2mpfr.h before gmpxx.h. However, the file does not translate everything. The following lets it compile in C++03 (as long as you don't convert to mpq_class):

#include <mpfr.h>
#include <mpf2mpfr.h>
void mpfr_get_q (mpq_ptr, mpfr_srcptr);
#undef mpq_set_f
#define mpq_set_f(x,y) mpfr_get_q(x,y)
#include <gmpxx.h>

int main(){
  mpf_class x=.73;
  mpf_class y;
  mpfr_sin(y.get_mpf_t(),x.get_mpf_t(),MPFR_RNDN);
} 

but trying to print with operator<< will print a pointer instead of the number, for instance. Extra functions provided in C++11 would require more tweaking, it is easier to disable them: #define __GMPXX_USE_CXX11 0 before including gmpxx.h.

There are mostly two ways to solve this and both start with removing mpf2mpfr.h. The first one is to create a temporary mpfr_t:

mpf_class x=.73;
mpf_class y;
mpfr_t xx;
mpfr_t yy;
mpfr_init_set_f(xx, x.get_mpf_t(), MPFR_RNDN);
mpfr_init(yy);
mpfr_sin(yy, xx, MPFR_RNDN);
mpfr_get_f(y.get_mpf_t(), yy, MPFR_RNDN);

The second one is to drop mpf completely and use only mpfr. Its webpage lists 6 C++ wrappers for it, several of which are still maintained.

Marc Glisse
  • 7,550
  • 2
  • 30
  • 53
  • Actually, I tried running the first piece of code (just copy & paste) and it yields some strange error: gmpxx.h, at line 1904: no member named _mp_size in __mpfr_struct. What does that mean? Thank you very much! – Matteo Monti Nov 18 '14 at 13:04
  • I updated my answer, but basically it is yet another sign that mpf2mpfr.h is a bad idea here. – Marc Glisse Nov 18 '14 at 13:30
  • mpf2mpfr.h was improved a bit since then, so the workaround around mpq_set_f is not needed anymore. – Marc Glisse Jul 02 '22 at 08:41