Signature
atanh(float $num): floatPurpose
atanh() returns the inverse hyperbolic tangent of a number. In other words, it finds the value y for which tanh(y) equals the argument you passed in. It undoes tanh() the same way atan() undoes tan().
You will meet it in statistics (the Fisher z-transformation of a correlation coefficient), in signal scaling and in physics formulas that use hyperbolic functions. It is a plain mathematical helper: it has no side effects and always gives the same result for the same input.
Signature
Parameters
num: the value to process. The mathematically meaningful domain is the open interval from -1 to 1. The parameter has no default, so you must always supply it.
Because the parameter is typed float, an integer such as 0 is accepted and converted. A non-numeric string such as "abc" throws a TypeError. In PHP's default coercive mode a numeric string like "0.5" is converted to a float.
Return value and failure cases
The function always returns a float. It does not return false and does not throw for numbers that are out of range. Instead, the result follows floating-point conventions:
- For a value strictly between -1 and 1, you get a finite float. The sign matches the sign of the input, and
atanh(0)is zero. - For exactly
1, the result is positive infinity (INF). For exactly-1, it is negative infinity. - For any value with an absolute value greater than 1, the result is
NAN.
Check for these cases with is_infinite(), is_nan() or is_finite(). Never compare against NAN with ==, because NAN is not equal to anything, including itself.
Example 1: basic values
The function grows slowly near zero and rises steeply as the input approaches 1. Rounding keeps the printed output stable and readable.
$inputs = [0.5, -0.5, 0.9];
$results = array_map(fn(float $x): float => round(atanh($x), 6), $inputs);
echo json_encode($results);[0.549306,-0.549306,1.472219]
The result is symmetric: atanh(-x) is the negative of atanh(x). The jump from 0.5 to 0.9 is bigger than the jump from 0 to 0.5, which shows how steep the curve gets near 1.
Example 2: boundaries and out-of-range input
The edges of the domain do not raise errors, so you need to detect them yourself.
$plusOne = atanh(1.0);
$minusOne = atanh(-1.0);
$outside = atanh(1.5);
echo json_encode([
'plusOneIsPositiveInfinity' => is_infinite($plusOne) && $plusOne > 0,
'minusOneIsNegativeInfinity' => is_infinite($minusOne) && $minusOne < 0,
'outsideIsNan' => is_nan($outside),
]);{"plusOneIsPositiveInfinity":true,"minusOneIsNegativeInfinity":true,"outsideIsNan":true}This is the most important behavior to remember. Infinity and NAN can quietly flow into later calculations and spoil totals or averages.
Example 3: a guarded Fisher z-transform
Statisticians often convert a correlation coefficient r with atanh(r). Since a correlation of exactly 1 or -1 would produce infinity, a small wrapper can return null for values that cannot be transformed.
function fisherZ(float $r): ?float
{
if ($r <= -1.0 || $r >= 1.0) {
return null;
}
return round(atanh($r), 4);
}
echo json_encode([fisherZ(0.25), fisherZ(0.8), fisherZ(1.0)]);[0.2554,1.0986,null]
Returning null makes the invalid case explicit, and it is easy to encode as JSON or test for later.
Edge cases
- Precision: results are ordinary floats, so avoid comparing them with
==. Round them or compare with a small tolerance. - Values very near 1: an input like
0.999999is valid and gives a large but finite result. Rounding in the input data can push a value to exactly 1 and change the result to infinity. - Integers:
atanh(1)is the same asatanh(1.0), so integer input at the boundary still gives infinity. - Round trip:
tanh(atanh($x))should return approximately$xfor finite results, but tiny floating-point differences are normal.
Common mistakes
- Assuming out-of-range input throws. It returns
NANinstead, so validate user data first. - Testing
$result === NANor$result == NAN. Useis_nan(). - Confusing it with
atan().atan()is the inverse of the circular tangent and accepts any real number.atanh()is the inverse of the hyperbolic tangent and has a limited domain. - Passing degrees or percentages. A percentage such as
50must be converted to0.5before use. - Printing raw floats in tests. Long decimal tails can differ in presentation, so round or encode deliberately.
Related functions
tanh()computes the hyperbolic tangent, the function thatatanh()inverts.atan()is the inverse circular tangent.asinh()is the inverse hyperbolic sine.acosh()is the inverse hyperbolic cosine.is_nan(),is_infinite()andis_finite()help you check the result.
Recap
atanh(float $num): float returns the number whose hyperbolic tangent is $num. It is well defined for values strictly between -1 and 1, returns INF or -INF at the endpoints, and returns NAN outside the range. Guard your inputs, check results with the float-inspection functions, and round before displaying or comparing.
Tested examples
$inputs = [0.5, -0.5, 0.9];
$results = array_map(fn(float $x): float => round(atanh($x), 6), $inputs);
echo json_encode($results);[0.549306,-0.549306,1.472219]
$plusOne = atanh(1.0);
$minusOne = atanh(-1.0);
$outside = atanh(1.5);
echo json_encode([
'plusOneIsPositiveInfinity' => is_infinite($plusOne) && $plusOne > 0,
'minusOneIsNegativeInfinity' => is_infinite($minusOne) && $minusOne < 0,
'outsideIsNan' => is_nan($outside),
]);{"plusOneIsPositiveInfinity":true,"minusOneIsNegativeInfinity":true,"outsideIsNan":true}
function fisherZ(float $r): ?float
{
if ($r <= -1.0 || $r >= 1.0) {
return null;
}
return round(atanh($r), 4);
}
echo json_encode([fisherZ(0.25), fisherZ(0.8), fisherZ(1.0)]);[0.2554,1.0986,null]