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<'_> {}