The huge, the tiny, and the (sometimes) ugly:
Javascript Numbers
Murray Bourne
BrisJS :: 4 Aug 2025
The motivation (1)
- Sketch the graph of y = f(x)
-
x 0 1 2 3 4 5 6 7 8 9 10 y
The motivation (2)
- I wanted better plots for some challenging functions
- Existing plotters have issues:
- JSXGraph
- Desmos and Wolfram|Alpha
- Mathway:

The motivation (3)
- We want to animate graphs efficiently
- We want to minimise data points, calculations
- We want to "plot to infinity"
- Improved versions: ASVG
Function:
-
i x tan(x) - m =
- d =
Stumbling blocks (1)
-
expression JS output
Stumbling blocks (2)
- Max. significant digits in JS numbers:
- 17, because:
- IEEE 754 double-precision binary floating-point format: binary64
- Largest safe integer:
- = 253 − 1 = 9,007,199,254,740,991
- Largest possible number:
- = (253 − 1)*2971 ≈ 1.7976931348623157e308
Big integers
- 20-digit number: use
BigInt(introduced 2020) -
expression JS output
Large numbers summary (+ve)
- Number.MAX_SAFE_INTEGER (253 − 1 ≈ 9e15) is the largest "safe" integer
- (positive)
- Number.MAX_VALUE (≈1.8e308) is the largest possible distinct number
- BigInt is for integers that are larger than the
Numberprimitive can handle. Uses suffix "n", e.g.123456789012345678901n - Infinity is larger than any other number in Javascript
Small numbers
- Beware the "Sometimes works, sometimes not" cases...
Adding decimals (1)
Adding decimals (2)
- How about
x == 0.4?
Adding decimals (PHP)
- Using PHP:
<?php for($x=0; $x<1.5; $x += 0.2) { echo "x = $x \n"; if($x == 0.6) { break; } } ?>-
x = 0
x = 0.2
x = 0.4
x = 0.6
x = 0.8
x = 1
x = 1.2
x = 1.4
- (Displays the floats OK, but misses the equality test)
Small numbers
- Smallest positive number:
Number.MIN_VALUE= 2−1074 = 5e-324- Somewhat useless(?), as:
5 + Number.MIN_VALUE = 5- In fact:
5 + 9e307 * Number.MIN_VALUE = 5.000000000000001
More useful: EPSILON (ε)
Number.EPSILON= 2−52 ≈ 2.22e-16- Reason: 52 bits to represent the mantissa
- Represents the smallest representable number near 1
1 + Number.EPSILON = 1.0000000000000002- But:
5 + Number.EPSILON = 5- Reason: Exponent is bigger, so accuracy lower
Number.EPSILON
- Solution:
- Multiply by the number you're comparing:
5 + 5 * Number.EPSILON = 5.000000000000001- Use as:
let x = 200.1, y = 200.2, z = 400.3;x + y == z// output: falseif( Math.abs(x + y - z) < 400 * Number.EPSILON) { console.log("yeah"); } else { console.log("nah") }// output: yeah (equal)
Small numbers summary (+ve)
- Number.MIN_VALUE (2−1074 − 1 = 5e-324) is the smallest possible positive number (useless)
Number.EPSILON= 2−52 ≈ 2.22e-16 indicates accuracy of 12 + 2*Number.EPSILONfor numbers near 2
Calculating π using BigInt (1)
Calculating π using BigInt (2)
- This uses:
- BigInt
- A spigot algorithm, based on Johann Lambert's continued fraction expression for π (pub. 1770):
- $$\pi = \frac{4}{1+\frac{1^2}{3+\frac{2^2}{5+\frac{3^2}{7+\dots}}}}$$
Overall summary
Stuff I learned:
- Be sceptical of Javascript numerical output
- Javascript numbers don't always follow actual mathematical principles
- Beware the "it mostly works" trap
- Throwing more data points at a problem is not always the best solution for accuracy or usability ^_^
Quiz
Ques expression JS output T or F? T or F? Value? Value? Value? Value? Value? Value? Output?
The end
Thank you!
@bourne2learn