malachite_float/comparison/partial_eq_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_nz::natural::Natural;
16
17fn float_partial_eq_unsigned<T: PrimitiveUnsigned>(x: &Float, y: &T) -> bool
18where
19 Natural: From<T>,
20{
21 match x {
22 float_either_zero!() => *y == T::ZERO,
23 Float(Finite {
24 sign,
25 exponent,
26 significand,
27 ..
28 }) => {
29 *y != T::ZERO
30 && *sign
31 && *exponent >= 0
32 && y.significant_bits() == u64::from(exponent.unsigned_abs())
33 && significand.cmp_normalized(&Natural::from(*y)) == Equal
34 }
35 _ => false,
36 }
37}
38
39macro_rules! impl_partial_eq_unsigned {
40 ($t: ident) => {
41 impl PartialEq<$t> for Float {
42 /// Determines whether a [`Float`] is equal to an unsigned 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(&self, other: &$t) -> bool {
58 float_partial_eq_unsigned(self, other)
59 }
60 }
61
62 impl PartialEq<Float> for $t {
63 /// Determines whether an unsigned primitive integer is equal to a [`Float`].
64 ///
65 /// No primitive integer is equal to $\infty$, $-\infty$, or NaN. The integer zero is
66 /// equal to both the [`Float`] zero and the [`Float`] negative zero.
67 ///
68 /// # Worst-case complexity
69 /// $T(n) = O(n)$
70 ///
71 /// $M(n) = O(1)$
72 ///
73 /// where $T$ is time, $M$ is additional memory, and $n$ is `other.significant_bits()`.
74 ///
75 /// # Examples
76 /// See [here](super::partial_eq_primitive_int#partial_eq).
77 #[inline]
78 fn eq(&self, other: &Float) -> bool {
79 other == self
80 }
81 }
82 };
83}
84apply_to_unsigneds!(impl_partial_eq_unsigned);
85
86fn float_partial_eq_signed<T: PrimitiveSigned>(x: &Float, y: &T) -> bool
87where
88 Natural: From<<T as UnsignedAbs>::Output>,
89{
90 match x {
91 float_either_zero!() => *y == T::ZERO,
92 Float(Finite {
93 sign,
94 exponent,
95 significand,
96 ..
97 }) => {
98 *y != T::ZERO
99 && *sign == (*y >= T::ZERO)
100 && *exponent >= 0
101 && y.significant_bits() == u64::from(exponent.unsigned_abs())
102 && significand.cmp_normalized(&Natural::from(y.unsigned_abs())) == Equal
103 }
104 _ => false,
105 }
106}
107
108macro_rules! impl_partial_eq_signed {
109 ($t: ident) => {
110 impl PartialEq<$t> for Float {
111 /// Determines whether a [`Float`] is equal to 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::partial_eq_primitive_int#partial_eq).
125 #[inline]
126 fn eq(&self, other: &$t) -> bool {
127 float_partial_eq_signed(self, other)
128 }
129 }
130
131 impl PartialEq<Float> for $t {
132 /// Determines whether a signed primitive integer is equal to a [`Float`].
133 ///
134 /// No primitive integer is equal to $\infty$, $-\infty$, or NaN. The integer zero is
135 /// equal to both the [`Float`] zero and the [`Float`] negative zero.
136 ///
137 /// # Worst-case complexity
138 /// $T(n) = O(n)$
139 ///
140 /// $M(n) = O(1)$
141 ///
142 /// where $T$ is time, $M$ is additional memory, and $n$ is `other.significant_bits()`.
143 ///
144 /// # Examples
145 /// See [here](super::partial_eq_primitive_int#partial_eq).
146 #[inline]
147 fn eq(&self, other: &Float) -> bool {
148 other == self
149 }
150 }
151 };
152}
153apply_to_signeds!(impl_partial_eq_signed);