10 #ifndef FIXED_POINT_MATH_H_ 11 #define FIXED_POINT_MATH_H_ 13 #include <sg14/fixed_point> 24 template<
class FixedPo
int>
25 constexpr FixedPoint rounding_conversion(
double d) {
26 using one_longer = make_fixed<FixedPoint::integer_digits, FixedPoint::fractional_digits + 1>;
27 return FixedPoint::from_data(static_cast<typename FixedPoint::rep>((one_longer{ d }.data() + 1) >> 1));
30 template<
class FixedPo
int>
31 using unsigned_rep =
typename std::make_unsigned<typename FixedPoint::rep>::type;
34 using make_largest_ufraction = fixed_point<unsigned_rep<Input>, -std::numeric_limits<unsigned_rep<Input>>::digits>;
36 static_assert(std::is_same<make_largest_ufraction<fixed_point<int32_t, -15>>, fixed_point<uint32_t, -32>>::value,
"");
43 template<
class CoeffType>
45 static constexpr CoeffType a1 { rounding_conversion<CoeffType>(0.6931471860838825) };
46 static constexpr CoeffType a2 { rounding_conversion<CoeffType>(0.2402263846181129) };
47 static constexpr CoeffType a3 { rounding_conversion<CoeffType>(
48 0.055505126858894846) };
49 static constexpr CoeffType a4 { rounding_conversion<CoeffType>(
50 0.009614017013719252) };
51 static constexpr CoeffType a5 { rounding_conversion<CoeffType>(
52 0.0013422634797558564) };
53 static constexpr CoeffType a6 { rounding_conversion<CoeffType>(
54 0.00014352314226313836) };
55 static constexpr CoeffType a7 { rounding_conversion<CoeffType>(
56 0.000021498763160402416) };
59 template<
class CoeffType>
60 constexpr CoeffType poly_coeffs<CoeffType>::a1;
61 template<
class CoeffType>
62 constexpr CoeffType poly_coeffs<CoeffType>::a2;
63 template<
class CoeffType>
64 constexpr CoeffType poly_coeffs<CoeffType>::a3;
65 template<
class CoeffType>
66 constexpr CoeffType poly_coeffs<CoeffType>::a4;
67 template<
class CoeffType>
68 constexpr CoeffType poly_coeffs<CoeffType>::a5;
69 template<
class CoeffType>
70 constexpr CoeffType poly_coeffs<CoeffType>::a6;
71 template<
class CoeffType>
72 constexpr CoeffType poly_coeffs<CoeffType>::a7;
74 template<
class Rep,
int Exponent>
75 constexpr
inline fixed_point<Rep, Exponent> evaluate_polynomial(
76 fixed_point<Rep, Exponent> xf) {
77 using fp = fixed_point<Rep, Exponent>;
82 using coeffs = poly_coeffs<fp>;
83 return fp{multiply(xf, (coeffs::a1+fp{multiply(xf, (coeffs::a2+fp{multiply(xf, (coeffs::a3+fp{multiply(xf, (coeffs::a4
84 +fp{multiply(xf, (coeffs::a5+fp{multiply(xf, (coeffs::a6+fp{multiply(fp{coeffs::a7}, fp{xf})}))}))}))}))}))}))};
90 template<
class Rep,
int Exponent, _impl::enable_if_t<(Exponent>=0),
int> dummy = 0>
91 inline constexpr make_largest_ufraction<fixed_point<Rep, Exponent>> exp2m1_0to1(
92 fixed_point<Rep, Exponent>) {
93 return make_largest_ufraction<fixed_point<Rep, Exponent>>::from_data(
97 template<
class Rep,
int Exponent, _impl::enable_if_t<(Exponent<0),
int> dummy = 0>
98 constexpr inline make_largest_ufraction<fixed_po
int<Rep, Exponent>> exp2m1_0to1(
99 fixed_po
int<Rep, Exponent> x) {
104 using im = make_largest_ufraction<fixed_po
int<Rep, Exponent>>;
107 return evaluate_polynomial(im{x});
110 template<
class Rep,
int Exponent>
111 constexpr
inline Rep floor(fixed_point<Rep, Exponent> x) {
112 return Rep { (x.data()) >> -Exponent };
126 template<
class Rep,
int Exponent>
128 using namespace _impl::fp;
132 using im = make_largest_ufraction<out_type>;
136 return out_type::from_data(
137 floor(x) <= Exponent ?
141 (exp2m1_0to1<Rep, Exponent>(
static_cast<out_type
>(x - floor(x))).data()
142 >> (-im::exponent + Exponent - floor(x)))
143 + (Rep { 1 } << (floor(x) - Exponent)));
literal real number approximation that uses fixed-point arithmetic
Definition: fixed_point_type.h:20
constexpr fixed_point< Rep, Exponent > exp2(fixed_point< Rep, Exponent > x)
Calculates exp2(x), i.e. 2^xAccurate to 1LSB for up to 32 bit underlying representation.
Definition: fixed_point_math.h:127
study group 14 of the C++ working group
Definition: const_integer.h:22