Float Equality
ID |
csharp.float_equality |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
CSharp |
Tags |
float, reliability |
Description
Reports == and != comparisons in which at least one operand is of a binary
floating-point type (float, double, System.Single or System.Double).
Rounding errors accumulated during arithmetic make exact equality very unlikely,
so such comparisons almost always indicate a bug.
Rationale
Binary floating-point representations cannot represent most decimal fractions
exactly. After a few arithmetic operations two values that the programmer expects
to be equal will typically differ by a few ULPs, making a == b false even when
the two values are mathematically equal. The decimal type is base-10 and does
not suffer from this problem; comparisons on decimal are not flagged.
double a = 0.1 + 0.2;
double b = 0.3;
if (a == b) { /* ... */ } // FLAW — exact equality on double
if (Math.Abs(a - b) < 1e-9) { /* ... */ } // OK — epsilon comparison
decimal d = 0.1m + 0.2m;
if (d == 0.3m) { /* ... */ } // OK — decimal is exact
Remediation
Compare the absolute difference against a domain-appropriate epsilon, or switch
to the decimal type when exact decimal arithmetic is required.