Numeric Literal Loses Precision

ID

javascript.no_loss_of_precision

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

JavaScript

Tags

reliability, suspicious-comparison

Description

Reports numeric literals that cannot be represented exactly as a JavaScript Number (IEEE 754 double precision) and therefore parse to a different value than the source text shows.

Rationale

Number in JavaScript is a 64-bit double. Integers above 2 ** 53 (Number.MAX_SAFE_INTEGER = 9007199254740991) and decimals with more than ~17 significant digits cannot be stored exactly. The runtime silently rounds the literal to the nearest representable double, which means a literal like 9007199254740993 ends up equal to 9007199254740992 — the visual constant in the source no longer matches the runtime value.

const a = 9007199254740993;        // becomes 9007199254740992
const b = 5123000000000000000;     // becomes 5.123e18 with low-bit rounding
const c = 0.1234567890123456789;   // tail digits silently dropped

Remediation

  • If the value fits in 64-bit but not in a double, use a BigInt literal: 9007199254740993n.

  • If the value must be a regular Number and the precision-loss is acceptable, split or compute it at runtime so the source code does not carry a misleading constant.

// Good
const safe = 9007199254740991;
const big = 9007199254740993n;