Signature
tanh(float $num): floatPurpose
tanh() returns the hyperbolic tangent of a number. It is defined as sinh($num) / cosh($num). Unlike the ordinary trigonometric tan(), it is not about angles on a circle. It is a smooth S-shaped curve that maps any real number into the range from -1 to 1. That makes it useful for squashing values into a bounded range, for example as an activation function in small neural-network calculations, for normalising scores, or for soft clipping in numeric code.
Signature
Parameters and defaults
$num: the value to process. It is required and has no default. Any finite float or integer is accepted, and integers are converted to float.
In the default (non-strict) typing mode, numeric strings such as "0.5" are coerced to float. With declare(strict_types=1) only int and float values are accepted. A non-numeric string such as "abc" throws a TypeError.
Return value and failure cases
The function always returns a float. The result lies between -1 and 1 inclusive:
tanh(0)is0.0, and the function is odd, sotanh(-$x)equals-tanh($x).- For large positive arguments the result reaches exactly
1.0, and for large negative arguments it reaches-1.0, because the true value is closer to the limit than a double can represent. tanh(INF)is1.0andtanh(-INF)is-1.0.tanh(NAN)isNAN.
There is no false return and no warning for out-of-range input. The only failure is a TypeError when the argument cannot be used as a number.
Example 1: sampling the curve
The curve rises steeply near zero and flattens as the input grows. Rounding keeps the output stable and readable.
$inputs = [0.5, 1, 2];
$results = array_map(fn(float $x): float => round(tanh($x), 4), $inputs);
echo json_encode($results), "\n";[0.4621,0.7616,0.964]
Notice how the step from 1 to 2 adds far less than the step from 0.5 to 1. This flattening is called saturation.
Example 2: saturation and special values
For large magnitudes the result is exactly 1 or -1, and special floats behave predictably.
var_dump(tanh(30));
var_dump(tanh(-30));
var_dump(tanh(INF));
var_dump(is_nan(tanh(NAN)));float(1) float(-1) float(1) bool(true)
Compare results with is_nan() rather than === or ==, because NAN is never equal to anything, including itself.
Example 3: a tiny neuron
A weighted sum passed through tanh() gives an output in the range -1 to 1. This is a classic use of the function.
function neuron(array $inputs, array $weights): float
{
$sum = 0.0;
foreach ($inputs as $i => $value) {
$sum += $value * $weights[$i];
}
return tanh($sum);
}
echo json_encode(round(neuron([0.5, -1.0, 2.0], [0.8, 0.3, 0.4]), 4)), "\n";0.7163
The weighted sum here is about 0.9, and tanh(0.9) is roughly 0.7163. The result is rounded to hide tiny floating-point noise.
Edge cases
- Saturation: beyond roughly magnitude 20 the output is indistinguishable from 1 or -1. Different inputs then produce identical results, so the function cannot be inverted there.
atanh()of exactly 1 gives infinity. - Precision near zero: for very small
$num,tanh($num)is almost equal to$numitself. - Float comparison: results are approximations. Compare with a tolerance, such as
abs($a - $b) < 1e-12, instead of strict equality, unless you are testing against the exact limits. - Integers: passing
0or1is fine, but the return is still a float, sovar_dump(tanh(0))showsfloat(0).
Common mistakes
- Confusing it with
tan().tan()is periodic and unbounded, whiletanh()is bounded and never repeats. - Passing degrees. Hyperbolic functions do not use angles, so there is nothing to convert with
deg2rad(). - Printing unrounded floats in tests. Expected outputs with long decimal tails are fragile. Round, or compare with a tolerance.
- Expecting a different range. If you need 0 to 1 rather than -1 to 1, rescale with
(tanh($x) + 1) / 2. - Feeding it text. Validate user input first, because a non-numeric string raises a
TypeError.
Related functions
tan(): the ordinary tangent of an angle in radians.atanh(): the inverse hyperbolic tangent, which reversestanh()for results strictly between -1 and 1.sinh(): hyperbolic sine, the numerator in the definition.cosh(): hyperbolic cosine, the denominator in the definition.
Recap
tanh(float $num): float computes sinh($num) / cosh($num) and always returns a float from -1 to 1. It is odd, smooth and saturating, returns NAN for NAN, and reaches exactly 1 or -1 for large inputs. Round or use a tolerance when comparing results, and do not confuse it with tan().
Tested examples
$inputs = [0.5, 1, 2];
$results = array_map(fn(float $x): float => round(tanh($x), 4), $inputs);
echo json_encode($results), "\n";
[0.4621,0.7616,0.964]
var_dump(tanh(30));
var_dump(tanh(-30));
var_dump(tanh(INF));
var_dump(is_nan(tanh(NAN)));
float(1) float(-1) float(1) bool(true)
function neuron(array $inputs, array $weights): float
{
$sum = 0.0;
foreach ($inputs as $i => $value) {
$sum += $value * $weights[$i];
}
return tanh($sum);
}
echo json_encode(round(neuron([0.5, -1.0, 2.0], [0.8, 0.3, 0.4]), 4)), "\n";
0.7163