Changes after review
This commit is contained in:
parent
04b21f522c
commit
d7a148016e
@ -1,6 +1,6 @@
|
||||
== 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.
|
||||
Numbers in JavaScript are stored in https://en.wikipedia.org/wiki/Double-precision_floating-point_format[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:
|
||||
|
||||
@ -23,7 +23,7 @@ However, because the 52 bits of the significand, only integers between -(2^53^ -
|
||||
|
||||
[source,javascript]
|
||||
----
|
||||
Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2; //true
|
||||
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.
|
||||
@ -32,41 +32,50 @@ JavaScript provides the `BigInt` primitive to represent values which are too lar
|
||||
[source,javascript]
|
||||
----
|
||||
const myBigInt = BigInt(Number.MAX_SAFE_INTEGER);
|
||||
myBigInt + 1n === myBigInt + 2n; //false
|
||||
myBigInt + 1n === myBigInt + 2n; // false
|
||||
----
|
||||
|
||||
|
||||
== How to fix it
|
||||
|
||||
=== Magnitude
|
||||
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` can be compared between them as usual, but pay attention that operations (`+` `pass:[*]` `-` `%` `pass:[**]`) between both types raise an error unless they are converted to the same type, so you will have to adapt your code accordingly. Use the `BigInt` and `Number` constructors to convert between both types:
|
||||
|
||||
[source,javascript]
|
||||
----
|
||||
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.
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
[source,javascript]
|
||||
----
|
||||
const foo = 2312123211345545367 // Noncompliant: will be stored as 2312123211345545000
|
||||
const bar = BigInt(2312123211345545367); // Noncompliant: parameter is first parsed as an integer and thus rounded
|
||||
const baz = 0.123456789123456789 // Noncompliant: will be stored as 0.12345678912345678
|
||||
----
|
||||
|
||||
Instead, these could be used:
|
||||
==== Compliant solution
|
||||
|
||||
[source,javascript]
|
||||
----
|
||||
const foo = BigInt('2312123211345545367');
|
||||
// OR
|
||||
const bar = 2312123211345545367n;
|
||||
----
|
||||
|
||||
=== Precision
|
||||
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
|
||||
[source,javascript]
|
||||
----
|
||||
const baz = 0.123456789123456789 // Noncompliant: will be stored as 0.12345678912345678
|
||||
----
|
||||
==== Compliant solution
|
||||
[source,javascript]
|
||||
----
|
||||
// use a library like decimal.js for storing numbers containing many decimal digits
|
||||
import { Decimal } from 'decimal.js';
|
||||
const bar = new Decimal('0.123456789123456789');
|
||||
@ -82,8 +91,8 @@ const bar = new Decimal('0.123456789123456789');
|
||||
|
||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number#number_encoding[MDN - Number encoding]
|
||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt[MDN - BigInt]
|
||||
* https://en.wikipedia.org/wiki/Double-precision_floating-point_format[Wikipedia Double-precision floating-point format]
|
||||
* https://en.wikipedia.org/wiki/IEEE_754[Wikipedia IEEE 754 Standard]
|
||||
* https://en.wikipedia.org/wiki/Double-precision_floating-point_format[Wikipedia - Double-precision floating-point format]
|
||||
* https://en.wikipedia.org/wiki/IEEE_754[Wikipedia - IEEE 754 Standard]
|
||||
//=== Articles & blog posts
|
||||
//=== Conference presentations
|
||||
//=== Standards
|
||||
|
Loading…
x
Reference in New Issue
Block a user