Numeric functions

log#

Return the natural logarithm (base e) of a number.

log is the inverse of exp. It takes a numeric EXPR, coerces it to a double-precision float if necessary, and returns its logarithm to the base e (Euler’s number, approximately 2.718281828459045). If EXPR is omitted, log operates on $_.

There is no built-in for logarithms to an arbitrary base — use basic algebra (see the examples below) or POSIX::log10 / POSIX::log2 for the two common fixed bases.

Synopsis#

log EXPR
log

What you get back#

A double-precision float: the natural logarithm of EXPR. Concretely:

  • log(1) is 0.

  • log(exp(1)) is 1 (the defining identity).

  • log(x) is strictly increasing for x > 0.

Special inputs follow IEEE-754 rules as provided by the platform C library’s log(3):

  • log(0) returns negative infinity (-Inf).

  • log(x) for x < 0 returns NaN.

  • log(Inf) returns Inf; log(NaN) returns NaN.

The result is always a float, even when the input is an integer or a string.

Examples#

The defining identity — the natural log of e is 1:

use POSIX ();
print log(exp(1)), "\n";            # 1

A base-10 logarithm, built from log by change of base. The base-N log of a number equals its natural log divided by the natural log of N:

sub log10 {
    my ($n) = @_;
    return log($n) / log(10);
}

print log10(1000), "\n";            # 3
print log10(0.01), "\n";            # -2

The same idiom generalised to any base — useful for bits (base 2), decibels (base 10), or anything else:

sub log_base {
    my ($base, $n) = @_;
    return log($n) / log($base);
}

print log_base(2, 1024), "\n";      # 10
print log_base(16, 65536), "\n";    # 4

Operating on $_ — handy inside map or a while line loop:

my @natural_logs = map { log } 1, 2, 3, 4;

Numeric coercion of a string argument — log evaluates its operand in numeric context just like the arithmetic operators:

print log("7.389056"), "\n";        # ~2 (log of e^2, give or take)

Edge cases#

  • log(0) is -Inf, not an error and not a division-by-zero exception. Perl does not die; you get a float infinity back and any further arithmetic propagates it:

    my $x = log(0);                   # -Inf
    print $x + 1, "\n";               # -Inf
    
  • log of a negative number is NaN. Again, no exception — the caller is responsible for range-checking if that matters:

    my $x = log(-1);                  # NaN
    print $x == $x ? "num" : "nan", "\n";   # nan (NaN != NaN)
    

    Guard the input if you need a defined result:

    die "log domain error" unless $n > 0;
    my $l = log($n);
    
  • Non-numeric strings coerce to 0 and therefore produce -Inf, and under use warnings trigger Argument "..." isn't numeric:

    use warnings;
    print log("hello"), "\n";         # -Inf, with warning
    
  • No argument form uses $_. log with an empty argument list reads the current topic; inside map { log } or while (<>) { print log; } this is the usual shortcut.

  • Integer vs float input makes no difference to the result type: the return value is always a float. log(2) and log(2.0) are the same value.

  • Precision is whatever the platform C library’s log(3) delivers — typically ~15–17 significant decimal digits on x86-64 Linux. Results are not bit-for-bit portable across architectures.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • exp — the inverse: exp(log($x)) is $x for $x > 0, and log(exp($x)) is $x for all finite $x

  • ** — the exponentiation operator; $x ** $y is equivalent to exp($y * log($x)) for positive $x

  • POSIX::log10 — base-10 logarithm, direct from the C library; faster and slightly more accurate than log($x)/log(10)

  • POSIX::log2 — base-2 logarithm, same story

  • POSIX::log1plog(1 + $x) computed accurately for small $x, where the naive form loses precision