Excel 16.0 build 19929
Windows, bitness not recorded, CPU not recorded
42 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
Close: 56 of 40,244 recorded answers differ in the last bits, worst 2 ULP
Everything else matches (40,241 in the answer bank and 3 workbook cells). Last-bit means a finite number within 16 ULP of Excel's. How we measure this · See the Rust code
| Language | Name in Excel |
|---|---|
| Arabic | COTH |
| Bulgarian | COTH |
| Czech | COTH |
| Danish | COTH |
| German | COTH |
| Greek | COTH |
| English (Australia) | COTH |
| English (United Kingdom) | COTH |
| English (United States) | COTH |
| Spanish | COTH |
| Estonian | COTH |
| Finnish | COTH |
| French | COTH |
| Hebrew | COTH |
| Croatian | COTH |
| Hungarian | COTH |
| Indonesian | COTH |
| Italian | COTH |
| Japanese | COTH |
| Korean | COTH |
| Lithuanian | COTH |
| Latvian | COTH |
| Norwegian | COTH |
| Dutch | COTH |
| Polish | COTH |
| Portuguese (Brazil) | COTH |
| Portuguese (Portugal) | COTH |
| Romanian | COTH |
| Russian | COTH |
| Slovak | COTH |
| Slovenian | COTH |
| Serbian (Latin) | COTH |
| Swedish | COTH |
| Thai | COTH |
| Turkish | COTH |
| Ukrainian | COTH |
| Vietnamese | COTH |
| Chinese (Simplified) | COTH |
| Chinese (Hong Kong) | COTH |
| Chinese (Traditional) | COTH |
Names from Microsoft's support site.
COTH(number)
COTH(number) returns the hyperbolic cotangent. Microsoft's page gives the equation as
cosh(x)/sinh(x) and describes the function as the hyperbolic analogue of the ordinary
cotangent.
coth x = cosh x / sinh x = 1 / tanh x = (e^{2x} + 1) / (e^{2x} - 1)
| Property | Statement |
|---|---|
| Domain | all real x except x = 0 |
| Range | (-∞, -1) ∪ (1, ∞) — the value 1 is a limit, never attained |
| Parity | odd: coth(-x) = -coth(x) |
| Pole | one, simple, at x = 0, with residue 1 |
| Laurent series at 0 | coth x = 1/x + x/3 - x³/45 + 2x⁵/945 - … (A&S 4.5.67) |
| Asymptote | coth x → ±1 as x → ±∞, exponentially fast: coth x = 1 + 2e^{-2x} + … |
| Fundamental identity | coth²x - csch²x = 1 |
| Derivative | d/dx coth x = -csch²x = 1 - coth²x |
| Relation to circular | coth x = i·cot(ix) |
| Complex structure | poles at every x = ikπ; periodic with period πi |
The shape is worth holding in mind: two branches, each strictly decreasing, each hugging the
line y = ±1 from outside. Because the approach is exponential, coth x becomes
indistinguishable from 1 in binary64 once x is above about 19 — 2e^{-2x} falls below half
an ulp of 1 there. From roughly x = 19 upward the mathematically correct answer already
is exactly 1.0. That fact does most of the work in the evidence discussion below.
| Argument | Meaning | Constraint (as documented) |
|---|---|---|
number | The hyperbolic angle. Required. | ABS(number) < 2^27 |
The constraint is also, on its face, unnecessary here in a way it is not for the circular
functions: coth needs no argument reduction, and its correct value at 2^27 is exactly 1.0.
A magnitude bound on a hyperbolic function looks like a documentation template applied
uniformly across the 2013 trigonometric batch rather than a numerical requirement — but that
reading is a hypothesis, not a finding, and it is on the probe list.
Returns Number with absolute value strictly greater than 1.
COTH(0) — mathematically a pole. Microsoft's COTH page, as fetched, states the
magnitude constraint and the non-numeric condition but does not state what happens at
zero, where COT's page does state #DIV/0!. That asymmetry is in the
documentation; the Handbook has not checked what Excel returns.x — the correct answer is 1.0 exactly, for every x above about 19.x — the correct answer is −1.0 exactly, symmetrically.±1 well
before any overflow, saturation and correct evaluation agree on the value everywhere the
overflow could occur. The saturation is therefore not an approximation — it is the right
answer reached by an unusual route. What it does hide is whether the documented 2^27 bound
fires at all.coth x ≈ 1/x, so COTH of a tiny argument is a huge finite number, and
overflows only for ABS(x) down in the subnormal range.As documented on Microsoft's COTH page:
| Error | Condition |
|---|---|
#NUM! | ABS(number) is not less than 2^27 |
#VALUE! | number is non-numeric |
Not documented on that page, and therefore not stated here as behaviour: what COTH(0)
returns. 1/TANH(0) and COSH(0)/SINH(0) are both divisions by zero, so #DIV/0! is the
expected outcome by analogy with COT, but expectation is not evidence and Microsoft's page
does not say it.
Three regimes, and the middle one is the only place a naive route is safe.
Near zero. 1/tanh x is well conditioned as a value — tanh x → x, so coth x → 1/x —
but the interesting quantity is often coth x - 1/x, which cancels catastrophically. The
remedy is the Laurent series 1/x + x/3 - x³/45 + … (A&S 4.5.67), used below roughly 2^-13,
where it is both cheaper and more accurate than any division.
Moderate. coth x = 1/tanh x, with tanh computed by the standard expm1 form: for
t = expm1(2·ABS(x)), tanh(ABS(x)) = t/(t + 2), hence coth(ABS(x)) = (t + 2)/t, sign
restored afterwards. This is fdlibm's s_tanh.c inverted, and it never forms e^{2x}
directly, so it never overflows on the way to a value near 1. Alternatively
coth x = 1 + 2/(e^{2x} - 1) isolates the deviation from the asymptote — the form to use if
what you want is coth x - 1.
Large. The mathematically correct answer is exactly sign(x) once 2e^{-2ABS(x)} drops
below half an ulp of 1, which happens around ABS(x) ≈ 19. Any branch structure that returns
sign(x) above that threshold is correct, whatever route it took to get there. The
cosh/sinh route, by contrast, produces Inf/Inf = NaN at around ABS(x) ≈ 710 — three
orders of magnitude past the point where the answer stopped changing. The recorded
saturation is a repair applied at the overflow boundary rather than a branch taken at the
mathematical one, and both give the same answer; the difference is only visible if you ask what
happens in between, which nothing on record does.
The general lesson, and it is a good one: a reciprocal built from cosh/sinh fails not because
the values are wrong but because the representation fails first. Reformulating in terms of
expm1 moves the overflow out of the computation entirely.
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.
COTH · 1 lines · calc-func/src/catalogue/math.rs on GitHub13 coth "COTH" (1, 1) [V "number"] |s, a, sv| { unary(s, a, k::coth::coth_kernel) }
coth_kernel · 10 lines · calc-func/src/ported/coth.rs on GitHubpub fn coth_kernel(n: f64) -> Result<f64, WorksheetErrorCode> {
let t = crate::ported::tanh::tanh_kernel(n);
if t == 0.0 {
return Err(WorksheetErrorCode::Div0);
}
// W111 retains the reciprocal of the published TANH composition, including
// its cancellation-safe small-argument denominator. Non-finite 1/TANH
// (large |n|) saturates to sign(n) under COTH's real policy.
ExcelRealPolicy::SATURATE_SIGN.publish(n, crate::ported::excel_numeric::excel_x87_recip(t))
}
unary catalogue/mathcosh_kernel ported/coshbinary_with ported/excel_numericexcel_expm1_internal ported/excel_numericexpm1_internal_graph ported/excel_numericexcel_x87_add ported/excel_numericexcel_x87_sub ported/excel_numericexcel_x87_mul ported/excel_numericexcel_x87_div ported/excel_numericexcel_x87_recip ported/excel_numericmul ported/excel_numeric/x87add ported/excel_numeric/x87sub ported/excel_numeric/x87div ported/excel_numeric/x87recip ported/excel_numeric/x87pow2_positive ported/excel_numeric/x87_chainspow2 ported/excel_numeric/x87_chainsexp_ext ported/excel_numeric/x87_chainsexp_with ported/excel_numeric/x87_chainsexcel_exp ported/excel_numeric/x87_chainslog_with ported/excel_numeric/x87_chainsexcel_log ported/excel_numeric/x87_chainssinh_kernel ported/sinhtanh_kernel ported/tanhNo 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 | 42 |
| 20430 | Windows, 64-bit, CPU not recorded | 40,241 |
Agreement on these compared inputs does not establish agreement on unmeasured inputs.
Recorded environments and comparison details.
Windows, bitness not recorded, CPU not recorded
42 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
40,241 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.
TANH — the reciprocal, and the numerically well-behaved member of the pair. Any
accurate COTH is 1/TANH computed carefully, or the Laurent series near zero.SINH, COSH — the ratio the documentation names. Evaluating COTH that
way is what produces the Inf/Inf the saturation exists to catch.arg_domain_guard=none axis value. Read the
two pages together: they diverge from their documentation in the same way.ACOTH — not an Excel function. There is no inverse hyperbolic cotangent on the
worksheet surface; ATANH(1/x) is the standard substitute and inherits ATANH's own
accuracy problem near ±1.coth x = i·cot(ix). Same 1/x leading term,
same documented bound, and the only member of the pair whose zero case is documented.IMCOT — the complex cotangent; there is no IMCOTH.No named variants are recorded yet.
Suggest a correction or contribute an implementation · For agents