Signature
acos(float $num): floatPurpose
acos() returns the arc cosine of a number. It answers the question: "Which angle has this cosine?" The angle is returned in radians, not degrees. The function is the inverse of cos(): for any value in its domain, cos(acos($num)) gives back the original number, apart from tiny floating-point rounding differences.
Typical uses include finding the angle between two vectors, working out the angle of a triangle from its side lengths, and some geometry or graphics calculations.
Signature
Parameters and defaults
$num is the only parameter and it has no default. It is a float, and the valid domain is from -1.0 to 1.0 inclusive, because no real angle has a cosine outside that range. Integers are accepted and converted to floats, so acos(1) works as expected. Values that are not numeric, such as an array or a non-numeric string, cause a TypeError.
Return value and failure cases
The return value is a float between 0 and M_PI (about 3.14159). Some reference points:
acos(1)is0acos(0)is half of pi, about1.5708acos(-1)is pi, about3.1416
If $num is outside the range -1 to 1, the function does not throw an exception. It returns NAN (not a number). Any later arithmetic with NAN also produces NAN, so you should check for it with is_nan() when the input is not guaranteed to be valid. Note that NAN is never equal to anything, including itself, so $x === NAN is not a valid test.
Example 1: Familiar values
The first example prints a few well-known results rounded to four decimals. Formatting with sprintf() keeps the output stable and avoids showing long floating-point tails.
echo sprintf("%.4f", acos(1)), "\n";
echo sprintf("%.4f", acos(0)), "\n";
echo sprintf("%.4f", acos(-1)), "\n";
echo sprintf("%.4f", acos(0.5)), "\n";0.0000 1.5708 3.1416 1.0472
Example 2: Angle between two vectors
The dot product of two vectors divided by the product of their lengths equals the cosine of the angle between them. Applying acos() gives the angle, and rad2deg() converts it to degrees. The code clamps the cosine into the valid range first, which is a good habit for reasons explained below.
function angleDegrees(array $a, array $b): float
{
$dot = $a[0] * $b[0] + $a[1] * $b[1];
$lengthA = sqrt($a[0] ** 2 + $a[1] ** 2);
$lengthB = sqrt($b[0] ** 2 + $b[1] ** 2);
$cosine = $dot / ($lengthA * $lengthB);
$cosine = max(-1.0, min(1.0, $cosine));
return rad2deg(acos($cosine));
}
echo sprintf("%.2f", angleDegrees([1, 0], [1, 1])), "\n";
echo sprintf("%.2f", angleDegrees([1, 0], [0, 1])), "\n";
echo sprintf("%.2f", angleDegrees([1, 0], [-1, 0])), "\n";45.00 90.00 180.00
Example 3: Out-of-range input and clamping
Calculated cosines can drift just past 1 or -1 because of floating-point rounding. In that case acos() returns NAN even though the mathematical result is valid. Clamping the value with min() and max() fixes this.
$value = 1 + PHP_FLOAT_EPSILON;
echo json_encode([
is_nan(acos(2)),
is_nan(acos($value)),
acos(min(1.0, max(-1.0, $value))) == 0.0,
]), "\n";[true,true,true]
Edge cases
- Exact endpoints:
1and-1are valid and give0and pi. - Slightly out of range: values like
1.0000000000000002returnNAN. This often appears after dividing dot products by vector lengths. - Zero-length vectors: dividing by zero length fails before
acos()is reached. Check lengths first. - Floating-point comparison: compare results with a tolerance or round them for display, instead of using
===on computed floats. - Result range: the answer is never negative. If you need a signed angle, use
atan2()with additional information.
Common mistakes
- Treating the result as degrees.
acos(0)is about1.5708, not90. Userad2deg()when you need degrees. - Passing degrees to trigonometric functions. If you go back with
cos(), give it radians. - Ignoring
NAN. An out-of-range argument does not raise an error, so the problem can silently spread into later calculations. - Testing with
=== NAN. Useis_nan()instead. - Printing raw floats and expecting short output. Round or format values when showing them to users.
Related functions
cos()is the cosine function thatacos()inverts.acosh()is the inverse hyperbolic cosine, which is a different function with a different domain.asin()returns the arc sine.atan()returns the arc tangent.rad2deg()converts radians to degrees.is_nan()detects invalid results.
Recap
acos(float $num): float returns an angle in radians from 0 to pi for a cosine between -1 and 1. Values outside that range produce NAN rather than an exception. Clamp computed cosines, convert to degrees only when needed, and format floats before displaying them.
Tested examples
echo sprintf("%.4f", acos(1)), "\n";
echo sprintf("%.4f", acos(0)), "\n";
echo sprintf("%.4f", acos(-1)), "\n";
echo sprintf("%.4f", acos(0.5)), "\n";
0.0000 1.5708 3.1416 1.0472
function angleDegrees(array $a, array $b): float
{
$dot = $a[0] * $b[0] + $a[1] * $b[1];
$lengthA = sqrt($a[0] ** 2 + $a[1] ** 2);
$lengthB = sqrt($b[0] ** 2 + $b[1] ** 2);
$cosine = $dot / ($lengthA * $lengthB);
$cosine = max(-1.0, min(1.0, $cosine));
return rad2deg(acos($cosine));
}
echo sprintf("%.2f", angleDegrees([1, 0], [1, 1])), "\n";
echo sprintf("%.2f", angleDegrees([1, 0], [0, 1])), "\n";
echo sprintf("%.2f", angleDegrees([1, 0], [-1, 0])), "\n";
45.00 90.00 180.00
$value = 1 + PHP_FLOAT_EPSILON;
echo json_encode([
is_nan(acos(2)),
is_nan(acos($value)),
acos(min(1.0, max(-1.0, $value))) == 0.0,
]), "\n";
[true,true,true]