demo(11-float-money-equality): 11 — Floating-point equality on a money amount#160
demo(11-float-money-equality): 11 — Floating-point equality on a money amount#160
Conversation
…y amount See scenarios/11-float-money-equality/README.md for the expected verdict.
| public double NetTotal(double subtotal, double discount) | ||
| { | ||
| var net = subtotal - discount; | ||
| if (net == 0.0) |
There was a problem hiding this comment.
GCI0049 — Float/Double Equality Comparison
Direct equality comparison on a floating-point value — use an epsilon threshold instead
Evidence:
Line 8: if (net == 0.0)
💡 Suggested action: Compare with an epsilon: Math.Abs(a - b) < 1e-9. For financial calculations use decimal instead of float/double.
Confidence: Medium | Severity: Info
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7265b3e33b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| public double NetTotal(double subtotal, double discount) | ||
| { | ||
| var net = subtotal - discount; | ||
| if (net == 0.0) |
There was a problem hiding this comment.
Avoid exact equality on floating-point totals
Replace this == check with a tolerance-based comparison (or switch to decimal) because subtotal - discount in double can produce tiny residuals for mathematically equal amounts (for example, values derived from 0.1 + 0.2 versus 0.3). In those cases this branch is skipped and a near-zero nonzero result leaks out, which is incorrect for zero-net pricing logic.
Useful? React with 👍 / 👎.
11 — Floating-point equality on a money amount
Expected verdict: ❌ Fails — GauntletCI should fire GCI0049 (float/double equality comparison).
What changed
A new
LegacyDiscountCalculatorworks indouble(because it wasported from a JavaScript pricing prototype) and tests for an exact
zero-net result with
==:For most inputs
subtotal - discountis exactly representable, but forvalues like
0.1 + 0.2 - 0.3the result is5.55e-17, not0.0, andthe comparison silently returns
false.Why this is risky
==indouble/float.Binary floating-point cannot exactly represent most decimal fractions,
so a "zero net" check returns the wrong answer for a single rounding
ulp difference.
pairs, so it sails through unit tests that use round numbers and
surfaces in production for the one customer with $19.99 and a
$19.99 discount.
Math.Abs(net) < 1e-9) or— much better for money — using
decimalend-to-end.What GauntletCI catches
GCI0049 Float/Double Equality Comparison—==(or!=) on thesame line as a floating-point literal in a non-test file.