8#ifndef LIBFXD_COMPARE_HPP
9#define LIBFXD_COMPARE_HPP
14#include "detail/shift.hpp"
21 template<fixed_po
int Fxd>
29 return a.raw_value == b.raw_value;
34 template<fixed_point A,
43 bool different_signs = (a.raw_value < 0) != (b.raw_value < 0);
47 auto raw_a = a.raw_value;
48 auto raw_b = b.raw_value;
56 constexpr int diff = A::frac_bits - B::frac_bits;
57 if constexpr (diff > 0) {
59 auto [scaled_a, ovf] = detail::overflow::shr_real(raw_a, diff);
62 return std::cmp_equal(scaled_a, raw_b);
65 auto [scaled_b, ovf] = detail::overflow::shr_real(raw_b, -diff);
68 return std::cmp_equal(raw_a, scaled_b);
74 template<fixed_point Fxd,
83 if constexpr (Fxd::frac_bits < 0) {
84 auto [hi_b, ovf] = detail::overflow::shr_real(b, -Fxd::frac_bits);
87 return std::cmp_equal(a.raw_value, hi_b);
89 auto [hi_a, ovf] = detail::overflow::shr_real(a.raw_value, Fxd::frac_bits);
92 return std::cmp_equal(hi_a, b);
98 template<fixed_point Fxd,
99 std::floating_point Flt>
113 template<fixed_po
int Fxd>
122 using Raw =
typename Fxd::raw_type;
123 Raw ra = a.raw_value;
124 Raw rb = b.raw_value;
129 template<fixed_point A,
138 bool a_neg = a.raw_value < 0;
139 bool b_neg = b.raw_value < 0;
141 return std::strong_ordering::less;
143 return std::strong_ordering::greater;
157 constexpr int diff = A::frac_bits - B::frac_bits;
158 const auto raw_a = a.raw_value;
159 const auto raw_b = b.raw_value;
161 if (raw_a == 0 && raw_b == 0)
162 return std::strong_ordering::equal;
164 if constexpr (diff > 0) {
166 auto [scaled_a, ovf] = detail::overflow::shr_real(raw_a, diff);
167 if (std::cmp_not_equal(scaled_a, raw_b))
168 return scaled_a <=> raw_b;
170 return std::strong_ordering::greater;
171 return std::strong_ordering::equal;
174 auto [scaled_b, ovf] = detail::overflow::shr_real(raw_b, -diff);
175 if (std::cmp_not_equal(raw_a, scaled_b))
176 return raw_a <=> scaled_b;
178 return std::strong_ordering::less;
179 return std::strong_ordering::equal;
184 template<fixed_point Fxd,
193 if constexpr (Fxd::frac_bits < 0) {
194 auto [hi_b, ovf] = detail::overflow::shr_real(b, -Fxd::frac_bits);
195 auto cmp = a.raw_value <=> hi_b;
196 if (cmp != 0 || !ovf)
199 return std::strong_ordering::less;
201 auto [int_a, ovf] = detail::overflow::shr_real(a.raw_value, Fxd::frac_bits);
202 auto cmp = int_a <=> b;
203 if (cmp != 0 || !ovf)
205 return std::strong_ordering::greater;
210 template<fixed_point Fxd,
211 std::floating_point Flt>
212 requires (
requires (Fxd a) {
to_float(a);})
215 std::partial_ordering
This is the namespace where the entire library is defined.
constexpr bool operator==(Fxd a, Fxd b) noexcept
Equality check for two similar fxd::fixed.
constexpr Flt to_float(Fxd f) noexcept
Convert a fixed-point to a floating-point type, rounds to zero.
constexpr std::strong_ordering operator<=>(Fxd a, Fxd b) noexcept