JavaScript Numbers and Math
In JavaScript, there is only one number type: Number. Whether it's an integer or a decimal, it's all Number. This is different from languages like Java or C that distinguish between int, float, and so on. Simpler, yes — but it comes with a few gotchas.
Number Type
In JavaScript, both integers and floating-point numbers are the Number type — there is no separate integer type.
<script>
let a = 42; // This is a Number
let b = 3.14; // This is also a Number
typeof a; // "number"
typeof b; // "number"
</script>
Numbers can also be written in several other formats:
<script>
let hex = 0xFF; // Hexadecimal, equals 255
let octal = 0o10; // Octal, equals 8
let binary = 0b1010; // Binary, equals 10
let big = 1e6; // Scientific notation, equals 1000000
</script>
NaN and Infinity
NaN stands for "Not a Number," yet it is of type Number — one of JavaScript's most ironic design choices.
<script>
typeof NaN; // "number" ← That's right, it's actually a number
NaN === NaN; // false ← It's not even equal to itself!
Number.isNaN(NaN); // true ← Use this method to check for NaN
</script>
When does NaN appear? When you try to do math with something that isn't a number:
<script>
parseInt('abc'); // NaN
'hello' * 5; // NaN
Math.sqrt(-1); // NaN
</script>
Infinity represents positive infinity and appears when dividing by zero:
<script>
1 / 0; // Infinity
-1 / 0; // -Infinity
typeof Infinity; // "number"
</script>
=== — use Number.isNaN(). Since NaN === NaN is false, this is a trap that has caught countless developers.
Floating-Point Precision
This is JavaScript's most famous quirk: 0.1 + 0.2 !== 0.3.
<script>
0.1 + 0.2; // 0.30000000000000004
0.1 + 0.2 === 0.3; // false
</script>
The reason is related to how computers store floating-point numbers in binary. The value 0.1 is a repeating fraction in binary, leading to precision loss during storage. This isn't unique to JavaScript — all languages using the IEEE 754 standard have this issue.
The fix: use toFixed() for formatting, or scale up before computing:
<script>
(0.1 + 0.2).toFixed(2); // "0.30"
(0.1 * 100 + 0.2 * 100) / 100; // 0.3
</script>
Example: Precision Issues Demo
<!DOCTYPE html>
<html>
<body>
<h2>Floating-Point Precision Issues</h2>
<p id="output"></p>
<script>
let html = '';
html += '0.1 + 0.2 = ' + (0.1 + 0.2) + '<br>';
html += '0.1 + 0.2 === 0.3 ? ' + (0.1 + 0.2 === 0.3) + '<br><br>';
html += '<strong>Fix 1: toFixed</strong><br>';
html += '(0.1 + 0.2).toFixed(2) = ' + (0.1 + 0.2).toFixed(2) + '<br><br>';
html += '<strong>Fix 2: Scale up then down</strong><br>';
html += '(0.1*100 + 0.2*100)/100 = ' + ((0.1 * 100 + 0.2 * 100) / 100) + '<br><br>';
html += '<strong>NaN related:</strong><br>';
html += 'parseInt("abc") = ' + parseInt('abc') + '<br>';
html += 'NaN === NaN ? ' + (NaN === NaN) + '<br>';
html += 'Number.isNaN(NaN) ? ' + Number.isNaN(NaN) + '<br><br>';
html += '<strong>Infinity related:</strong><br>';
html += '1 / 0 = ' + (1 / 0) + '<br>';
html += 'typeof Infinity = ' + typeof Infinity;
document.getElementById('output').innerHTML = html;
</script>
</body>
</html>
The Math Object
Math is JavaScript's built-in math utility. No instantiation needed — just call its methods directly:
| Method/Property | Purpose | Example |
|---|---|---|
Math.round() |
Round to nearest integer | Math.round(4.6) → 5 |
Math.floor() |
Round down | Math.floor(4.9) → 4 |
Math.ceil() |
Round up | Math.ceil(4.1) → 5 |
Math.random() |
Random number 0–1 | Math.random() → 0.3721... |
Math.max() |
Maximum value | Math.max(1,5,3) → 5 |
Math.min() |
Minimum value | Math.min(1,5,3) → 1 |
Math.PI |
Pi | 3.141592653589793 |
Math.abs() |
Absolute value | Math.abs(-7) → 7 |
Math.pow() |
Exponentiation | Math.pow(2,3) → 8 |
Math.sqrt() |
Square root | Math.sqrt(16) → 4 |
Example: Common Math Methods
<!DOCTYPE html>
<html>
<body>
<h2>Math Object Methods</h2>
<p id="output"></p>
<script>
let html = '';
html += 'Math.round(4.6) = ' + Math.round(4.6) + '<br>';
html += 'Math.round(4.4) = ' + Math.round(4.4) + '<br>';
html += 'Math.floor(4.9) = ' + Math.floor(4.9) + '<br>';
html += 'Math.ceil(4.1) = ' + Math.ceil(4.1) + '<br>';
html += 'Math.abs(-7) = ' + Math.abs(-7) + '<br>';
html += 'Math.pow(2, 10) = ' + Math.pow(2, 10) + '<br>';
html += 'Math.sqrt(144) = ' + Math.sqrt(144) + '<br>';
html += 'Math.max(1, 5, 3) = ' + Math.max(1, 5, 3) + '<br>';
html += 'Math.min(1, 5, 3) = ' + Math.min(1, 5, 3) + '<br>';
html += 'Math.PI = ' + Math.PI + '<br>';
let radius = 5;
let area = Math.PI * Math.pow(radius, 2);
html += `Area of circle with radius ${radius} = ${area.toFixed(2)}`;
document.getElementById('output').innerHTML = html;
</script>
</body>
</html>
Math.round(-1.5) returns -1, not -2. Rounding behavior at the negative boundary may not match your intuition — keep this in mind.
toFixed() — Formatting Decimals
toFixed(n) formats a number to n decimal places and returns a string:
<script>
let price = 9.9;
price.toFixed(2); // "9.90" ← Note: returns a string
+(9.9).toFixed(2); // 9.9 ← Use + to convert back to a number
</script>
toFixed returns a string! If you need to do further math with it, remember to convert it back to a number.
toString() — Base Conversion
The number method toString(radix) converts a number to a string in the specified base:
<script>
(255).toString(16); // "ff" hexadecimal
(255).toString(2); // "11111111" binary
(255).toString(8); // "377" octal
(100).toString(); // "100" decimal (default)
</script>
Example: Base Conversion
<!DOCTYPE html>
<html>
<body>
<h2>Base Conversion</h2>
<p id="output"></p>
<script>
let num = 255;
let html = `Number ${num} in different bases:<br><br>`;
html += `Decimal: ${num.toString()}<br>`;
html += `Binary: ${num.toString(2)}<br>`;
html += `Octal: ${num.toString(8)}<br>`;
html += `Hexadecimal: ${num.toString(16)}<br><br>`;
let price = 19.9;
html += `Price formatted: $${price.toFixed(2)}<br>`;
html += `toFixed return type: ${typeof price.toFixed(2)}<br>`;
document.getElementById('output').innerHTML = html;
</script>
</body>
</html>
Math.random() — Generating Random Numbers
Math.random() returns a random floating-point number between 0 (inclusive) and 1 (exclusive). In practice, you often need a random integer within a specific range:
<script>
// Generate a random integer between min and max (inclusive)
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
</script>
Example: Random Number Demo
<!DOCTYPE html>
<html>
<body>
<h2>Random Number Generator</h2>
<button onclick="rollDice()">Roll Dice</button>
<button onclick="pickLotto()">Pick Numbers (1-35)</button>
<p id="output"></p>
<script>
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function rollDice() {
let dice = getRandomInt(1, 6);
let dots = '';
for (let i = 0; i < dice; i++) {
dots += ' ⚀';
}
document.getElementById('output').innerHTML =
`You rolled <strong>${dice}</strong>${dots}`;
}
function pickLotto() {
let numbers = [];
while (numbers.length < 5) {
let n = getRandomInt(1, 35);
if (!numbers.includes(n)) {
numbers.push(n);
}
}
numbers.sort((a, b) => a - b);
document.getElementById('output').innerHTML =
`Your lucky numbers: <strong>${numbers.join(' ')}</strong>`;
}
</script>
</body>
</html>
Math.random() produces pseudo-random numbers and is not suitable for cryptographic purposes. For cryptographically secure randomness, use crypto.getRandomValues().
📖 Summary
- JavaScript has only one
Numbertype — both integers and decimals are Number NaNis not equal to any value (including itself); useNumber.isNaN()to detect it0.1 + 0.2 !== 0.3is a precision issue; fix it withtoFixed()or by scaling up and downMath.floorrounds down,Math.ceilrounds up,Math.roundrounds to the nearest integer- Formula for a random integer:
Math.floor(Math.random() * (max - min + 1)) + min toFixed()returns a string — convert it back to a number if you need to do further math
❓ FAQ
Math.round(2.5) and Math.round(-2.5) respectively?Math.round(2.5) is 3, and Math.round(-2.5) is -2. When the decimal is exactly .5, JavaScript rounds toward positive infinity — so both positive and negative numbers round up (closer to 0).Number.isFinite(value). It excludes NaN, Infinity, and -Infinity, and also rejects non-number types. The global isFinite() works too but doesn't check the type (it coerces first).parseInt and Number()?parseInt('12abc') returns 12 — it parses left to right until it can't continue. Number('12abc') returns NaN — the entire string must be a valid number. Use parseInt for lenient parsing and Number() for strict conversion.📝 Exercises
- Write a program that takes a circle's radius as input, calculates its area and circumference, and displays the results rounded to 2 decimal places.
- Write a number guessing game: the program randomly generates an integer between 1 and 100, the user enters guesses, and the program responds with "Too high" or "Too low" until the correct answer is found.
- Write a base converter: input a decimal number and simultaneously display its binary, octal, and hexadecimal equivalents.



