You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
sig.Equals(precise) returns false for equal values while sig == precise, precise.Equals(sig) and CompareTo all say they're equal #143
SignificantNumber is a readonly record struct (SignificantNumber/SignificantNumber.cs:28) with no Equals(PreciseNumber) overload. So sig.Equals(precise) binds to the synthesized Equals(object), which boxes the PreciseNumber, fails the is SignificantNumber type check, and returns false.
Every other way of comparing the same pair treats it as equal:
the mixed == operators (SignificantNumber.cs:456-466)
CompareTo(object)
precise.Equals(sig), which binds to PreciseNumber.Equals(PreciseNumber) through the implicit conversion
This is not a regression: 1.4.40 gives the same results.
Why it matters
measured.Equals(expectedPrecise) is false while measured == expectedPrecise is true, so an assertion, List.Contains/IndexOf, or LINQ Contains that uses Equals silently misses an equal value.
Equals is not symmetric, which breaks the Equals contract.
The migration guide says "Compare values with == or Equals", but which of the two you pick changes the answer.
Suggested fix / acceptance criteria
Add public bool Equals(PreciseNumber other) => Value.Equals(other);, plus IEquatable<PreciseNumber> if desired, so that s.Equals(p) == p.Equals(s) == (s == p).
Document the remaining case: Equals(object) with a boxed PreciseNumber stays false, because the record struct's Equals(object) can't be customised, even though CompareTo(object) returns 0 for it.
Add tests that cover both argument orders, plus the boxed case, for equal and unequal values.
Priority: Medium. Equals is asymmetric, which breaks the Equals contract, and List.Contains/IndexOf/LINQ Contains miss equal values without any error. It isn't a regression (1.4.40 behaves the same), and == already gives the right answer. The fix is small and additive.
Area / suggested assignment:SignificantNumber/SignificantNumber.cs: add an Equals(PreciseNumber) overload (plus IEquatable<PreciseNumber> if wanted) next to the mixed == operators at L456-466, and update the migration guide's "Compare values with == or Equals" wording to cover the boxed Equals(object) case.
Activity
matt-edmondson commentedon Nov 3, 2026
Triage
Equalsis asymmetric, which breaks theEqualscontract, andList.Contains/IndexOf/LINQContainsmiss equal values without any error. It isn't a regression (1.4.40 behaves the same), and==already gives the right answer. The fix is small and additive.SignificantNumber/SignificantNumber.cs: add anEquals(PreciseNumber)overload (plusIEquatable<PreciseNumber>if wanted) next to the mixed==operators at L456-466, and update the migration guide's "Compare values with==orEquals" wording to cover the boxedEquals(object)case.sum += 2loop stops at 10 #124, ++ and -- skip the addition rounding rule: 1.2E3++ gives 1201, while 1.2E3 + 1 gives 1200 #125,%returns 0 whenever an integer operand ends in 0: 37 % 10 == 0, 1234 % 100 == 0, 10 % 3 == 0 #135, A computed result that rounds to 0, 1 or -1 is treated as exact: (1.4 - 0.4) * 3.14159 == 3.14159, but (1.4 - 0.5) * 3.14159 == 3 #139), not equality binding.Generated by Claude Code