5#ifndef DUNE_COMMON_BIGFLOAT_HH
6#define DUNE_COMMON_BIGFLOAT_HH
24#include <dune/common/quadmath.hh>
34 template<
unsigned int precision >
38 using Base = mpfr::mpreal;
39 using Prec = mp_prec_t;
46 : Base(0, Prec(precision))
53 explicit BigFloat (
const char* str)
54 : Base(str, Prec(precision))
58 BigFloat (
const Base& v) noexcept
63 BigFloat (Base&& v) noexcept
69 std::enable_if_t<std::is_arithmetic_v<T>,
int> = 0>
70 BigFloat (
const T& v) noexcept
71 : Base(v, Prec(precision))
76 BigFloat (
const Dune::Float128& v)
77 : Base([](const
Dune::Float128& v) {
78 std::ostringstream oss; oss << v;
80 }(v), Prec(precision))
84 BigFloat (
const BigFloat&) =
default;
85 BigFloat (BigFloat&&) =
default;
89 std::enable_if_t<std::is_arithmetic_v<T>,
int> = 0>
90 BigFloat& operator= (
const T& v)
noexcept
92 static_cast<Base&
>(*this) = v;
98 BigFloat& operator= (
const Dune::Float128& v)
100 std::ostringstream oss; oss << v;
101 static_cast<Base&
>(*this) = oss.str();
106 BigFloat& operator= (
const BigFloat&) =
default;
107 BigFloat& operator= (BigFloat&&) =
default;
110 template <
unsigned int p1,
unsigned int p2>
111 friend bool operator== (
const BigFloat<p1>& A,
const BigFloat<p2>& B)
113 const Base& a =
static_cast<const Base&
>(A);
114 const Base& b =
static_cast<const Base&
>(B);
119 template <
unsigned int p1,
unsigned int p2>
120 friend std::partial_ordering operator<=> (
const BigFloat<p1>& A,
const BigFloat<p2>& B)
122 const Base& a =
static_cast<const Base&
>(A);
123 const Base& b =
static_cast<const Base&
>(B);
124 if (isnan(a) || isnan(b))
125 return std::partial_ordering::unordered;
127 return std::partial_ordering::less;
129 return std::partial_ordering::greater;
130 return std::partial_ordering::equivalent;
135 std::enable_if_t<std::is_arithmetic_v<T>,
int> = 0>
136 explicit operator T ()
const
138#ifdef MPREAL_HAVE_EXPLICIT_CONVERTERS
139 return T(
static_cast<const Base&
>(*
this));
141 if constexpr(std::is_same_v<T,bool>)
142 return this->toBool();
143 else if constexpr(std::is_same_v<T,long long>)
144 return this->toLLong();
145 else if constexpr(std::is_same_v<T,unsigned long long>)
146 return this->toULLong();
147 else if constexpr(std::is_signed_v<T>)
148 return T(this->toLong());
149 else if constexpr(std::is_unsigned_v<T>)
150 return T(this->toULong());
151 else if constexpr(std::is_same_v<T,float>)
152 return this->toFloat();
153 else if constexpr(std::is_same_v<T,double>)
154 return this->toDouble();
155 else if constexpr(std::is_floating_point_v<T>)
156 return T(this->toLDouble());
166 explicit operator Dune::Float128 ()
const
168 const int n = std::numeric_limits<Dune::Impl::Float128>::max_digits10;
169 return Float128(this->
toString(n,10).c_str());
179 template <
unsigned int precision>
180 struct IsNumber<BigFloat<precision>>
181 :
public std::true_type {};
183 template <
unsigned int precision1,
unsigned int precision2>
184 struct PromotionTraits<BigFloat<precision1>, BigFloat<precision2>>
186 using PromotedType = BigFloat<(precision1 > precision2 ? precision1 : precision2)>;
189 template <
unsigned int precision>
190 struct PromotionTraits<BigFloat<precision>,BigFloat<precision>>
192 using PromotedType = BigFloat<precision>;
195 template <
unsigned int precision,
class T>
196 struct PromotionTraits<BigFloat<precision>, T>
198 using PromotedType = BigFloat<std::max<unsigned int>(8*
sizeof(T), precision)>;
201 template <
class T,
unsigned int precision>
202 struct PromotionTraits<T, BigFloat<precision>>
204 using PromotedType = BigFloat<std::max<unsigned int>(8*
sizeof(T), precision)>;
208 template<
unsigned int precision >
209 struct MathematicalConstants<BigFloat<precision>>
211 using T = BigFloat<precision>;
219 return mpfr::const_pi(mp_prec_t(precision));
227 template <
unsigned int precision>
228 inline void swap (Dune::BigFloat<precision>& x, Dune::BigFloat<precision>& y)
230 return mpfr::swap(x, y);
234 template <
unsigned int precision>
235 class numeric_limits<
Dune::BigFloat<precision>>
236 :
public numeric_limits<mpfr::mpreal>
238 using type = Dune::BigFloat<precision>;
239 using Base = numeric_limits<mpfr::mpreal>;
241 static constexpr int bits2digits (
int prec)
243 constexpr double LOG10_2 = 0.301029995663981195213738894724493;
244 return int(prec * LOG10_2);
248 inline static type
min () {
return mpfr::minval(precision); }
249 inline static type
max () {
return mpfr::maxval(precision); }
250 inline static type lowest () {
return -mpfr::maxval(precision); }
251 inline static type epsilon () {
return mpfr::machine_epsilon(precision); }
252 inline static type round_error () {
return Base::round_error(precision); }
254 static constexpr int digits = int(precision);
255 static constexpr int digits10 = bits2digits(precision);
256 static constexpr int max_digits10 = bits2digits(precision);
267 template<
unsigned int precision >
270 static_assert(AlwaysFalse<BigFloat<precision>>::value,
271 "The BigFloat type requires MPFR to be found and enabled. Use find_package(MPFR) and add_dune_mpfr_flags(target) in CMake to activate this package on your target.");
Provide the macro DUNE_ASSUME(...) that is a portable assume expression as a hint for the compiler/op...
std::string toString(Precision p)
map precision to VTK type name
Definition: common.hh:280
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:489
constexpr auto min
Function object that returns the smaller of the given values.
Definition: hybridutilities.hh:511
constexpr EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:238
Some useful basic math stuff.
Dune namespace
Definition: alignedallocator.hh:13
static const Field e()
Euler's number.
Definition: math.hh:38
static const Field pi()
Archimedes' constant.
Definition: math.hh:48
Traits for type conversions and type information.