Skip to content

VNX-1339: Insufficient Precision or Accuracy of a Real Number

Reports exact equality or inequality comparisons (==, !=, ===, !==) with a decimal literal that binary floating point cannot represent exactly (0.1, 0.3, 19.99f) in Python, JavaScript/TypeScript, Java and Go. Exact literals (0.5, 1.0), tolerance comparisons, ordering comparisons, strings and test files are not reported.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-1339
Severity Low
SARIF level note
Kind sast
Languages Python, JavaScript / TypeScript, Java, Go
CWE CWE-1339
CAPEC CAPEC-66
ATT&CK T1190
CWSS vector CWSS:1.0/TI:L/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:L/DI:H/EX:L/EC:N/P:L
Tags float-precision floating-point correctness cwe-1339
Source internal/sast/rules/vnx-1339.rego

Overview

VNX-1339 maps to CWE-1339: Insufficient Precision or Accuracy of a Real Number. Most decimal fractions (0.1, 0.3, 19.99) have no exact binary floating-point representation. A computed value is almost never bit-identical to the rounded literal, so total == 0.3 is false for 0.1 + 0.2, and a branch guarded that way silently never runs (or a != loop never ends).

Why This Matters

Exact float comparisons in prices, discounts, rates and balances produce wrong totals, skipped promotions and infinite loops. In financial or safety logic the error is a correctness bug that an attacker can sometimes steer by choosing amounts.

What Gets Flagged

if total == 0.3:              # FLAGGED
while balance != 0.1:         # FLAGGED
if 0.7 == ratio:              # FLAGGED
if (sum === 0.3) { ... }      // FLAGGED
if (rate == 0.05) { ... }     // FLAGGED
return amount != 19.99f;      // FLAGGED
if price*0.9 == 8.99 { ... }  // FLAGGED

What Is Not Flagged

  • Literals that are exact in binary: 0.5, 0.25, 0.125, 1.0, 0.0, 2.75.
  • Exponent forms (1e-3), ordering comparisons (<, <=, >, >=).
  • Comparisons through a tolerance: math.isclose, pytest.approx, toBeCloseTo, assertAlmostEqual, abs(a - b) < eps.
  • Strings (versions, IP addresses), comments and test files.
  • Operand types are not known, so an integer variable compared with a fractional literal is also reported.

Remediation

  1. Compare with a tolerance: math.isclose(a, b, rel_tol=1e-9), Math.abs(a - b) < EPS.
  2. For money, use a decimal type (decimal.Decimal, BigDecimal) or integer minor units (cents).

References

Suppressing this rule

Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):

# nosec vnx-1339
// nosec vnx-1339

Or record an ignore rule: vulnetix ignore add --rule vnx-1339 --reason "...". See Suppressing findings.

Edit this pageSources: cli/internal/sast/rules/vnx-1339.rego, cli/internal/sast/docs/vnx-1339.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.