3#ifndef DUNE_QUADMATH_HH
4#define DUNE_QUADMATH_HH
36 using float128_t = __float128;
41 float128_t value_ = 0.0q;
44 constexpr Float128() =
default;
45 constexpr Float128(
const float128_t& value) noexcept
52 constexpr Float128(
const T& value) noexcept
57 explicit Float128(
const char* str) noexcept
58 : value_(strtoflt128(str, NULL))
62 constexpr operator float128_t() const noexcept {
return value_; }
64 constexpr float128_t
const& value() const noexcept {
return value_; }
65 constexpr float128_t& value() noexcept {
return value_; }
68 template<
class CharT,
class Traits>
75 x.value() = strtoflt128(buf.c_str(), NULL);
79 template<
class CharT,
class Traits>
87 ((out.
flags() | std::ios_base::scientific) ?
"e" :
"f");
88 const int numChars = quadmath_snprintf(buf, bufSize,
format.c_str(), x.value());
97 constexpr Float128& operator++() noexcept { ++value_;
return *
this; }
98 constexpr Float128& operator--() noexcept { --value_;
return *
this; }
100 constexpr Float128 operator++(
int)
noexcept { Float128 tmp{*
this}; ++value_;
return tmp; }
101 constexpr Float128 operator--(
int)
noexcept { Float128 tmp{*
this}; --value_;
return tmp; }
104 constexpr Float128
operator+() const noexcept {
return Float128{+value_}; }
105 constexpr Float128
operator-() const noexcept {
return Float128{-value_}; }
108#define DUNE_ASSIGN_OP(OP) \
109 constexpr Float128& operator OP(const Float128& u) noexcept \
111 value_ OP float128_t(u); \
114 static_assert(true, "Require semicolon to unconfuse editors")
129#define DUNE_BINARY_OP(OP) \
130 constexpr Float128 operator OP(const Float128& t, \
131 const Float128& u) noexcept \
133 return Float128{float128_t(t) OP float128_t(u)}; \
135 constexpr Float128 operator OP(const float128_t& t, \
136 const Float128& u) noexcept \
138 return Float128{t OP float128_t(u)}; \
140 constexpr Float128 operator OP(const Float128& t, \
141 const float128_t& u) noexcept \
143 return Float128{float128_t(t) OP u}; \
146 std::enable_if_t<std::is_arithmetic<T>::value, int> = 0> \
147 constexpr Float128 operator OP(const T& t, \
148 const Float128& u) noexcept \
150 return Float128{float128_t(t) OP float128_t(u)}; \
153 std::enable_if_t<std::is_arithmetic<U>::value, int> = 0> \
154 constexpr Float128 operator OP(const Float128& t, \
155 const U& u) noexcept \
157 return Float128{float128_t(t) OP float128_t(u)}; \
159 static_assert(true, "Require semicolon to unconfuse editors")
171#define DUNE_BINARY_BOOL_OP(OP) \
172 constexpr bool operator OP(const Float128& t, \
173 const Float128& u) noexcept \
175 return float128_t(t) OP float128_t(u); \
178 std::enable_if_t<std::is_arithmetic<T>::value, int> = 0> \
179 constexpr bool operator OP(const T& t, \
180 const Float128& u) noexcept \
182 return float128_t(t) OP float128_t(u); \
185 std::enable_if_t<std::is_arithmetic<U>::value, int> = 0> \
186 constexpr bool operator OP(const Float128& t, \
187 const U& u) noexcept \
189 return float128_t(t) OP float128_t(u); \
191 static_assert(true, "Require semicolon to unconfuse editors")
193 DUNE_BINARY_BOOL_OP(==);
194 DUNE_BINARY_BOOL_OP(!=);
195 DUNE_BINARY_BOOL_OP(<);
196 DUNE_BINARY_BOOL_OP(>);
197 DUNE_BINARY_BOOL_OP(<=);
198 DUNE_BINARY_BOOL_OP(>=);
200#undef DUNE_BINARY_BOOL_OP
205#define DUNE_UNARY_FUNC(name,func) \
206 inline Float128 name(const Float128& u) noexcept \
208 return Float128{func (float128_t(u))}; \
210 static_assert(true, "Require semicolon to unconfuse editors")
213#define DUNE_CUSTOM_UNARY_FUNC(type,name,func) \
214 inline type name(const Float128& u) noexcept \
216 return (type)(func (float128_t(u))); \
218 static_assert(true, "Require semicolon to unconfuse editors")
221#define DUNE_BINARY_FUNC(name,func) \
222 inline Float128 name(const Float128& t, \
223 const Float128& u) noexcept \
225 return Float128{func (float128_t(t), float128_t(u))}; \
227 static_assert(true, "Require semicolon to unconfuse editors")
246 DUNE_CUSTOM_UNARY_FUNC(
int, ilogb, ilogbq);
248 DUNE_CUSTOM_UNARY_FUNC(
long long int, llrint, llrintq);
249 DUNE_CUSTOM_UNARY_FUNC(
long long int, llround, llroundq);
255 DUNE_CUSTOM_UNARY_FUNC(
long int, lrint, lrintq);
256 DUNE_CUSTOM_UNARY_FUNC(
long int, lround, lroundq);
258 DUNE_BINARY_FUNC(nextafter, nextafterq);
259 DUNE_BINARY_FUNC(pow, powq);
270 DUNE_CUSTOM_UNARY_FUNC(
bool, isfinite, finiteq);
271 DUNE_CUSTOM_UNARY_FUNC(
bool, isinf, isinfq);
272 DUNE_CUSTOM_UNARY_FUNC(
bool, isnan, isnanq);
273 DUNE_CUSTOM_UNARY_FUNC(
bool, signbit, signbitq);
275#undef DUNE_UNARY_FUNC
276#undef DUNE_CUSTOM_UNARY_FUNC
277#undef DUNE_BINARY_FUNC
281#define DUNE_BINARY_ARITHMETIC_FUNC(name,func) \
282 inline Float128 name(const Float128& t, \
283 const Float128& u) noexcept \
285 return Float128{func (float128_t(t), float128_t(u))}; \
288 std::enable_if_t<std::is_arithmetic<T>::value, int> = 0> \
289 inline Float128 name(const T& t, \
290 const Float128& u) noexcept \
292 return Float128{func (float128_t(t), float128_t(u))}; \
295 std::enable_if_t<std::is_arithmetic<U>::value, int> = 0> \
296 inline Float128 name(const Float128& t, \
297 const U& u) noexcept \
299 return Float128{func (float128_t(t), float128_t(u))}; \
301 static_assert(true, "Require semicolon to unconfuse editors")
303 DUNE_BINARY_ARITHMETIC_FUNC(atan2,atan2q);
304 DUNE_BINARY_ARITHMETIC_FUNC(copysign,copysignq);
305 DUNE_BINARY_ARITHMETIC_FUNC(fdim,fdimq);
306 DUNE_BINARY_ARITHMETIC_FUNC(fmax,fmaxq);
307 DUNE_BINARY_ARITHMETIC_FUNC(fmin,fminq);
308 DUNE_BINARY_ARITHMETIC_FUNC(fmod,fmodq);
309 DUNE_BINARY_ARITHMETIC_FUNC(hypot,hypotq);
310 DUNE_BINARY_ARITHMETIC_FUNC(remainder,remainderq);
312#undef DUNE_BINARY_ARITHMETIC_FUNC
316 inline Float128
fma(
const Float128& t,
const Float128& u,
const Float128& v)
318 return Float128{fmaq(float128_t(t),float128_t(u),float128_t(v))};
321 inline Float128
frexp(
const Float128& u,
int* p)
323 return Float128{frexpq(float128_t(u), p)};
326 inline Float128
ldexp(
const Float128& u,
int p)
328 return Float128{ldexpq(float128_t(u), p)};
331 inline Float128
remquo(
const Float128& t,
const Float128& u,
int* quo)
333 return Float128{remquoq(float128_t(t), float128_t(u), quo)};
336 inline Float128
scalbln(
const Float128& u,
long int e)
338 return Float128{scalblnq(float128_t(u), e)};
341 inline Float128
scalbn(
const Float128& u,
int e)
343 return Float128{scalbnq(float128_t(u), e)};
355 inline Float128
pow(
const Float128& x,
const Int p)
357 static const Float128
max_value = FLT128_MAX;
358 static const Float128
min_value = FLT128_MIN;
359 static const Float128 inf_value = float128_t{1} / float128_t{0};
361 const bool isneg = (x < 0);
362 const bool isnan = (x != x);
365 if (isnan) {
return x; }
366 if (isinf) {
return Float128{nanq(
"")}; }
368 const Float128 abs_x = (isneg ? -x : x);
371 return (isneg ? -inf_value : +inf_value);
373 return Float128(1) /
pow(x, Int(-p));
376 if (p == Int(0)) {
return Float128(1); }
377 if (p == Int(1)) {
return x; }
379 return (isneg ? -inf_value : +inf_value);
381 if (p == Int(2)) {
return (x * x); }
382 if (p == Int(3)) {
return ((x * x) * x); }
383 if (p == Int(4)) {
const Float128 x2 = (x * x);
return (x2 * x2); }
385 Float128 result = ((p % Int(2)) != Int(0)) ? x : Float128(1);
389 while (Int(p2 /= 2) != Int(0)) {
392 const bool has_binary_power = (Int(p2 % Int(2)) != Int(0));
393 if (has_binary_power)
404 struct IsNumber<Impl::Float128>
411#ifndef NO_STD_NUMERIC_LIMITS_SPECIALIZATION
413 class numeric_limits<
Dune::Impl::Float128>
415 using Float128 = Dune::Impl::Float128;
416 using float128_t = Dune::Impl::float128_t;
419 static constexpr bool is_specialized =
true;
420 static constexpr Float128
min() noexcept {
return FLT128_MIN; }
421 static constexpr Float128
max() noexcept {
return FLT128_MAX; }
422 static constexpr Float128
lowest() noexcept {
return -FLT128_MAX; }
423 static constexpr int digits = FLT128_MANT_DIG;
424 static constexpr int digits10 = 34;
425 static constexpr int max_digits10 = 36;
426 static constexpr bool is_signed =
true;
427 static constexpr bool is_integer =
false;
428 static constexpr bool is_exact =
false;
429 static constexpr int radix = 2;
430 static constexpr Float128
epsilon() noexcept {
return FLT128_EPSILON; }
431 static constexpr Float128
round_error() noexcept {
return float128_t{0.5}; }
432 static constexpr int min_exponent = FLT128_MIN_EXP;
433 static constexpr int min_exponent10 = FLT128_MIN_10_EXP;
434 static constexpr int max_exponent = FLT128_MAX_EXP;
435 static constexpr int max_exponent10 = FLT128_MAX_10_EXP;
436 static constexpr bool has_infinity =
true;
437 static constexpr bool has_quiet_NaN =
true;
438 static constexpr bool has_signaling_NaN =
false;
439 static constexpr float_denorm_style has_denorm = denorm_present;
440 static constexpr bool has_denorm_loss =
false;
441 static constexpr Float128
infinity() noexcept {
return float128_t{1}/float128_t{0}; }
442 static Float128
quiet_NaN() noexcept {
return nanq(
""); }
443 static constexpr Float128
signaling_NaN() noexcept {
return float128_t{}; }
444 static constexpr Float128
denorm_min() noexcept {
return FLT128_DENORM_MIN; }
445 static constexpr bool is_iec559 =
true;
446 static constexpr bool is_bounded =
false;
447 static constexpr bool is_modulo =
false;
448 static constexpr bool traps =
false;
449 static constexpr bool tinyness_before =
false;
450 static constexpr float_round_style round_style = round_to_nearest;
#define DUNE_BINARY_OP(OP)
Definition debugalign.hh:235
#define DUNE_UNARY_FUNC(name)
#define DUNE_ASSIGN_OP(OP)
Definition debugalign.hh:194
A few common exception classes.
Traits for type conversions and type information.
Stream & operator>>(Stream &stream, std::tuple< Ts... > &t)
Read a std::tuple.
Definition streamoperators.hh:41
std::ostream & operator<<(std::ostream &s, const bigunsignedint< k > &x)
Definition bigunsignedint.hh:273
bigunsignedint< k > operator-(const bigunsignedint< k > &x, std::uintmax_t y)
Definition bigunsignedint.hh:537
bigunsignedint< k > operator+(const bigunsignedint< k > &x, std::uintmax_t y)
Definition bigunsignedint.hh:530
#define DUNE_THROW(E, m)
Definition exceptions.hh:216
Dune namespace.
Definition alignedallocator.hh:11
T max_value(const AlignedNumber< T, align > &val)
Definition debugalign.hh:468
T min_value(const AlignedNumber< T, align > &val)
Definition debugalign.hh:474
Default exception class for range errors.
Definition exceptions.hh:252
T signaling_NaN(T... args)