Math.exp()
Returns e raised to the power of a number, the inverse of the natural logarithm.
Math.exp(x)- Added in JavaScript ES1
Parameters
| Parameter | Type | Description |
|---|---|---|
$x | number | A number: the exponent that e is raised to. |
Return value
numberA nonnegative number representing e^x, where e is the base of the natural logarithm (about 2.718). Returns 0 for -Infinity, 1 for 0, Infinity for Infinity, and NaN for NaN.
Math.exp(x) returns ex. It is the inverse of Math.log(): Math.exp(Math.log(v)) recovers v for any positive v, give or take a rounding step.
When to reach for it
Any continuous growth or decay model is written in terms of e. Radioactive decay, compound interest at a continuous rate, exponential smoothing, temperature cooling, and the softmax and sigmoid functions of machine learning all evaluate Math.exp() at some scaled input. If your rate is quoted per period rather than continuously, convert it once with Math.log() instead of calling Math.exp() on the wrong constant.
What trips people up
The result grows brutally fast. Math.exp(710) is already Infinity, because doubles top out near 1.8e308, and Math.exp(-746) flushes to 0. Sigmoid and softmax implementations must subtract the maximum input before exponentiating or they overflow on perfectly ordinary logits.
At the other end, for x very close to 0 the result is very close to 1, and the interesting fractional part is destroyed by the leading digit. Math.exp(x) - 1 loses most of its significant digits there; Math.expm1(x) computes the same quantity accurately.
Example
When to use it
- Model radioactive or exponential decay from a half-life
- Compute a sigmoid activation: 1 / (1 + Math.exp(-x))
- Convert a continuously compounded rate into a growth factor
- Apply exponential smoothing weights to a time series
Frequently asked questions
What is the difference between Math.exp(x) and Math.E ** x?
Math.exp(x) is more accurate. Math.E ** x first rounds e to a double and then raises it, compounding two rounding errors, while Math.exp() is implemented as a single operation on the exponent. The results usually differ only in the last digit or two, but Math.exp() is the correct choice.
Why does Math.exp() return Infinity?
Math.exp() returns Infinity for any argument above about 709.78, because e raised to that power exceeds the largest finite double (roughly 1.8e308). In softmax and sigmoid code, subtract the maximum input from every value before exponentiating to keep the arguments in range.
When should I use Math.expm1() instead of Math.exp()?
Use Math.expm1(x) whenever you need Math.exp(x) - 1 and x is close to 0. The subtraction cancels the leading 1 and discards most significant digits, so Math.exp(1e-10) - 1 is accurate to only a few digits while Math.expm1(1e-10) is accurate to full precision.
More examples
Overflow and the softmax fix
Math.exp(710) is Infinity. Subtracting the maximum logit first leaves the probabilities unchanged but keeps every exponent at or below 0, so the shifted call returns the same distribution for inputs a thousand times larger.
console.log(Math.exp(709));
console.log(Math.exp(710)); // overflows
function softmax(logits) {
const max = Math.max(...logits);
const exps = logits.map((v) => Math.exp(v - max));
const sum = exps.reduce((a, b) => a + b, 0);
return exps.map((v) => v / sum);
}
console.log(softmax([1, 2, 3]));
console.log(softmax([1001, 1002, 1003])); // same answer, no InfinityPrecision near zero
Math.exp(1e-10) - 1 prints 1.000000082740371e-10 against the accurate 1.00000000005e-10 from Math.expm1() — the leading 1 has already eaten the low-order digits. At 1e-20 the subtraction returns a flat 0 while expm1 still reports 1e-20.
const x = 1e-10;
console.log(Math.exp(x) - 1);
console.log(Math.expm1(x));
console.log(Math.exp(1e-20) - 1); // lost entirely
console.log(Math.expm1(1e-20));exp and log are inverses
Round-tripping through log and exp returns each input, though not always bit for bit: 0.5, 1 and 42 come back exactly, while 1e6 returns as 999999.9999999995 because each step rounds to the nearest double. Use the ** operator when the base is known; exp/log is for continuous rates.
const values = [0.5, 1, 42, 1e6];
for (const v of values) {
console.log(v, Math.exp(Math.log(v)));
}
console.log(Math.exp(Math.log(2) * 10)); // 2 ** 10, the long way
console.log(2 ** 10);
Discussion