Math and trigonometry functions

ACOTH

Matches all 269,999 recorded answers

Recorded: 269,996 in the answer bank and 3 workbook cells. How we measure this · See the Rust code

Local names in 40 languages
LanguageName in Excel
ArabicACOTH
BulgarianACOTH
CzechACOTH
DanishARCCOTH
GermanACOTH
GreekACOTH
English (Australia)ACOTH
English (United Kingdom)ACOTH
English (United States)ACOTH
SpanishACOTH
EstonianACOTH
FinnishACOTH
FrenchACOTH
HebrewACOTH
CroatianACOTH
HungarianARCCOTH
IndonesianACOTH
ItalianACOTH
JapaneseACOTH
KoreanACOTH
LithuanianACOTH
LatvianACOTH
NorwegianACOTH
DutchACOTH
PolishACOTH
Portuguese (Brazil)ACOTH
Portuguese (Portugal)ACOTH
RomanianACOTH
RussianACOTH
SlovakACOTH
SlovenianACOTH
Serbian (Latin)ACOTH
SwedishARCCOTH
ThaiACOTH
TurkishACOTH
UkrainianACOTH
VietnameseACOTH
Chinese (Simplified)ACOTH
Chinese (Hong Kong)ACOTH
Chinese (Traditional)ACOTH

Names from Microsoft's support site.

What it does

ACOTH(number)

ACOTH(number) is the inverse hyperbolic cotangent.

acoth x  =  (1/2) * ln( (x + 1) / (x - 1) )  =  atanh(1/x),     |x| > 1
  • Domain: |x| > 1, that is (-infinity, -1) ∪ (1, +infinity). The closed interval [-1, 1] is excluded: coth maps R \ {0} onto exactly |y| > 1, so no real argument in the unit interval has a real inverse hyperbolic cotangent. This is the complement of ATANH's domain, and the two functions partition the real line between them but for the two endpoints.
  • Range: (-infinity, 0) ∪ (0, +infinity) — every nonzero real, with zero itself unattained. acoth never returns zero, because coth never equals zero.
  • Parity: odd. acoth(-x) = -acoth(x). This is exact mathematics and, as the identification work in this family has shown for its sibling, not something an implementation gets for free.
  • Poles: logarithmic singularities at x = 1+ (where acoth -> +infinity) and x = -1- (where acoth -> -infinity). Approach from inside the interval is not possible; there is nothing there.
  • Asymptotics: acoth(x) = 1/x + 1/(3x^3) + 1/(5x^5) + ... for |x| > 1. As |x| -> infinity the function decays like 1/x and reaches into the subnormals. This is the half of the domain where all the numerical difficulty lives.
  • Near the poles: with x = 1 + t, acoth(1 + t) = (1/2) * ln(2/t) + O(t). The growth is logarithmic, so even an argument one ulp above 1 produces only a modest number — around 18. The function is far better behaved at its poles than its poles suggest.
  • Derivative: d/dx acoth x = 1/(1 - x^2), which is negative on the whole domain (so acoth is decreasing on each branch) and finite everywhere except at the excluded endpoints.
  • Complex continuation: the branch cut is the closed interval [-1, 1] — exactly the excluded real domain. ATANH's cuts are the two outer rays. The two functions have complementary cuts, which is the precise statement of the complementary-domain observation above.

Abramowitz & Stegun give the closed form in chapter 4 section 4.6; Kahan's branch-cut paper is the standard treatment of why the cut sits where it does.

Arguments

ArgumentMeaningDefault
numberThe hyperbolic cotangent of the value you want. Required.—

That description is Microsoft's, from the Learn reference: "the hyperbolic cotangent of the angle that you want".

Try it

Input cells (optional)

Example: {"B2": 3, "B3": 4}. A1 holds the formula. Other cells need values before a formula can read them.

Enter a formula, then calculate.

Runs locally in your browser with OneCalc. Its answer may differ from Excel. Use English function names and commas between arguments.

Quirks

Result and edge cases

Returns Number.

  • x = 1 and x = -1 are not in the domain and are rejected. The interval is open; these are the poles.
  • Anything strictly inside (-1, 1), including zero and every subnormal, is a domain failure. Readers arriving from ATANH — whose domain is exactly this interval — get this wrong in both directions.
  • Just outside ±1 the answer is finite and modest. There is no overflow near the poles, because the growth is logarithmic: the largest magnitude reachable from a double argument is around 18.4, attained one ulp outside 1.
  • Large magnitudes decay towards zero like 1/x, and the result reaches into the subnormal range at the top of the double domain. This is the region where relative accuracy is hard to keep, and where the two candidate evaluation forms visibly differ.
  • Arrays lift elementwise, with out-of-domain elements erroring element-locally.

How to implement

Numerical notes

ACOTH has one serious hazard, and it is at the far end of the domain rather than at the poles — the opposite of what the function's shape suggests.

The large-argument cancellation. Evaluate (1/2) ln((x+1)/(x-1)) for large x. The ratio (x+1)/(x-1) tends to 1, and ln of a value near 1 is the canonical accuracy disaster: the information about the answer lives entirely in the digits of the ratio that the division has just rounded away. Concretely, once x exceeds about 2^53, the doubles x+1 and x-1 are the same number, the ratio is exactly 1, and the naive form returns exactly zero — where the true answer is approximately 1/x, a perfectly representable positive number. The failure begins long before that: relative accuracy degrades steadily from around x = 10.

The remedies, both standard:

  1. Reciprocate. acoth(x) = atanh(1/x), and 1/x is small, so an accurate small-argument atanh delivers full relative accuracy right down to the subnormals. This is the single most effective change and it costs one division.
  2. Use log1p on the difference form. atanh(u) = (1/2)(log1p(u) - log1p(-u)) with u = 1/x, which never forms a quantity near 1 and never takes a logarithm of one. Higham's treatment of log(1+x) is the standard reference for why the log1p primitive exists at all.

Near the poles, by contrast, the naive form is fine: (x+1)/(x-1) is large there, ln of a large number is well conditioned, and the only subtlety is that x - 1 must be computed from a double argument that is already close to 1 — which Sterbenz's lemma makes exact.

So the correct branch structure is the reverse of the intuitive one: use the direct ratio-log near the poles, where the ratio is far from one, and the reciprocal atanh form far from them, where the ratio is close to one. An implementation that uses one form everywhere is wrong at one end or the other.

Why the switch point matters more here than usual. Because the two forms disagree in the last bits over a whole band, any implementation that places its switch differently from Excel's will differ from Excel on every argument in the gap between the two placements — even though both forms are individually excellent. This is the characteristic signature of a piecewise elementary function, and it is why identification work on this family concentrates on locating switches rather than on improving accuracy.

Rust code

Show the CalcFunc source of this function

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.

ACOTH · 1 lines · calc-func/src/catalogue/math.rs on GitHub
4 acoth "ACOTH" (1, 1) [V "number"] |s, a, sv| { unary(s, a, k::acoth::acoth_kernel) }
acoth_series_magnitude · 26 lines · calc-func/src/ported/acoth.rs on GitHub
fn acoth_series_magnitude(a: f64) -> f64 {
    let reciprocal = crate::ported::excel_numeric::excel_x87_div(1.0, a);

    // Excel flushes the reciprocal-to-series handoff when it is subnormal. In
    // particular, both signs of a sufficiently large finite input publish +0.
    if reciprocal < f64::MIN_POSITIVE {
        return 0.0;
    }

    let square = crate::ported::excel_numeric::excel_x87_mul(a, a);
    let mut power = a;
    let mut sum = reciprocal;

    for k in 1..ACOTH_SERIES_TERM_CAP {
        power = crate::ported::excel_numeric::excel_x87_mul(power, square);
        let denominator = crate::ported::excel_numeric::excel_x87_mul((2 * k + 1) as f64, power);
        let term = crate::ported::excel_numeric::excel_x87_div(1.0, denominator);
        let next = crate::ported::excel_numeric::excel_x87_add(sum, term);
        if next == sum {
            break;
        }
        sum = next;
    }

    sum
}
acoth_kernel · 26 lines · calc-func/src/ported/acoth.rs on GitHub
pub fn acoth_kernel(n: f64) -> Result<f64, WorksheetErrorCode> {
    let a = n.abs();
    if a <= 1.0 {
        return Err(WorksheetErrorCode::Num);
    }
    // W109 build-20228/CV2 identification: ACOTH computes on |x| and restores
    // the sign after one of two distinct calculation graphs:
    //   * below the pinned switch, native binary64 +/-1 staging, an x87-PC64
    //     stored division, then FYL2X and half-scale;
    //   * at and above it, the direct inverse odd-power series with every
    //     reciprocal, multiply, divide, and accumulator add stored through
    //     x87 PC64.
    // The frozen graph scored 202,217/202,217 discovery inputs and
    // 66,552/66,552 disjoint held-out inputs exactly.
    let mag = if a < ACOTH_SERIES_FLOOR {
        let ratio = crate::ported::excel_numeric::excel_x87_div(a + 1.0, a - 1.0);
        // Storing the FYL2X result before multiplying by the exact power-of-two
        // scale is bit-equivalent here to keeping the half-scale in x87.
        0.5 * crate::ported::excel_numeric::excel_log(ratio)
    } else {
        acoth_series_magnitude(a)
    };

    // Excel publishes positive zero for both signs after the reciprocal flush.
    Ok(if mag == 0.0 { 0.0 } else { mag.copysign(n) })
}

Kernels shared with other functions

Argument and result plumbing

  • num catalogue/kit
  • out catalogue/kit

No implementation has been published with a Handbook test suite for this function.

Version differences

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 buildPlatform and CPUCaptured inputs
19929Windows, bitness not recorded, CPU not recorded26
20131Windows, bitness not recorded, AMD Ryzen 7 4800H with Radeon Graphics56
20228Windows, 64-bit, CPU not recorded239,774
20430Windows, 64-bit, CPU not recorded1,224
  • XC-ACOTH-001: build 19929 versus build 20131; 1 same-input pairs, 0 differing answers. Compared axes: excel-build. Numeric answers were compared by their recorded binary64 bits; other answers by typed value.
  • XC-ACOTH-002: build 19929 versus build 20228; 1 same-input pairs, 0 differing answers. Compared axes: excel-build. Numeric answers were compared by their recorded binary64 bits; other answers by typed value.
  • XC-ACOTH-003: build 19929 versus build 20430; 1 same-input pairs, 0 differing answers. Compared axes: excel-build. Numeric answers were compared by their recorded binary64 bits; other answers by typed value.
  • XC-ACOTH-004: build 20131 versus build 20228; 9 same-input pairs, 0 differing answers. Compared axes: excel-build. Numeric answers were compared by their recorded binary64 bits; other answers by typed value.
  • XC-ACOTH-005: build 20131 versus build 20430; 1 same-input pairs, 0 differing answers. Compared axes: excel-build. Numeric answers were compared by their recorded binary64 bits; other answers by typed value.
  • XC-ACOTH-006: build 20228 versus build 20430; 4 same-input pairs, 0 differing answers. Compared axes: excel-build. Numeric answers were compared by their recorded binary64 bits; other answers by typed value.

Agreement on these compared inputs does not establish agreement on unmeasured inputs.

Recorded environments and comparison details.

Excel 16.0 build 19929

Windows, bitness not recorded, CPU not recorded

26 captured inputs are indexed for this environment. Capture dates are not recorded. This is a reading count, not a comparison with another build.

Excel 16.0 build 20131

Windows, bitness not recorded, AMD Ryzen 7 4800H with Radeon Graphics

56 captured inputs are indexed for this environment. Capture dates: 2026-07-12 to 2026-07-12. This is a reading count, not a comparison with another build.

Excel 16.0 build 20228

Windows, 64-bit, CPU not recorded

239,774 captured inputs are indexed for this environment. Capture dates: 2026-08-09 to 2026-08-09. This is a reading count, not a comparison with another build.

Excel 16.0 build 20430

Windows, 64-bit, CPU not recorded

1,224 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.

Alternatives

Relationships

  • ATANH — the reciprocal partner and the complementary domain: acoth(x) = atanh(1/x) wherever both are defined, ATANH on (-1, 1) and ACOTH on |x| > 1. Upstream identification work treats the two together for exactly this reason, and both carry evidence records here.
  • COTH — the forward function. COTH(ACOTH(x)) = x to rounding on the domain; ACOTH(COTH(t)) = t for every nonzero t.
  • ACOSH — shares the exclusion of the unit interval, but only on one side: ACOSH takes [1, infinity), ACOTH takes |x| > 1. They differ at exactly x = 1, where ACOSH is defined and zero and ACOTH is not defined at all.
  • ACOT — the circular namesake, and unlike ACOTH it has no domain restriction whatsoever. The pair is a good illustration that a hyperbolic namesake is not a variant: it is a different function with a different domain and a different shape.
  • LN — the substrate of the closed form, and the source of the large-argument hazard.
  • Confused with: 1/COTH(x), and with ATANH, whose domain is the exact complement.

Named variants

No named variants are recorded yet.

Suggest a correction or contribute an implementation · For agents