malachite_float/comparison/eq.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::InnerFloat::{Finite, Infinity, NaN, Zero};
10use crate::{ComparableFloat, ComparableFloatRef, Float};
11use core::cmp::Ordering::*;
12
13impl PartialEq for Float {
14 /// Compares two [`Float`]s for equality.
15 ///
16 /// This implementation follows the IEEE 754 standard. `NaN` is not equal to anything, not even
17 /// itself. Positive zero is equal to negative zero. [`Float`]s with different precisions are
18 /// equal if they represent the same numeric value.
19 ///
20 /// For different equality behavior, consider using [`ComparableFloat`] or
21 /// [`ComparableFloatRef`].
22 ///
23 /// # Worst-case complexity
24 /// $T(n) = O(n)$
25 ///
26 /// $M(n) = O(1)$
27 ///
28 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
29 /// other.significant_bits())`.
30 ///
31 /// # Examples
32 /// ```
33 /// use malachite_base::num::basic::traits::{NaN, NegativeZero, One, Two, Zero};
34 /// use malachite_float::Float;
35 ///
36 /// assert_ne!(Float::NAN, Float::NAN);
37 /// assert_eq!(Float::ZERO, Float::ZERO);
38 /// assert_eq!(Float::NEGATIVE_ZERO, Float::NEGATIVE_ZERO);
39 /// assert_eq!(Float::ZERO, Float::NEGATIVE_ZERO);
40 ///
41 /// assert_eq!(Float::ONE, Float::ONE);
42 /// assert_ne!(Float::ONE, Float::TWO);
43 /// assert_eq!(Float::ONE, Float::one_prec(100));
44 /// ```
45 fn eq(&self, other: &Float) -> bool {
46 match (self, other) {
47 (Float(Infinity { sign: s_x }), Float(Infinity { sign: s_y })) => s_x == s_y,
48 (float_either_zero!(), float_either_zero!()) => true,
49 (
50 Float(Finite {
51 sign: s_x,
52 exponent: e_x,
53 significand: x,
54 ..
55 }),
56 Float(Finite {
57 sign: s_y,
58 exponent: e_y,
59 significand: y,
60 ..
61 }),
62 ) => e_x == e_y && s_x == s_y && x.cmp_normalized_no_shift(y) == Equal,
63 _ => false,
64 }
65 }
66}
67
68impl PartialEq for ComparableFloat {
69 /// Compares two [`ComparableFloat`]s for equality.
70 ///
71 /// This implementation ignores the IEEE 754 standard in favor of an equality operation that
72 /// respects the expected properties of symmetry, reflexivity, and transitivity. Using
73 /// [`ComparableFloat`], `NaN`s are equal to themselves. There is a single, unique `NaN`;
74 /// there's no concept of signalling `NaN`s. Positive and negative zero are two distinct values,
75 /// not equal to each other. [`ComparableFloat`]s with different precisions are unequal.
76 ///
77 /// # Worst-case complexity
78 /// $T(n) = O(n)$
79 ///
80 /// $M(n) = O(1)$
81 ///
82 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
83 /// other.significant_bits())`.
84 ///
85 /// # Examples
86 /// ```
87 /// use malachite_base::num::basic::traits::{NaN, NegativeZero, One, Two, Zero};
88 /// use malachite_float::{ComparableFloat, Float};
89 ///
90 /// assert_eq!(ComparableFloat(Float::NAN), ComparableFloat(Float::NAN));
91 /// assert_eq!(ComparableFloat(Float::ZERO), ComparableFloat(Float::ZERO));
92 /// assert_eq!(
93 /// ComparableFloat(Float::NEGATIVE_ZERO),
94 /// ComparableFloat(Float::NEGATIVE_ZERO)
95 /// );
96 /// assert_ne!(
97 /// ComparableFloat(Float::ZERO),
98 /// ComparableFloat(Float::NEGATIVE_ZERO)
99 /// );
100 ///
101 /// assert_eq!(ComparableFloat(Float::ONE), ComparableFloat(Float::ONE));
102 /// assert_ne!(ComparableFloat(Float::ONE), ComparableFloat(Float::TWO));
103 /// assert_ne!(
104 /// ComparableFloat(Float::ONE),
105 /// ComparableFloat(Float::one_prec(100))
106 /// );
107 /// ```
108 #[inline]
109 fn eq(&self, other: &ComparableFloat) -> bool {
110 self.as_ref() == other.as_ref()
111 }
112}
113
114impl Eq for ComparableFloat {}
115
116impl<'a> PartialEq<ComparableFloatRef<'a>> for ComparableFloatRef<'_> {
117 /// Compares two [`ComparableFloatRef`]s for equality.
118 ///
119 /// This implementation ignores the IEEE 754 standard in favor of an equality operation that
120 /// respects the expected properties of symmetry, reflexivity, and transitivity. Using
121 /// [`ComparableFloatRef`], `NaN`s are equal to themselves. There is a single, unique `NaN`;
122 /// there's no concept of signalling `NaN`s. Positive and negative zero are two distinct values,
123 /// not equal to each other. [`ComparableFloatRef`]s with different precisions are unequal.
124 ///
125 /// # Worst-case complexity
126 /// $T(n) = O(n)$
127 ///
128 /// $M(n) = O(1)$
129 ///
130 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
131 /// other.significant_bits())`.
132 ///
133 /// # Examples
134 /// ```
135 /// use malachite_base::num::basic::traits::{NaN, NegativeZero, One, Two, Zero};
136 /// use malachite_float::{ComparableFloatRef, Float};
137 ///
138 /// assert_eq!(
139 /// ComparableFloatRef(&Float::NAN),
140 /// ComparableFloatRef(&Float::NAN)
141 /// );
142 /// assert_eq!(
143 /// ComparableFloatRef(&Float::ZERO),
144 /// ComparableFloatRef(&Float::ZERO)
145 /// );
146 /// assert_eq!(
147 /// ComparableFloatRef(&Float::NEGATIVE_ZERO),
148 /// ComparableFloatRef(&Float::NEGATIVE_ZERO)
149 /// );
150 /// assert_ne!(
151 /// ComparableFloatRef(&Float::ZERO),
152 /// ComparableFloatRef(&Float::NEGATIVE_ZERO)
153 /// );
154 ///
155 /// assert_eq!(
156 /// ComparableFloatRef(&Float::ONE),
157 /// ComparableFloatRef(&Float::ONE)
158 /// );
159 /// assert_ne!(
160 /// ComparableFloatRef(&Float::ONE),
161 /// ComparableFloatRef(&Float::TWO)
162 /// );
163 /// assert_ne!(
164 /// ComparableFloatRef(&Float::ONE),
165 /// ComparableFloatRef(&Float::one_prec(100))
166 /// );
167 /// ```
168 fn eq(&self, other: &ComparableFloatRef<'a>) -> bool {
169 match (&self.0, &other.0) {
170 (float_nan!(), float_nan!()) => true,
171 (Float(Infinity { sign: s_x }), Float(Infinity { sign: s_y }))
172 | (Float(Zero { sign: s_x }), Float(Zero { sign: s_y })) => s_x == s_y,
173 (
174 Float(Finite {
175 sign: s_x,
176 exponent: e_x,
177 precision: p_x,
178 significand: x,
179 }),
180 Float(Finite {
181 sign: s_y,
182 exponent: e_y,
183 precision: p_y,
184 significand: y,
185 }),
186 ) => s_x == s_y && e_x == e_y && p_x == p_y && x == y,
187 _ => false,
188 }
189 }
190}
191
192impl Eq for ComparableFloatRef<'_> {}