malachite_float/comparison/eq_abs_primitive_int.rs
1// Copyright © 2025 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::Float;
10use crate::InnerFloat::{Finite, Zero};
11use core::cmp::Ordering::*;
12use malachite_base::num::arithmetic::traits::UnsignedAbs;
13use malachite_base::num::basic::signeds::PrimitiveSigned;
14use malachite_base::num::basic::unsigneds::PrimitiveUnsigned;
15use malachite_base::num::comparison::traits::EqAbs;
16use malachite_nz::natural::Natural;
17
18fn float_eq_abs_unsigned<T: PrimitiveUnsigned>(x: &Float, y: &T) -> bool
19where
20 Natural: From<T>,
21{
22 match x {
23 float_either_zero!() => *y == T::ZERO,
24 Float(Finite {
25 exponent,
26 significand,
27 ..
28 }) => {
29 *y != T::ZERO
30 && *exponent >= 0
31 && y.significant_bits() == u64::from(exponent.unsigned_abs())
32 && significand.cmp_normalized(&Natural::from(*y)) == Equal
33 }
34 _ => false,
35 }
36}
37
38macro_rules! impl_eq_abs_unsigned {
39 ($t: ident) => {
40 impl EqAbs<$t> for Float {
41 /// Determines whether the absolute value of a [`Float`] is equal to an unsigned
42 /// primitive integer.
43 ///
44 /// $\infty$, $-\infty$, and NaN are not equal to any primitive integer. Both the
45 /// [`Float`] zero and the [`Float`] negative zero are equal to the integer zero.
46 ///
47 /// # Worst-case complexity
48 /// $T(n) = O(n)$
49 ///
50 /// $M(n) = O(1)$
51 ///
52 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
53 ///
54 /// # Examples
55 /// See [here](super::partial_eq_primitive_int#partial_eq).
56 #[inline]
57 fn eq_abs(&self, other: &$t) -> bool {
58 float_eq_abs_unsigned(self, other)
59 }
60 }
61
62 impl EqAbs<Float> for $t {
63 /// Determines whether an unsigned primitive integer is equal to the absolute value of a
64 /// [`Float`].
65 ///
66 /// No primitive integer is equal to $\infty$, $-\infty$, or NaN. The integer zero is
67 /// equal to both the [`Float`] zero and the [`Float`] negative zero.
68 ///
69 /// # Worst-case complexity
70 /// $T(n) = O(n)$
71 ///
72 /// $M(n) = O(1)$
73 ///
74 /// where $T$ is time, $M$ is additional memory, and $n$ is `other.significant_bits()`.
75 ///
76 /// # Examples
77 /// See [here](super::partial_eq_primitive_int#partial_eq).
78 #[inline]
79 fn eq_abs(&self, other: &Float) -> bool {
80 other.eq_abs(self)
81 }
82 }
83 };
84}
85apply_to_unsigneds!(impl_eq_abs_unsigned);
86
87fn float_eq_abs_signed<T: PrimitiveSigned>(x: &Float, y: &T) -> bool
88where
89 Natural: From<<T as UnsignedAbs>::Output>,
90{
91 match x {
92 float_either_zero!() => *y == T::ZERO,
93 Float(Finite {
94 exponent,
95 significand,
96 ..
97 }) => {
98 *y != T::ZERO
99 && *exponent >= 0
100 && y.significant_bits() == u64::from(exponent.unsigned_abs())
101 && significand.cmp_normalized(&Natural::from(y.unsigned_abs())) == Equal
102 }
103 _ => false,
104 }
105}
106
107macro_rules! impl_eq_abs_signed {
108 ($t: ident) => {
109 impl EqAbs<$t> for Float {
110 /// Determines whether the absolute value of a [`Float`] is equal to the absolute value
111 /// of a signed primitive integer.
112 ///
113 /// $\infty$, $-\infty$, and NaN are not equal to any primitive integer. Both the
114 /// [`Float`] zero and the [`Float`] negative zero are equal to the integer zero.
115 ///
116 /// # Worst-case complexity
117 /// $T(n) = O(n)$
118 ///
119 /// $M(n) = O(1)$
120 ///
121 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
122 ///
123 /// # Examples
124 /// See [here](super::eq_abs#eq_abs).
125 #[inline]
126 fn eq_abs(&self, other: &$t) -> bool {
127 float_eq_abs_signed(self, other)
128 }
129 }
130
131 impl EqAbs<Float> for $t {
132 /// Determines whether the absolute value of a signed primitive integer is equal to the
133 /// absolute value of a [`Float`].
134 ///
135 /// No primitive integer is equal to $\infty$, $-\infty$, or NaN. The integer zero is
136 /// equal to both the [`Float`] zero and the [`Float`] negative zero.
137 ///
138 /// # Worst-case complexity
139 /// $T(n) = O(n)$
140 ///
141 /// $M(n) = O(1)$
142 ///
143 /// where $T$ is time, $M$ is additional memory, and $n$ is `other.significant_bits()`.
144 ///
145 /// # Examples
146 /// See [here](super::eq_abs#eq_abs).
147 #[inline]
148 fn eq_abs(&self, other: &Float) -> bool {
149 other.eq_abs(self)
150 }
151 }
152 };
153}
154apply_to_signeds!(impl_eq_abs_signed);