All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.l10n.javascript.rules.javascript.S6534.html Maven / Gradle / Ivy

There is a newer version: 5.0.0.6962
Show newest version

Why is this an issue?

Numbers in JavaScript are stored in double-precision 64-bit binary format IEEE 754. Like any other number encoding occupying a finite number of bits, it is unable to represent all numbers.

The values are stored using 64 bits in the following form:

  • 1 bit for the sign (positive or negative)
  • 11 bits for the exponent (2n). -1022 ≤ n ≤ 1023
  • 52 bits for the significand (or mantissa)

The actual value of the stored number will be (-1)sign * (1 + significand) * 2 exponent

Given this structure, there are limits in both magnitude and precision.

Due to the 52 bits used for the significand, any arithmetic in need of more precision than 2-52 (provided by Number.EPSILON) is subject to rounding.

In terms of magnitude, the largest number the 64 bits of the format can store is 21024 - 1 (Number.MAX_VALUE).

However, because the 52 bits of the significand, only integers between -(253 - 1) (Number.MIN_SAFE_INTEGER) and 253 - 1 (Number.MAX_SAFE_INTEGER) can be represented exactly and be properly compared.

Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2;  // true

JavaScript provides the bigint primitive to represent values which are too large to be represented by the number primitive. BigInts are created by appending n to the end of an integer literal, or by calling the BigInt() function (without the new operator), with an integer or a string.

const myBigInt = BigInt(Number.MAX_SAFE_INTEGER);
myBigInt + 1n === myBigInt + 2n;  // false

How to fix it

For large numbers, JavaScript provides the helper function Number.isSafeInteger() to test if a number is between the safe limits.

When you need to store a large number, use BigInt. bigint and number primitives can be compared between them as usual (e.g. >, ==), but pay attention that arithmetic operations (+ * - % **) between both types raise an error unless they are converted to the same type. Use the BigInt and Number functions to convert between both types:

const myNumber = Number(myBigInt);
const myBigInt = BigInt(myNumber);

Be careful converting values back and forth, however, as the precision of a bigint value may be lost when it is coerced to a number value.

Code examples

Noncompliant code example

const foo = 2312123211345545367  // Noncompliant: will be stored as 2312123211345545000
const bar = BigInt(2312123211345545367);  // Noncompliant: parameter is first parsed as an integer and thus rounded

Compliant solution

const foo = BigInt('2312123211345545367');
const bar = 2312123211345545367n;

When in need of more decimal precision, it is recommended to use a dedicated library to ensure that calculation errors are not introduced by rounding.

Noncompliant code example

const baz = 0.123456789123456789 // Noncompliant: will be stored as 0.12345678912345678

Compliant solution

// use a library like decimal.js for storing numbers containing many decimal digits
import { Decimal } from 'decimal.js';
const bar = new Decimal('0.123456789123456789');

Resources

Documentation





© 2015 - 2025 Weber Informatics LLC | Privacy Policy