Excel 16.0 build 19929
Windows, bitness not recorded, CPU not recorded
17 captured inputs are indexed for this environment. Capture dates are not recorded. This is a reading count, not a comparison with another build.
Math and trigonometry functions
Matches all 13,965 recorded answers
Recorded: 13,962 in the answer bank and 3 workbook cells. How we measure this · See the Rust code
| Language | Name in Excel |
|---|---|
| Arabic | ACOS |
| Bulgarian | ACOS |
| Czech | ACOS |
| Danish | ARCCOS |
| German | ARCCOS |
| Greek | ACOS |
| English (Australia) | ACOS |
| English (United Kingdom) | ACOS |
| English (United States) | ACOS |
| Spanish | ACOS |
| Estonian | ACOS |
| Finnish | ACOS |
| French | ACOS |
| Hebrew | ACOS |
| Croatian | ACOS |
| Hungarian | ARCCOS |
| Indonesian | ACOS |
| Italian | ARCCOS |
| Japanese | ACOS |
| Korean | ACOS |
| Lithuanian | ACOS |
| Latvian | ACOS |
| Norwegian | ACOS |
| Dutch | BOOGCOS |
| Polish | ACOS |
| Portuguese (Brazil) | ACOS |
| Portuguese (Portugal) | ACOS |
| Romanian | ACOS |
| Russian | ACOS |
| Slovak | ACOS |
| Slovenian | ACOS |
| Serbian (Latin) | ACOS |
| Swedish | ACOS |
| Thai | ACOS |
| Turkish | ACOS |
| Ukrainian | ACOS |
| Vietnamese | ACOS |
| Chinese (Simplified) | ACOS |
| Chinese (Hong Kong) | ACOS |
| Chinese (Traditional) | ACOS |
Names from Microsoft's support site.
ACOS(number)
ACOS(number) is the principal inverse cosine: the angle in radians whose cosine is number.
acos: [-1, 1] -> [0, pi], cos(acos x) = x
[-1, 1]. Outside it there is no real angle whose cosine is
number, and the function is undefined over the reals.[0, pi], the principal branch. Microsoft's Learn reference states this range
explicitly: the returned angle is given in radians in the range 0 to pi.acos(-1) = pi, acos(0) = pi/2, acos(1) = 0. It is
the only one of the three inverse circular primaries that runs downhill, which is a frequent
source of sign errors when it is substituted for ASIN.acos(-x) = pi - acos(x). The function is neither even nor odd; it is
antisymmetric about the point (0, pi/2).acos(x) + asin(x) = pi/2 exactly, for every x in the domain.
This is the single most useful relation on the page and it is also, in floating point, a
liability — see the numerical notes.d/dx acos x = -1 / sqrt(1 - x^2), which is finite in the interior and blows up
at both endpoints. The graph meets x = 1 and x = -1 with a vertical tangent.x = 1, acos(x) = sqrt(2(1-x)) * (1 + (1-x)/12 + ...). The
square root is the whole story of this function's numerics: the answer near the endpoints is
governed by the square root of a quantity that itself has to be computed by subtraction.acos x = pi/2 - (x + x^3/6 + 3x^5/40 + ...), that is, pi/2 minus the
arcsine series. Convergence is slow near the endpoints, which is why nobody implements it this
way.IM* family, not to this surface): acos extends to
the complex plane with branch cuts along (-infinity, -1] and [1, +infinity). The real
function's domain is exactly the complement of those cuts on the real axis, which is why the
domain restriction is not arbitrary.Abramowitz & Stegun treat the inverse circular functions in chapter 4 section 4.4, including the principal-range conventions used above.
| Argument | Meaning | Default |
|---|---|---|
number | The cosine of the angle you want. Required. | — |
Microsoft's Learn reference describes the argument as "the cosine of the angle you want, and must be from -1 to 1".
The commonly misunderstood point is not the slot but the units of the result: ACOS returns
radians. Readers who work in degrees need DEGREES(ACOS(x)), and the Learn reference gives the
same advice in the form "multiply it by 180/PI()".
Returns Number — an angle in radians in [0, pi].
-1 and 1 are in the domain and return pi and 0 respectively. This is
a closed interval; an implementation that tests |x| < 1 rather than |x| <= 1 gets both
endpoints wrong, and they are the two arguments users are most likely to pass.1 is a domain failure. This matters far
more than it sounds, because the natural producer of ACOS arguments is a normalised dot
product, and rounding routinely pushes such a quotient a bit past 1. Formulas that compute an
angle between vectors need to clamp before calling ACOS; without a clamp they fail on exactly
the parallel-vector case they were written for.pi/2, and the smallest subnormals also return pi/2 — the function is flat
enough there that every subnormal maps to the same double.ACOS named there as a canonical example of it.ACOS is a well-conditioned function in the middle of its domain and an ill-conditioned one at
both ends, and every implementation question is about the ends.
The endpoint problem, stated exactly. Write x = 1 - t. Then acos(x) ~ sqrt(2t). A relative
error eps in t becomes a relative error eps/2 in the answer — that part is benign. The
problem is upstream: when x is a double near 1, forming 1 - x is exact by Sterbenz's lemma,
but the information was already lost if x itself came from a computation. The spacing of
doubles near 1 is about 2^-52, so the smallest nonzero acos reachable from a double argument
is around 2^-26 — roughly 1.5e-8. Half the exponent range of the answer is simply unreachable.
This is intrinsic to the argument being a cosine, not a defect of any implementation, and it is
why numerical geometry code computes angles from ATAN2 of a cross product and dot product rather
than from ACOS of a normalised dot product.
The complementary identity as a trap. acos(x) = pi/2 - asin(x) is exact in mathematics and
catastrophic in floating point for x near 1: asin(x) is then near pi/2, and the
subtraction of two nearly equal quantities destroys the relative accuracy of a result that is
itself near zero. An implementation of ACOS built on ASIN this way is accurate near x = -1
and wrong near x = +1. The mirror trap catches ASIN built on ACOS. Cody & Waite state the
rule: compute whichever of the pair is large directly, and get the small one another way.
The standard remedies, in the form the reference implementations use:
|x| = 1/2. For |x| <= 1/2, evaluate a rational (minimax)
approximation to asin and set acos(x) = pi/2 - asin(x); here both terms are comparable in
size and the subtraction is harmless.x in (1/2, 1], reduce by the half-angle identity: acos(x) = 2 * asin(sqrt((1-x)/2)).
The argument of the inner asin is small, so the accurate small-argument branch does the work,
and the square root supplies the endpoint behaviour exactly.x in [-1, -1/2), use the reflection acos(x) = pi - acos(-x) to move onto the
branch above. This subtraction is safe because the result is near pi, not near zero.sqrt(1 - x*x) near the endpoints. The product x*x rounds, and the
subtraction then loses bits that (1-x)*(1+x) retains. The factored form is the standard
substitute and costs one extra multiply.fdlibm's e_acos.c is the canonical published implementation of exactly this structure.
Correct rounding. ACOS is not correctly rounded in any mainstream library; the usual quality
target is under one ulp over the domain, with the last-bit behaviour near the endpoints being the
part that differs between vendors. That is where a comparison against Excel would be expected to
find its residuals, and no such comparison exists here.
Symmetry as a self-test. ACOS(x) + ACOS(-x) should be PI() and ACOS(x) + ASIN(x) should
be PI()/2. Neither will hold to the last bit for every x in any implementation — but how
they fail is a fingerprint of the branch structure, and it is measurable without an oracle.
Quoted from the public repository DnaCalc/DnaCalc, crates calc-func and calc-fml, at commit 9e1884369a67. Comments are the source's own. A kernel shared with other functions appears once, on its module page.
ACOS · 1 lines · calc-func/src/catalogue/math.rs on GitHub1 acos "ACOS" (1, 1) [V "number"] |s, a, sv| { unary(s, a, k::acos::acos_kernel) }
acos_kernel · 11 lines · calc-func/src/ported/acos.rs on GitHubpub fn acos_kernel(n: f64) -> Result<f64, WorksheetErrorCode> {
// W111 signed controls distinguish the staged subtraction near half an
// output ULP. ASIN's reused-factor graph is shared without re-evaluation.
match crate::ported::asin::asin_kernel(n) {
Ok(a) => Ok(crate::ported::excel_numeric::excel_x87_sub(
std::f64::consts::FRAC_PI_2,
a,
)),
Err(_) => Err(WorksheetErrorCode::Num),
}
}
unary catalogue/mathasin_kernel ported/asinatan_with ported/excel_numericatan_reduced_with ported/excel_numericbinary_with ported/excel_numericexcel_x87_sub ported/excel_numericexcel_x87_mul ported/excel_numericexcel_x87_div ported/excel_numericexcel_atan_reduced ported/excel_numericexcel_sqrt_staged ported/excel_numericpack_raw ported/excel_numeric/soft87zero ported/excel_numeric/soft87inf ported/excel_numeric/soft87pack ported/excel_numeric/soft87ext_pi ported/excel_numeric/soft87ext_one ported/excel_numeric/soft87atan ported/excel_numeric/x87atan_reduced ported/excel_numeric/x87mul ported/excel_numeric/x87sub ported/excel_numeric/x87div ported/excel_numeric/x87No implementation has been published with a Handbook test suite for this function.
The recorded environments below distinguish a reading from a same-input comparison. Counts describe captured inputs in each environment; overlapping captures and comparisons are not totals of unique worksheet calls.
| Excel 16.0 build | Platform and CPU | Captured inputs |
|---|---|---|
| 19929 | Windows, bitness not recorded, CPU not recorded | 17 |
| 20430 | Windows, 64-bit, CPU not recorded | 13,962 |
Agreement on these compared inputs does not establish agreement on unmeasured inputs.
Recorded environments and comparison details.
Windows, bitness not recorded, CPU not recorded
17 captured inputs are indexed for this environment. Capture dates are not recorded. This is a reading count, not a comparison with another build.
Windows, 64-bit, CPU not recorded
13,962 captured inputs are indexed for this environment. Capture dates: 2026-09-29 to 2026-09-29. This is a reading count, not a comparison with another build.
ASIN — the complementary partner, via ACOS(x) + ASIN(x) = PI()/2. Where ASIN is odd
and increasing, ACOS is neither odd nor increasing; the pair is not interchangeable with a
sign flip.ATAN and ATAN2 — the other route to an angle. acos(x) = atan2(x, sqrt(1-x^2)) in
Excel's x-first argument order, and that form is better conditioned near the endpoints than
ACOS computed from a series.COS — the forward function. COS(ACOS(x)) = x holds to rounding on the whole domain;
ACOS(COS(t)) recovers t only for t in [0, pi], and folds every other t into that
interval.ACOSH — the hyperbolic namesake, and a genuinely different function: its domain is
[1, +infinity), exactly the region where ACOS stops being defined. The two domains touch at
the single point x = 1, where both are zero.DEGREES — the usual consumer of the result.IMCOS and the complex family — where the branch cuts stop being a footnote.ACOT, whose range is also stated as 0 to pi. Two different functions with
the same stated range is a real trap, and the discriminator is the domain: ACOS takes
[-1, 1], ACOT takes everything.No named variants are recorded yet.
Suggest a correction or contribute an implementation · For agents