10 #if !defined(SG14_FIXED_POINT_DEF_H) 11 #define SG14_FIXED_POINT_DEF_H 1 13 #include <sg14/auxiliary/const_integer.h> 14 #include <sg14/bits/number_base.h> 19 template<
class Rep =
int,
int Exponent = 0>
30 template<
int NumBits,
class Enable =
void>
34 struct float_of_size<NumBits, enable_if_t<NumBits <=
sizeof(float)*CHAR_BIT>> {
39 struct float_of_size<NumBits, enable_if_t<sizeof(float)*CHAR_BIT < NumBits && NumBits <= sizeof(double)*CHAR_BIT>> {
44 struct float_of_size<NumBits, enable_if_t<sizeof(double)*CHAR_BIT < NumBits && NumBits <= sizeof(long double)*CHAR_BIT>> {
45 using type =
long double;
52 using float_of_same_size =
typename float_of_size<digits<T>::value + is_signed<T>::value>::type;
67 template<
class Rep,
int Exponent>
69 :
public _impl::number_base<fixed_point<Rep, Exponent>, Rep> {
70 using _base = _impl::number_base<fixed_point<Rep, Exponent>, Rep>;
82 constexpr
static int exponent = Exponent;
86 constexpr
static int digits = std::numeric_limits<Rep>::digits;
90 constexpr
static int integer_digits = digits+exponent;
94 constexpr
static int fractional_digits = -exponent;
111 template<
class FromRep,
int FromExponent>
113 : _base(fixed_point_to_rep(rhs))
118 template<
class Integral, Integral Constant>
119 constexpr
fixed_point(
const std::integral_constant<Integral, Constant>&)
120 : fixed_point(fixed_point<Integral, 0>::from_data(Constant))
125 template<class S, _impl::enable_if_t<std::numeric_limits<S>::is_integer,
int> Dummy = 0>
127 : fixed_point(fixed_point<S, 0>::from_data(s))
132 template<
class Integral, Integral Value,
int Digits>
134 : _base(ci << Exponent)
139 template<class S, _impl::enable_if_t<std::numeric_limits<S>::is_iec559,
int> Dummy = 0>
141 :_base(floating_point_to_rep(s))
146 template<class S, _impl::enable_if_t<std::numeric_limits<S>::is_integer,
int> Dummy = 0>
153 template<class S, _impl::enable_if_t<std::numeric_limits<S>::is_iec559,
int> Dummy = 0>
156 _base::operator=(floating_point_to_rep(s));
161 template<
class FromRep,
int FromExponent>
164 _base::operator=(fixed_point_to_rep(rhs));
169 template<
typename R = Rep>
170 constexpr
operator typename std::enable_if<std::is_convertible<Rep, bool>::value,
bool>()
const 172 return static_cast<bool>(_base::data());
176 template<class S, _impl::enable_if_t<std::numeric_limits<S>::is_integer,
int> Dummy = 0>
177 constexpr
operator S()
const 179 return rep_to_integral<S>(_base::data());
183 template<class S, _impl::enable_if_t<std::numeric_limits<S>::is_iec559,
int> Dummy = 0>
184 explicit constexpr
operator S()
const 186 return rep_to_floating_point<S>(_base::data());
196 template<class S, _impl::enable_if_t<std::numeric_limits<S>::is_iec559,
int> Dummy = 0>
197 static constexpr S one();
199 template<class S, _impl::enable_if_t<std::numeric_limits<S>::is_integer,
int> Dummy = 0>
200 static constexpr S one();
203 static constexpr S inverse_one();
206 static constexpr S rep_to_integral(
rep r);
209 static constexpr
rep floating_point_to_rep(S s);
212 static constexpr S rep_to_floating_point(
rep r);
214 template<
class FromRep,
int FromExponent>
219 template<
class Rep,
int Exponent>
224 template<
class Rep,
int Exponent>
229 template<
class Rep,
int Exponent>
234 template<
class Rep,
int Exponent>
246 struct is_fixed_point
247 :
public std::false_type {
250 template<
class Rep,
int Exponent>
251 struct is_fixed_point<fixed_point<Rep, Exponent>>
252 :
public std::true_type {
263 template<
int exp,
class Output,
class Input>
264 constexpr Output shift_left(Input i)
266 using larger =
typename std::conditional<
267 digits<Input>::value<=digits<Output>::value,
268 Output, Input>::type;
270 return (exp>-std::numeric_limits<larger>::digits)
271 ?
static_cast<Output
>(_impl::scale<larger>(
static_cast<larger
>(i), 2, exp))
284 template<
class S,
int Exponent, enable_if_t<Exponent==0,
int> Dummy = 0>
287 static_assert(std::numeric_limits<S>::is_iec559,
"S must be floating-point type");
291 template<
class S,
int Exponent,
292 enable_if_t<!(Exponent<=0) && (Exponent<8), int> Dummy = 0>
295 static_assert(std::numeric_limits<S>::is_iec559,
"S must be floating-point type");
296 return pow2<S, Exponent-1>()*S(2);
299 template<
class S,
int Exponent, enable_if_t<(Exponent>=8),
int> Dummy = 0>
302 static_assert(std::numeric_limits<S>::is_iec559,
"S must be floating-point type");
303 return pow2<S, Exponent-8>()*S(256);
306 template<
class S,
int Exponent,
307 enable_if_t<!(Exponent>=0) && (Exponent>-8),
int> Dummy = 0>
310 static_assert(std::numeric_limits<S>::is_iec559,
"S must be floating-point type");
311 return pow2<S, Exponent+1>()*S(.5);
314 template<
class S,
int Exponent, enable_if_t<(Exponent<=-8),
int> Dummy = 0>
317 static_assert(std::numeric_limits<S>::is_iec559,
"S must be floating-point type");
318 return pow2<S, Exponent+8>()*S(.003906250);
327 template<
class Rep,
int Exponent>
328 template<class S, _impl::enable_if_t<std::numeric_limits<S>::is_iec559,
int> Dummy>
331 return _impl::fp::type::pow2<S, -exponent>();
334 template<
class Rep,
int Exponent>
335 template<class S, _impl::enable_if_t<std::numeric_limits<S>::is_integer,
int> Dummy>
341 template<
class Rep,
int Exponent>
345 static_assert(std::numeric_limits<S>::is_iec559,
"S must be floating-point type");
346 return _impl::fp::type::pow2<S, exponent>();
349 template<
class Rep,
int Exponent>
353 static_assert(std::numeric_limits<S>::is_integer,
"S must be integral type");
355 return _impl::shift_left<exponent, S>(r);
358 template<
class Rep,
int Exponent>
362 static_assert(std::numeric_limits<S>::is_iec559,
"S must be floating-point type");
363 return static_cast<rep>(s*one<S>());
366 template<
class Rep,
int Exponent>
370 static_assert(std::numeric_limits<S>::is_iec559,
"S must be floating-point type");
371 return S(r)*inverse_one<S>();
374 template<
class Rep,
int Exponent>
375 template<
class FromRep,
int FromExponent>
378 return _impl::shift_left<FromExponent-exponent,
rep>(rhs.data());
382 #endif // SG14_FIXED_POINT_DEF_H constexpr fixed_point(const_integer< Integral, Value, Digits, Exponent > ci)
constructor taking an integral_constant type
Definition: fixed_point_type.h:133
constexpr fixed_point(S s)
constructor taking a floating-point type
Definition: fixed_point_type.h:140
fixed_point & operator=(const fixed_point< FromRep, FromExponent > &rhs)
copy assignement operator taking a fixed-point type
Definition: fixed_point_type.h:162
static constexpr fixed_point from_data(rep const &r)
creates an instance given the underlying representation value
Definition: fixed_point_type.h:190
constexpr fixed_point()
default constructor
Definition: fixed_point_type.h:108
constexpr fixed_point(const S &s)
constructor taking an integer type
Definition: fixed_point_type.h:126
constexpr fixed_point(const fixed_point< FromRep, FromExponent > &rhs)
constructor taking a fixed-point type
Definition: fixed_point_type.h:112
a compile-time-only integer type like a std::integral_constant with arithmetic support ...
Definition: const_integer.h:98
fixed_point & operator=(S s)
copy assignment operator taking an integer type
Definition: fixed_point_type.h:147
Rep rep
alias to template parameter, Rep
Definition: fixed_point_type.h:76
literal real number approximation that uses fixed-point arithmetic
Definition: fixed_point_type.h:20
constexpr fixed_point(const std::integral_constant< Integral, Constant > &)
constructor taking an integral_constant type
Definition: fixed_point_type.h:119
study group 14 of the C++ working group
Definition: const_integer.h:22