|
@@ -3,6 +3,7 @@
|
|
|
|
|
|
#include <cinttypes>
|
|
#include <cinttypes>
|
|
#include <cmath>
|
|
#include <cmath>
|
|
|
|
+#include <string>
|
|
#include "Fixed.h"
|
|
#include "Fixed.h"
|
|
|
|
|
|
#ifdef WITH_BOOST
|
|
#ifdef WITH_BOOST
|
|
@@ -13,20 +14,24 @@
|
|
# include <boost/multiprecision/cpp_int.hpp>
|
|
# include <boost/multiprecision/cpp_int.hpp>
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+#ifdef WITH_QD
|
|
|
|
+# include <qd/dd_real.h>
|
|
|
|
+#endif
|
|
|
|
+
|
|
namespace mnd
|
|
namespace mnd
|
|
{
|
|
{
|
|
|
|
|
|
|
|
|
|
#ifdef WITH_BOOST
|
|
#ifdef WITH_BOOST
|
|
-#if 0//defined(__GNUC__) || defined(__INTEL_COMPILER)
|
|
|
|
|
|
+# if 0//defined(__GNUC__) || defined(__INTEL_COMPILER)
|
|
using Float128 = boost::multiprecision::float128;
|
|
using Float128 = boost::multiprecision::float128;
|
|
-#else
|
|
|
|
|
|
+# else
|
|
//using Float128 = boost::multiprecision::cpp_bin_float_quad;
|
|
//using Float128 = boost::multiprecision::cpp_bin_float_quad;
|
|
using Float128 = boost::multiprecision::number<
|
|
using Float128 = boost::multiprecision::number<
|
|
boost::multiprecision::backends::cpp_bin_float<
|
|
boost::multiprecision::backends::cpp_bin_float<
|
|
112, boost::multiprecision::backends::digit_base_2, void, boost::int16_t, -16382, 16383>,
|
|
112, boost::multiprecision::backends::digit_base_2, void, boost::int16_t, -16382, 16383>,
|
|
boost::multiprecision::et_off>;
|
|
boost::multiprecision::et_off>;
|
|
-#endif
|
|
|
|
|
|
+# endif
|
|
inline Float128 abs(const Float128& x) { return boost::multiprecision::abs(x); }
|
|
inline Float128 abs(const Float128& x) { return boost::multiprecision::abs(x); }
|
|
inline Float128 floor(const Float128& x) { return boost::multiprecision::floor(x); }
|
|
inline Float128 floor(const Float128& x) { return boost::multiprecision::floor(x); }
|
|
inline Float128 log(const Float128& x) { return boost::multiprecision::log(x); }
|
|
inline Float128 log(const Float128& x) { return boost::multiprecision::log(x); }
|
|
@@ -54,6 +59,17 @@ namespace mnd
|
|
using Integer = int64_t;
|
|
using Integer = int64_t;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+
|
|
|
|
+#ifdef WITH_QD
|
|
|
|
+ using DoubleDouble = dd_real;
|
|
|
|
+
|
|
|
|
+ inline DoubleDouble abs(const DoubleDouble& x) { return ::abs(x); }
|
|
|
|
+ inline DoubleDouble floor(const DoubleDouble& x) { return ::floor(x); }
|
|
|
|
+ inline DoubleDouble log(const DoubleDouble& x) { return ::log(x); }
|
|
|
|
+ inline DoubleDouble log2(const DoubleDouble& x) { return ::log(x) / ::log(DoubleDouble(2.0)); }
|
|
|
|
+ inline DoubleDouble pow(const DoubleDouble& x, const DoubleDouble& y) { return ::pow(x, y); }
|
|
|
|
+#endif
|
|
|
|
+
|
|
inline double abs(double x) { return ::abs(x); }
|
|
inline double abs(double x) { return ::abs(x); }
|
|
inline float abs(float x) { return ::abs(x); }
|
|
inline float abs(float x) { return ::abs(x); }
|
|
inline double floor(double x) { return ::floor(x); }
|
|
inline double floor(double x) { return ::floor(x); }
|
|
@@ -64,6 +80,28 @@ namespace mnd
|
|
inline float log2(float x) { return ::log2f(x); }
|
|
inline float log2(float x) { return ::log2f(x); }
|
|
inline double pow(double x, double y) { return ::pow(x, y); }
|
|
inline double pow(double x, double y) { return ::pow(x, y); }
|
|
inline float pow(float x, float y) { return ::powf(x, y); }
|
|
inline float pow(float x, float y) { return ::powf(x, y); }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ template<typename T, typename U>
|
|
|
|
+ T convert(const U& x)
|
|
|
|
+ {
|
|
|
|
+ return static_cast<T>(x);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+#if defined(WITH_BOOST) && defined(WITH_QD)
|
|
|
|
+ template<>
|
|
|
|
+ inline DoubleDouble convert<DoubleDouble, Real>(const Real& x)
|
|
|
|
+ {
|
|
|
|
+ std::string s = x.str();
|
|
|
|
+ return DoubleDouble(s.c_str());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ template<>
|
|
|
|
+ inline float convert<float, DoubleDouble>(const DoubleDouble& x)
|
|
|
|
+ {
|
|
|
|
+ return float(x.x[0] + x.x[1]);
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|