Mathematics7 min readExamples run on PHP 8.5.10

acosh()

Learn how PHP 8.4 acosh() computes the inverse hyperbolic cosine, which inputs are valid, what it returns outside its domain, and how to avoid common mistakes.

Signature

acosh(float $num): float
Available since PHP 4.1.07.48.08.18.28.38.48.5All versions →
PHP acosh() function

Purpose

acosh() returns the inverse hyperbolic cosine of a number. Given a value num, it finds the non-negative number y for which cosh(y) equals num. It belongs to the family of hyperbolic functions, which appear in physics formulas, curve calculations such as the catenary (the shape of a hanging chain), and some numerical algorithms. Hyperbolic functions are related to the exponential function in the same way ordinary trigonometric functions are related to the circle.

The function is not the same as acos(). The arc cosine works with angles and accepts values from -1 to 1. The inverse hyperbolic cosine works with values of 1 or greater.

Signature

Parameters and defaults

$num is the only parameter and it has no default, so you must always supply it. It is declared as float. In PHP's default (non-strict) mode an integer such as 2 is converted to 2.0, and a numeric string such as "2" is also accepted. A non-numeric string such as "abc" throws a TypeError. If the file uses declare(strict_types=1), only integers and floats are accepted.

The mathematically valid domain is num >= 1.

Return value and failure cases

The function returns a float: the inverse hyperbolic cosine of $num.

  • For 1, the result is 0.0.
  • For values greater than 1, the result is a positive float that grows slowly as the input grows.
  • For values below 1, there is no real result, so PHP returns NAN (not a number). It does not throw an exception and it does not emit an error by itself.
  • For INF, the result is INF.

Because NAN is never equal to anything, including itself, you must test it with is_nan() rather than with == or ===.

Example 1: values on the valid domain

The first example prints the result for three inputs, formatted to six decimal places so the output does not depend on float display settings.

Example
<?php
foreach ([1, 2, 10] as $value) {
    echo $value, ' => ', sprintf('%.6f', acosh($value)), "\n";
}
Output
1 => 0.000000
2 => 1.316958
10 => 2.993223

The input 1 is the smallest valid value and yields zero. Larger inputs give larger outputs, but the growth is slow: going from 2 to 10 only raises the result from about 1.32 to about 2.99.

Example 2: the relationship with cosh()

acosh() undoes cosh() for non-negative arguments. Applying one after the other returns the original number, apart from tiny floating point rounding, which is why the output is formatted.

Example
<?php
$x = 3.0;
$y = acosh($x);
echo sprintf('%.4f', cosh($y)), "\n";
echo sprintf('%.4f', acosh(cosh(2.5))), "\n";
Output
3.0000
2.5000

Notice the round trip only works in this direction for non-negative numbers. cosh() gives the same result for -2.5 and 2.5, but acosh() always returns the non-negative one, so acosh(cosh(-2.5)) gives 2.5, not -2.5.

Example 3: a safe wrapper

In real code, an out-of-range input should usually be handled explicitly instead of letting NAN flow through later calculations. This wrapper converts NAN into null.

Example
<?php
function safeAcosh(float $x): ?float
{
    $result = acosh($x);
    return is_nan($result) ? null : $result;
}

foreach ([0.5, 1, 2, -3] as $value) {
    $result = safeAcosh($value);
    echo $value, ': ', $result === null ? 'invalid' : sprintf('%.6f', $result), "\n";
}
Output
0.5: invalid
1: 0.000000
2: 1.316958
-3: invalid

The values 0.5 and -3 are below 1, so they are reported as invalid. The values 1 and 2 pass through normally.

Edge cases

  • Exactly 1: this is the boundary of the domain and returns 0.0.
  • Just below 1: a value such as 0.999999 returns NAN. Floating point results from earlier calculations can land slightly below 1 because of rounding, so clamp or validate if your input is computed.
  • Very large numbers: the result grows roughly like the natural logarithm of twice the input, so it stays small even for huge inputs.
  • NAN input: passing NAN returns NAN.
  • Output formatting: floats are approximations. Use round(), sprintf() or number_format() when you display or compare results.

Common mistakes

  1. Confusing it with acos(). The two functions have different domains and different meanings. Use acos() for angles in radians and acosh() for the hyperbolic inverse.
  2. Comparing with NAN using ===. Always use is_nan().
  3. Expecting an exception for invalid input. PHP returns NAN silently for numbers below 1. Only wrong types raise a TypeError.
  4. Comparing floats exactly. After a round trip through cosh(), compare with a small tolerance or round both values first.
  5. Expecting negative results. The function returns only non-negative values on its domain.
  • cosh() computes the hyperbolic cosine, the function that acosh() inverts.
  • acos() computes the arc cosine of a value between -1 and 1.
  • asinh() computes the inverse hyperbolic sine.
  • atanh() computes the inverse hyperbolic tangent.
  • is_nan() checks for the NAN value that acosh() produces outside its domain.

Recap

acosh(float $num): float returns the inverse hyperbolic cosine. It is valid for inputs of 1 or more, returns 0.0 at 1, and returns NAN below 1. Check results with is_nan(), format floats before displaying them, and do not confuse the function with acos().

Tested examples

Values on the valid domain
<?php
foreach ([1, 2, 10] as $value) {
    echo $value, ' => ', sprintf('%.6f', acosh($value)), "\n";
}
Output
1 => 0.000000
2 => 1.316958
10 => 2.993223
The relationship with cosh()
<?php
$x = 3.0;
$y = acosh($x);
echo sprintf('%.4f', cosh($y)), "\n";
echo sprintf('%.4f', acosh(cosh(2.5))), "\n";
Output
3.0000
2.5000
A safe wrapper
<?php
function safeAcosh(float $x): ?float
{
    $result = acosh($x);
    return is_nan($result) ? null : $result;
}

foreach ([0.5, 1, 2, -3] as $value) {
    $result = safeAcosh($value);
    echo $value, ': ', $result === null ? 'invalid' : sprintf('%.6f', $result), "\n";
}
Output
0.5: invalid
1: 0.000000
2: 1.316958
-3: invalid