27#include "detail/add.hpp"
28#include "detail/shift.hpp"
35 template<fixed_po
int Fxd>
41 return f.raw_value < 0 ? -f : +f;
46 template<fixed_po
int Fxd>
61 template<fixed_po
int Fxd>
74 template<fixed_po
int Fxd>
80 if constexpr (std::numeric_limits<Fxd>::is_signed) {
82 if (x == std::numeric_limits<Fxd>::lowest())
83 return Fxd::int_bits - 1;
88 return std::numeric_limits<int>::min();
90 using URaw = std::make_unsigned_t<typename Fxd::raw_type>;
91 URaw rx = x.raw_value;
92 return std::bit_width(rx) - 1 - Fxd::frac_bits;
98 template<fixed_po
int Fxd>
106 return Fxd::from_raw(x.raw_value << exp);
108 auto [y, ovf] = detail::overflow::shr_real(x.raw_value, -exp);
111 return Fxd::from_raw(y);
120 template<fixed_po
int Fxd>
127 return Fxd::from_raw(detail::shl(x.raw_value, exp));
134 template<fixed_po
int Fxd>
142 return Fxd::from_raw(x.raw_value << exp);
144 auto [y, ovf] = detail::overflow::shr_real(x.raw_value, -exp);
147 return Fxd::from_raw(y);
155 template<fixed_po
int Fxd>
162 auto mid = std::midpoint(a.raw_value, b.raw_value);
163 return Fxd::from_raw(mid);
168 template<fixed_po
int Fxd>
175 constexpr Fxd e = std::numeric_limits<Fxd>::epsilon();
190 template<
unsigned_fixed_po
int Fxd>
191 requires (Fxd::int_bits > 0 && Fxd::frac_bits >= 0)
206 Fxd a, b = std::max(Fxd{1}, x);
225 }
while (old_b != b);
228 Fxd a_next = a + std::numeric_limits<Fxd>::epsilon();
229 if (
up::mul(a_next, a_next) <= x)
240 template<
signed_fixed_po
int Fxd>
241 requires (Fxd::int_bits > 1 && Fxd::frac_bits >= 0)
251 auto ux = fxd::fixed_cast<fxd::make_unsigned_t<Fxd>>(x);
253 return fixed_cast<Fxd>(r);
258 template<
unsigned_fixed_po
int Fxd>
259 requires (Fxd::int_bits > 0 && Fxd::frac_bits >= 0)
267 using Lim = std::numeric_limits<Fxd>;
272 const int top_bit = (Lim::max_bit <= 17
276 const int bot_bit = Lim::min_bit / 2;
282 for (
int b = top_bit; b >= 0; --b) {
293 for (
int b = -1; b >= bot_bit; --b) {
303 if (Lim::min_bit >= -32) {
306 for (
int b = bot_bit - 1; b >= Lim::min_bit; --b) {
308 if (
up::mul(next_r, next_r) <= x)
324 if (++i > Fxd::frac_bits)
335 Fxd a_next = a + std::numeric_limits<Fxd>::epsilon();
336 if (
up::mul(a_next, a_next) <= x)
349 template<
signed_fixed_po
int Fxd>
350 requires (Fxd::int_bits > 1 && Fxd::frac_bits >= 0)
359 auto ux = fxd::fixed_cast<fxd::make_unsigned_t<Fxd>>(x);
361 return fixed_cast<Fxd>(r);
constexpr Fxd ldexp(Fxd x, int exp) noexcept
Same as std::ldexp().
constexpr Fxd div(Fxd a, Fxd b) noexcept
Divide rounding down.
constexpr Fxd mul(Fxd a, Fxd b) noexcept
Multiply rounding up.
constexpr Fxd ldexp(Fxd x, int exp) noexcept
Same as std::ldexp().
This is the namespace where the entire library is defined.
constexpr Fxd midpoint(Fxd a, Fxd b) noexcept
Same as std::midpoint().
constexpr Fxd sqrt(Fxd x) noexcept
Same as std::sqrt().
constexpr int ilogb(Fxd x) noexcept
Same as std::ilogb().
Fxd sqrt_bin(Fxd x) noexcept
constexpr Fxd nextafter(Fxd from, Fxd to) noexcept
Same as std::nextafter().
constexpr Fxd fdim(Fxd a, Fxd b) noexcept
Same as std::fdim().
constexpr Fxd fma(Fxd a, Fxd b, Fxd c) noexcept
Same as std::fma().