In this lesson, you will learn how to implement custom equality logic to safely compare values that involve floating-point numbers.
The Problem with f64 and Equality
In Rust, the standard f64 and f32 types do not implement Eq. This is because floating-point math includes a "trap": f64::NAN == f64::NAN is false. Because they lack total equality (where everything is equal to itself), we must implement PartialEq manually when our structs contain these types.
Defining Custom Equivalence
Sometimes, "equal" doesn't mean bit-for-bit identical. If you are building a system that tracks physical measurements, you might consider two values equal if the difference between them is smaller than a tiny threshold (an "epsilon").
Here is how you implement PartialEq for a Measurement struct:
struct Measurement {
value: f64,
}
impl PartialEq for Measurement {
fn eq(&self, other: &Self) -> bool {
// Define an epsilon for comparison
let epsilon = 0.0001;
(self.value - other.value).abs() < epsilon
}
}
Why This Matters
When you implement PartialEq, you define your own "domain-specific" rules. By manually defining eq, you bypass the standard IEEE 754 floating-point behavior that would otherwise make your struct impossible to compare or sort.
Note that Eq is a subtrait of PartialEq. It has no methods of its own; it acts as a "marker trait" telling the compiler: "I promise that my PartialEq implementation is total—meaning everything is equal to itself, even NaN values." If your logic is based on an epsilon threshold, you cannot implement Eq because NaN would still break the reflexive property (a == a). Stick to PartialEq for these custom floating-point comparisons to keep your code sound.
By shifting from #[derive(PartialEq)] to an explicit impl block, you gain full control over what "equality" means for your domain, allowing you to ignore tiny precision errors that are common in scientific or financial computing.
Key Takeaway: Implement PartialEq manually to define custom equality thresholds, but remember that floating-point logic usually prevents you from implementing the Eq trait.