Math.log2()
Returns the base 2 logarithm of a number — how many doublings it takes to reach it.
Math.log2(x)- Added in JavaScript ES2015
Parameters
| Parameter | Type | Description |
|---|---|---|
$x | number | A number greater than or equal to 0. |
Return value
numberThe base 2 logarithm of x. Returns -Infinity if x is ±0, NaN if x < 0, and Infinity if x is Infinity.
Math.log2(x) returns the power of 2 that produces x. Practically, it counts doublings: how many times a value must halve to reach 1, how many bits a number needs, how deep a balanced binary tree gets.
When to reach for it
Bit width comes first: Math.ceil(Math.log2(n)) is the number of bits needed to hold values 0…n-1. It is also the natural unit for information theory — Shannon entropy in bits is -Σ p·log2(p). Binary search depth, octave ratios in audio, and complexity estimates for divide-and-conquer algorithms all read naturally in base 2.
What trips people up
The spec permits an implementation-approximated result, so Math.log2() is not guaranteed exact even on exact powers of two. Engines return a clean 10 for Math.log2(1024) in practice, but larger or computed inputs can land a hair below the integer, and Math.floor() then reports one bit too few. When correctness matters, round and verify, or for 32-bit integers use 31 - Math.clz32(n), which is exact by construction.
The usual logarithm edges apply: 0 gives -Infinity and negatives give NaN, neither of which throws.
Example
When to use it
- Find how many bits are needed to represent a range of values
- Compute Shannon entropy in bits for a probability distribution
- Estimate the depth of a binary search or balanced tree
- Convert a frequency ratio into musical octaves
Frequently asked questions
How do I count the bits needed for a number in JavaScript?
Use Math.ceil(Math.log2(n)) for n distinct values, or Math.floor(Math.log2(n)) + 1 for the bit length of a positive integer n. For 32-bit integers, 32 - Math.clz32(n) gives the same answer exactly, without the floating-point approximation log2 is permitted.
Is Math.log2() the same as Math.log(x) / Math.LN2?
They agree to within a rounding step but are not identical. Math.log2() is a single operation, while the division compounds two rounded results, so the divided form is more likely to fall just below an exact integer on powers of two.
Why does Math.log2() return -Infinity for 0?
No power of 2 produces 0, so the logarithm diverges toward negative infinity as the input approaches zero, and IEEE 754 defines the result as -Infinity rather than an error. Guard entropy and size calculations against zero inputs.
More examples
Shannon entropy in bits
A fair coin carries exactly 1 bit, four equally likely outcomes carry 2, and the skewed three-way split lands at 1.5. A certain outcome gives 0 — though note that a probability of 0 in the list would produce NaN and needs filtering out.
function entropy(probabilities) {
return -probabilities.reduce((sum, p) => sum + p * Math.log2(p), 0);
}
console.log(entropy([0.5, 0.5])); // one fair coin
console.log(entropy([0.5, 0.25, 0.25]));
console.log(entropy([0.25, 0.25, 0.25, 0.25]));
console.log(entropy([1])); // no uncertaintyExact bit length
Both columns agree here, but only the clz32 version is guaranteed: Math.log2() may be approximated, so the floor-based form can slip a bit low on some engines or inputs. Use clz32 for 32-bit integers and reserve log2 for continuous quantities.
const viaLog = (n) => Math.floor(Math.log2(n)) + 1;
const viaClz = (n) => 32 - Math.clz32(n);
for (const n of [1, 255, 256, 4294967295]) {
console.log(n, viaLog(n), viaClz(n));
}Edge cases
Values below 1 give negative logs — 0.5 is one halving, so -1. Zero collapses to -Infinity and negative inputs to NaN without an exception, so filter probability or size values before feeding them in.
console.log(Math.log2(1));
console.log(Math.log2(0)); // -Infinity
console.log(Math.log2(-0)); // -Infinity
console.log(Math.log2(-2)); // NaN
console.log(Math.log2(0.5)); // -1
console.log(Math.log2(Infinity));
Discussion