Opened 6 years ago
Closed 6 years ago
#12234 closed Bugs (fixed)
boost::multiprecision x64 win32 hard compile errors on windows with mpir
Reported by: | Owned by: | John Maddock | |
---|---|---|---|
Milestone: | Boost 1.62.0 | Component: | multiprecision |
Version: | Boost 1.61.0 | Severity: | Showstopper |
Keywords: | mpir x64 | Cc: |
Description
I get a hard compile error in trying to get boost multprecision floating point examples working with mpir on windows x64.
The crux of the error is that some of the boost code uses functions whose signatures are long* but the code is used with arguments of type mpir_ui* etc.and of course this is a nasty for pointers!
1>C:\Program Files\boost\boost_1_61_0\boost/multiprecision/gmp.hpp(982): error C2664: 'double __gmpf_get_d_2exp(mpir_si *,mpf_srcptr)': cannot convert argument 1 from 'long *' to 'mpir_si *' 1> C:\Program Files\boost\boost_1_61_0\boost/multiprecision/gmp.hpp(982): note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
One workaround that "works" is to define double gmpf_get_d_2exp(long * p, mpf_srcptr a) :
#include "stdafx.h" #include <boost/multiprecision/gmp.hpp> #include <boost/math/special_functions/gamma.hpp> #include "Safeint3.hpp" #include <iostream> namespace boost { namespace multiprecision { template <unsigned Digits10> struct gmp_float; typedef number<gmp_float<50> > mpf_float_50; typedef number<gmp_float<100> > mpf_float_100; typedef number<gmp_float<500> > mpf_float_500; typedef number<gmp_float<1000> > mpf_float_1000; typedef number<gmp_float<0> > mpf_float; } } // namespaces //FIX - define a wrapper double __gmpf_get_d_2exp(long * p, mpf_srcptr a) { mpir_si temp{ *p }; double b = __gmpf_get_d_2exp(&temp, a); *p = SafeInt<long>(temp); return b; }
But is this the answer? I find it difficult to get the sense of gmp.hpp well enough to figure out whether or not it knows when it can narrow a variable and when it cannot.
Clearly is intended to cope with the 64 32 divide on long; however I am puzzled by code like:
inline void eval_convert_to(long* result, const gmp_rational& val) { double r; eval_convert_to(&r, val); *result = static_cast<long>(r); } inline void eval_convert_to(unsigned long* result, const gmp_rational& val) { double r; eval_convert_to(&r, val); *result = static_cast<long>(r); }
Which to my amateur eye does not seem to be nice.
Suggestions welcome - mpir is the current version and working nicely; boost is 1.61.0 and working nicely.
I would really like to get them working together.
Environment - VS 2015-2008, Intel 16.0, windows 7.
Terry
Change History (4)
comment:1 by , 6 years ago
comment:2 by , 6 years ago
I need to check with latest MPIR, but my version has no such type as mpir_si, further the function call that's causing the issue (mpf_get_d_2exp) is documented as:
double mpf_get_d_2exp (signed long int *exp, const mpf_t op)
In the latest GMP documentation. Is this an incompatibility between GMP and MPIR by any chance?
comment:3 by , 6 years ago
I believe this to be an MPIR bug: https://github.com/wbhart/mpir/commit/fb616eed78d0a32dc9e53b355b0c2d42c1209907#commitcomment-17775327
Will commit a workaround shortly.
comment:4 by , 6 years ago
Milestone: | To Be Determined → Boost 1.62.0 |
---|---|
Resolution: | → fixed |
Status: | new → closed |
I should have given the code example that triggered the problem. Uncomment the relevant part and it runs successfully: