3.2-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
quad.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*****************************************************************************
4 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
25#if !defined DUMUX_QUAD_HH && HAVE_QUAD
26#define DUMUX_QUAD_HH
27
28#include <iostream>
29#include <cmath>
30#include <limits>
31
32extern "C" {
33#include <quadmath.h>
34}
35
36#include <dune/common/typetraits.hh>
37
38namespace Dumux {
39
40using Quad = __float128;
41
42} // namespace Dumux
43
44// Dune's desired way of enabling their algebraic operations for
45// extended-precision data types, see dune/common/typetraits.hh.
46namespace Dune {
47
48template <>
49struct IsNumber<Dumux::Quad> : std::true_type {};
50
51} // namespace Dune
52
53namespace std {
54
55// provide the numeric limits for the quad precision type
56template <>
57class numeric_limits<Dumux::Quad>
58{
59public:
60 static constexpr bool is_specialized = true;
61
62 static constexpr Dumux::Quad min() noexcept
63 { return FLT128_MIN; }
64 static constexpr Dumux::Quad max() noexcept
65 { return FLT128_MAX; }
66 static constexpr Dumux::Quad lowest() noexcept
67 { return -FLT128_MAX; }
68
69 // number of bits in mantissa
70 static constexpr int digits = FLT128_MANT_DIG;
71 // number of decimal digits
72 static constexpr int digits10 = FLT128_DIG;
73 static constexpr int max_digits10 = FLT128_MANT_DIG;
74
75 static constexpr bool is_signed = true;
76 static constexpr bool is_integer = false;
77 static constexpr bool is_exact = false;
78 static constexpr int radix = 0;
79 static constexpr Dumux::Quad epsilon() noexcept
80 { return FLT128_EPSILON; }
81 static constexpr Dumux::Quad round_error() noexcept
82 { return 0.5; }
83
84 static constexpr int min_exponent = FLT128_MIN_EXP;
85 static constexpr int min_exponent10 = FLT128_MIN_10_EXP;
86 static constexpr int max_exponent = FLT128_MAX_EXP;
87 static constexpr int max_exponent10 = FLT128_MAX_10_EXP;
88
89 static constexpr bool has_infinity = true;
90 static constexpr bool has_quiet_NaN = true;
91 static constexpr bool has_signaling_NaN = true;
92 static constexpr float_denorm_style has_denorm = denorm_present;
93 static constexpr bool has_denorm_loss = false;
94 static constexpr Dumux::Quad infinity() noexcept
95 { return __builtin_huge_valq(); };
96 static constexpr Dumux::Quad quiet_NaN() noexcept
97 { return __builtin_nan(""); }
98 static constexpr Dumux::Quad signaling_NaN() noexcept
99 { return __builtin_nans(""); }
100 static constexpr Dumux::Quad denorm_min() noexcept
101 { return FLT128_DENORM_MIN; }
102
103 static constexpr bool is_iec559 = true;
104 static constexpr bool is_bounded = true;
105 static constexpr bool is_modulo = false;
106
107 static constexpr bool traps = std::numeric_limits<double>::traps;
108 static constexpr bool tinyness_before = std::numeric_limits<double>::tinyness_before;
109 static constexpr float_round_style round_style = round_to_nearest;
110};
111
112} // namespace std
113
114// Putting the following definitions in the namespace std yields undefined
115// behavior. Unfortunately, ADL doesn't work for aliases (Quad) because the underlying type
116// is used for the lookup. Putting these functions into any other namespace yields compiler errors.
117namespace std {
118
119inline ostream& operator<<(ostream& os, const Dumux::Quad &val)
120{
121 return (os << double(val));
122}
123
124inline istream& operator>>(istream& is, Dumux::Quad &val)
125{
126 double tmp;
127 istream &ret = (is >> tmp);
128 val = tmp;
129 return ret;
130}
131
132inline Dumux::Quad abs(Dumux::Quad val)
133{ return (val < 0)?-val:val; }
134
135inline Dumux::Quad floor(Dumux::Quad val)
136{ return floorq(val); }
137
138inline Dumux::Quad ceil(Dumux::Quad val)
139{ return ceilq(val); }
140
141inline Dumux::Quad max(Dumux::Quad a, Dumux::Quad b)
142{ return (a>b)?a:b; }
143
144inline Dumux::Quad min(Dumux::Quad a, Dumux::Quad b)
145{ return (a<b)?a:b; }
146
147inline Dumux::Quad sqrt(Dumux::Quad val)
148{ return sqrtq(val); }
149
150template <class ExpType>
151inline Dumux::Quad pow(Dumux::Quad base, ExpType exp)
152{ return powq(base, exp); }
153
154inline Dumux::Quad exp(Dumux::Quad val)
155{ return expq(val); }
156
157inline Dumux::Quad log(Dumux::Quad val)
158{ return logq(val); }
159
160inline Dumux::Quad sin(Dumux::Quad val)
161{ return sinq(val); }
162
163inline Dumux::Quad cos(Dumux::Quad val)
164{ return cosq(val); }
165
166inline Dumux::Quad tan(Dumux::Quad val)
167{ return tanq(val); }
168
169inline Dumux::Quad atan(Dumux::Quad val)
170{ return atanq(val); }
171
172inline Dumux::Quad atan2(Dumux::Quad a, Dumux::Quad b)
173{ return atan2q(a, b); }
174
175inline bool signbit(Dumux::Quad val)
176{ return signbitq(val); }
177
178inline bool isfinite(Dumux::Quad val)
179{ return !isnanq(val) && !isinfq(val); }
180
181inline bool isnan(Dumux::Quad val)
182{ return isnanq(val); }
183
184inline bool isinf(Dumux::Quad val)
185{ return isinfq(val); }
186
187} // namespace std
188
189#endif // DUMUX_QUAD_HH
Definition: adapt.hh:29
Definition: common/pdesolver.hh:35