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.