Safeguard
Application Security•

CWE-1077 Floating Point Comparison with Incorrect Operator

Comparing floats with equality can fail because of rounding. CWE-1077 explains why, with Python and Java examples and safe comparison patterns.

Safeguard Security Team
3 min read

CWE-1077 is code that compares two floating point values, for example for equality, using operators that do not account for loss of precision. It affects any program doing arithmetic on floats, including pricing, scoring, limits and thresholds.

How it happens

MITRE explains that numeric calculation with floating point values can generate imprecise results because of rounding errors. Two calculations can produce numbers that are mathematically equal but have slightly different bit representations, so an equality test returns an unexpected answer.

The classic demonstration:

# Vulnerable pattern: exact equality on computed floats
total = 0.1 + 0.2
if total == 0.3:
    grant_access()
else:
    deny_access()

In most languages that comparison is false, because 0.1 plus 0.2 is not stored as exactly 0.3. The same happens in Java:

// Vulnerable pattern
double a = 0.1 + 0.2;
if (a == 0.3) {
    approve();
}

The failure can go either direction. A discount code may never match, or a limit check may pass or fail at the boundary when it should not.

What an attacker gains

MITRE lists reduced reliability: "If the relevant code is reachable by an attacker, then this reliability problem might introduce a vulnerability." The attacker's route is through boundaries. Where a limit, balance or threshold is compared as a float, the attacker can pick inputs that land on the wrong side of the rounding error.

How to find it

MITRE says automated static analysis (SAST) can find some instances by analyzing source code without running it. Add manual checks:

  • Search for == and != where either side is a float or double.
  • Review comparisons in money, quota and security threshold code first.
  • Write tests with boundary values, such as the sum of 0.1 and 0.2.

Try it yourself

A static scan flags risky comparison patterns across a codebase. This demo shows the idea.

Click through it at your own pace, or open it full screen.

How to fix it

The record lists no mitigations, so these are standard techniques.

  1. Compare with a tolerance instead of exact equality.
  2. Use exact types for money and counts: integers in the smallest unit, or a decimal type.
  3. Use ordered comparisons deliberately, and decide how the boundary should behave.
# Fixed: tolerance comparison
import math
if math.isclose(total, 0.3, rel_tol=1e-9):
    grant_access()
// Fixed: explicit tolerance
if (Math.abs(a - 0.3) < 1e-9) {
    approve();
}

For money, store cents as an integer so the problem never arises:

price_cents = 1999

Pick the tolerance with care. It should reflect the precision your data really has, not just a tiny number.

Libraries can contain this mistake too, and reachability analysis shows whether your code calls a vulnerable function at all. You can start with the free scan at gold.safeguard.sh/scan, which needs no login, covers up to 100 dependencies and keeps your file on your machine.

Quick check

Why does 0.1 plus 0.2 not equal 0.3 in most languages?

Floating point numbers are stored in binary with rounding, so the two values have slightly different bit representations even though they are mathematically equal.

What should you use for money?

An exact type, such as integers in the smallest currency unit or a decimal type, rather than a float.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.