log1p()
log1p(x) The log1p() function computes log(1 + x), the natural logarithm of one plus the input. It is more accurate than log(1 + x) when x is very small.
Syntax
log1p(x)
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
x | numeric | , | A numeric vector or scalar |
The argument x is typically a numeric vector, though log1p() will attempt to coerce other types. The function is vectorized, so log1p(c(0.001, 0.01, 0.1)) computes the result for each element and returns a numeric vector of the same length. Inputs below -1 produce NaN with a warning, while log1p(-1) returns -Inf as the limit approaches negative infinity.
Examples
Basic usage
# log1p(0) = log(1) = 0
log1p(0)
# [1] 0
# log1p(1) = log(2)
log1p(1)
# [1] 0.6931472
# For very small values, log1p is more accurate
x <- 1e-10
log(1 + x)
# [1] 0
log1p(x)
# [1] 1e-10
These examples show how log1p() preserves precision when x is extremely small. For values like 1e-10, the floating-point representation of 1 + 1e-10 is indistinguishable from 1.0 in double precision, so log(1 + 1e-10) incorrectly returns zero. log1p() avoids forming the intermediate sum entirely, computing the result through a series expansion that retains full accuracy.
Numerical stability demonstration
# When x is very small, log(1 + x) loses precision
x <- 1e-15
log(1 + x)
# [1] 0 # precision lost!
log1p(x)
# [1] 1e-15 # accurate
# Relative error comparison
x <- 1e-8
(log(1 + x) - x) / x # relative error in log()
# [1] -5.000001e-08
(log1p(x) - x) / x # relative error in log1p()
# [1] 0
The relative error comparison demonstrates why log1p() matters in practice. When x = 1e-8, the naive log(1 + x) introduces a relative error of about 5e-8, while log1p() produces the exact result within floating-point limits. This error accumulates quickly in iterative algorithms or when summing many small log-likelihood terms in statistical estimation.
Common patterns
Statistical calculations
# Log-likelihood with small probabilities
p <- 1e-10
log(p + 1) # loses precision
log1p(p) # accurate
# Geometric mean for values near 1
x <- c(1.001, 1.002, 1.003)
exp(mean(log1p(x - 1)))
# [1] 1.002
The geometric mean calculation using log1p() is a common numerical trick. By subtracting 1 from each value, applying log1p(), taking the mean, and exponentiating, you compute the geometric mean with full precision even when all values are extremely close to 1. The same approach works for any statistic that transforms values near 1 into log-space for stable computation, including geometric standard deviations and confidence intervals.
Financial calculations
# Continuous compounding for small rates
rate <- 0.0001
time <- 1
log1p(rate * time)
# [1] 0.000099995
Continuously compounded returns for small interest rates are naturally expressed as log1p(rate * time). In quantitative finance, daily returns are often close to zero, and compounding them over long horizons accumulates floating-point error if log(1 + r) is used. log1p() keeps the computation accurate across thousands of compounding periods, which matters for pricing derivatives and calculating value-at-risk with high precision.
Why log1p() exists
log1p(x) computes log(1 + x) with better numerical precision than calling log(1 + x) directly. When x is very small (close to zero), 1 + x rounds to 1 in floating point, and log(1) returns exactly zero, losing all information about x. log1p() avoids this by computing the result directly without forming the intermediate 1 + x.
This matters in statistical contexts where probabilities or rates are small. In survival analysis, hazard rates near zero; in Bayesian updating with sparse data, log-likelihoods involving small counts; in financial computing, continuously compounded returns for small interest rates, all benefit from log1p() precision.
The inverse of log1p() is expm1(): expm1(log1p(x)) == x (within floating-point precision). Using the pair together is a standard pattern for numerically stable computation in log-space.
log1p() is a C primitive that is faster and more accurate than log(1 + x). The precision advantage is largest when x is close to zero: for x = 1e-15, log(1 + x) returns exactly zero (because 1 + 1e-15 == 1 in double precision), while log1p(1e-15) returns approximately 9.99e-16 — the correct answer. This matters in any application where you compute logarithms of quantities slightly larger than 1.
In data transformation for machine learning, log1p() is commonly used to normalize right-skewed count data that includes zeros. log(x + 1) and log1p(x) are equivalent in most contexts, but log1p() is both more explicit and more accurate. The back-transformation expm1(y) recovers the original scale after predictions are made on the log1p-transformed scale, since expm1() is the exact mathematical inverse of log1p() within the limits of 64-bit double-precision floating-point arithmetic.
The accuracy improvement is most pronounced for x values smaller than about 0.001. For larger x, both log(1 + x) and log1p(x) produce nearly identical results, so log1p() is safe to use everywhere without conditionals.
log1p(x) computes log(1 + x) with greater precision than the naive expression for small x. When x is close to zero, log(1 + x) loses significant digits because 1 + x rounds to 1 in floating-point arithmetic. log1p() avoids this by computing the result directly. Its complement is expm1(). Use log1p() in financial or probabilistic calculations involving small changes.