{
  "category": "Math and trigonometry functions",
  "display_name": "ACOT",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.ACOT",
  "implementation_state": {
    "answer_bank": {
      "excel_builds": [
        "20430"
      ],
      "larger_numeric": 0,
      "last_bit": 0,
      "matched": 16924,
      "other_mismatch": 0,
      "refused": 0,
      "rows": 16924,
      "unread": 0,
      "worst_ulp": 0
    },
    "detail": "Recorded: 16,924 in the answer bank and 3 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 16,927 recorded answers",
    "workbook_corpus": {
      "cells": 3,
      "matched": 3
    }
  },
  "implementations": [
    {
      "commit": "9e1884369a678158dd82d3d74188daf986995e87",
      "flavour": "excel-compatibility-candidate",
      "language": "Rust",
      "name": "CalcFunc",
      "own_code": [
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/math.rs#L46-L46",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/ported/acot.rs#L3-L22"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/math::unary",
        "ported/excel_numeric::atan_with",
        "ported/excel_numeric::atan_reduced_with",
        "ported/excel_numeric::binary_with",
        "ported/excel_numeric::excel_x87_recip",
        "ported/excel_numeric::excel_atan_reduced",
        "ported/excel_numeric/soft87::pack_raw",
        "ported/excel_numeric/soft87::zero",
        "ported/excel_numeric/soft87::inf",
        "ported/excel_numeric/soft87::pack",
        "ported/excel_numeric/soft87::ext_pi",
        "ported/excel_numeric/soft87::ext_one",
        "ported/excel_numeric/x87::atan",
        "ported/excel_numeric/x87::atan_reduced",
        "ported/excel_numeric/x87::recip"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/math.rs#L46-L46",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 16,927 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.ACOT.json",
  "name": "ACOT",
  "notes": [],
  "schema": "efh.function-reference/v1",
  "section_order": [
    "what-it-does",
    "try-it",
    "quirks",
    "how-to-implement",
    "version-differences",
    "alternatives"
  ],
  "sections": {
    "alternatives": "\n### Relationships\n\n- **`COT`** — the forward function. `COT(ACOT(x)) = x` to rounding; `ACOT(COT(t))` recovers `t`\n  only for `t` in `(0, pi)`.\n- **`ACOTH`** — the hyperbolic namesake, and a genuinely different shape: its domain excludes\n  `[-1, 1]` entirely, where `ACOT` accepts everything.\n- **`ACOS`** — shares the stated range `0` to `pi`, and shares nothing else. The discriminator is\n  the domain: `ACOS` takes `[-1, 1]`, `ACOT` takes all of `R`. Two surfaces with the same stated\n  range are a live confusion, and this is the pair.\n- **`ATAN2`** — the four-quadrant route. `ACOT(x)` is `ATAN2(x, 1)` in Excel's `x`-first argument\n  order, and that formulation is better behaved at large `|x|` than the subtraction is.\n- **Confused with**: `1/ATAN(x)`, which is not any inverse cotangent; and `ATAN(1/x)`, which is\n  the *other* branch convention and differs by `pi` for negative arguments.\n\n\n",
    "how-to-implement": "\n### Numerical notes\n\n\n`ACOT` is analytically the tamest function on this batch of pages — bounded derivative, no\nsingularities, no domain edge — and it has one sharp numerical problem, which comes entirely from\nhow it is usually computed.\n\n**Catastrophic cancellation in `pi/2 - atan(x)`.** The identity is exact in mathematics. In binary64\nit is not: as `x` grows, `atan(x)` approaches `pi/2`, and the subtraction of two nearly equal\nquantities destroys the relative accuracy of a result that is itself near zero. The failure is\nprogressive and total:\n\n- The correctly rounded `atan(x)` becomes exactly the double nearest `pi/2` once `x` exceeds\n  roughly `2^53` — beyond which the subtraction returns a fixed, tiny residue and then, past\n  another threshold, exactly zero.\n- The true `acot(x)` at those arguments is approximately `1/x`, a perfectly representable positive\n  number all the way down to the subnormal floor.\n- So there is a very wide band of arguments — everything above about `1e16`, which is more than\n  290 decades of the double range — on which `pi/2 - atan(x)` has no correct significant digits\n  at all, and eventually returns a value outside the function's own open range.\n\nThis is the mirror image of the `ATAN` situation: `ATAN` is accurate for large `x` because its\nanswer is large; `ACOT`'s answer is small there, and small answers reached by subtraction are\nwhere relative accuracy goes to die.\n\n**The standard remedy** is the reciprocal reduction, and it is one line:\n\n    acot(x) = atan(1/x)              for x >=  1        (result in (0, pi/4])\n    acot(x) = pi + atan(1/x)         for x <= -1        (result in [3pi/4, pi))\n    acot(x) = pi/2 - atan(x)         for |x| < 1\n\nInside the unit interval the subtraction is harmless — both terms are of order one and the answer\nis of order one. Outside it, `1/x` is small and `atan` of a small argument is accurate to the last\nbit, so `acot(x)` inherits full relative accuracy right down to the subnormals. Cody & Waite give\nthis reduction for the `ATAN`/`ACOT` pair; it is the same trick, run the other way, that makes\n`ATAN` accurate for large arguments.\n\n**Cost of the remedy**: one division and one comparison. There is no accuracy trade-off, no extra\npolynomial, and no branch subtlety beyond getting the `x <= -1` offset right.\n\n**A self-test without an oracle.** `TAN(ACOT(x)) * x` should be `1`, and `ACOT(x) + ACOT(-x)`\nshould be `PI()`. Sweeping the first across many decades of `x` shows the exact point where the\nsubtraction stops carrying information, without needing any high-precision reference.\n\n\n",
    "quirks": "\n### Result and edge cases\n\n\nReturns `Number` — an angle in radians.\n\n- **Zero** returns `pi/2`. This is the case that separates the two branch conventions, and it is\n  the one worth checking first in any implementation.\n- **Negative arguments** return values in `(pi/2, pi)` on the documented convention — never\n  negative. A negative result from `ACOT` would be evidence of the other convention.\n- **Very large negative arguments** produce results approaching `pi` from below, and the\n  corresponding question is whether they saturate at exactly `pi`.\n- **Subnormal arguments** return `pi/2`, indistinguishably from zero.\n- **Arrays** lift elementwise.\n\n### Version\n\n`ACOT` is one of the trigonometric surfaces added in Excel 2013, alongside `ACOTH`, `SEC`, `CSC`,\n`COT` and their hyperbolic partners. Workbooks that must open in earlier versions substitute\n`PI()/2 - ATAN(x)`, which is the same function on the documented convention.\n\n\n\n### Errors\n\n\n| Error | Condition | Source |\n|---|---|---|\n| `#VALUE!` | The argument does not convert to a number | Shared coercion rules |\n| propagated | An error value in the argument is returned unchanged | Shared coercion rules |\n\n",
    "sources": "- Microsoft Learn, \"WorksheetFunction.Acot method (Excel)\" —\n  <https://learn.microsoft.com/en-us/office/vba/api/excel.worksheetfunction.acot> (retrieved: the\n  description and the statement that the result is in radians in the range 0 to pi).\n- Abramowitz & Stegun, *Handbook of Mathematical Functions*, chapter 4 section 4.4 — inverse\n  circular functions and the arccotangent branch conventions.\n- Kahan, *Branch Cuts for Complex Elementary Functions* — why the arccotangent branch is a decision\n  with consequences rather than a notational preference.\n- Cody & Waite, *Software Manual for the Elementary Functions*, chapter on `ATAN`/`ACOT` — the\n  reciprocal reduction.\n- Handbook projections `data/functions/FUNC.ACOT.json` (arity, `NumToNum` kernel signature,\n  `real_result_policy` with `arg_domain_guard=none;non_finite=allow`) and\n  `data/presence/FUNC.ACOT.json` (implementing module; no discrepancy, math-deviation or defect\n  entries).\n- Handbook [Coercion and lifting](../model/02-coercion-and-lifting.md).\n\n",
    "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.\n\n| Excel 16.0 build | Platform and CPU | Captured inputs |\n|---|---|---:|\n| 19929 | Windows, bitness not recorded, CPU not recorded | 45 |\n| 20430 | Windows, 64-bit, CPU not recorded | 16,924 |\n\n- XC-ACOT-001: build 19929 versus build 20430; 2 same-input pairs, 0 differing answers. Compared axes: excel-build. Numeric answers were compared by their recorded binary64 bits; other answers by typed value.\n\nAgreement on these compared inputs does not establish agreement on unmeasured inputs.\n\n[Recorded environments and comparison details](https://github.com/DnaCalc/ExcelFunctionsHandbook/blob/5dc75391aa5125ccc5abdb095da85950980d6fd8/content/evidence/environments/FUNC.ACOT.json).",
    "what-it-does": "\n`ACOT(number)` is the inverse cotangent: the angle whose cotangent is *number*.\n\n    acot: R -> (0, pi),    cot(acot x) = x\n\n- **Domain**: all real numbers. Unlike `ACOS` and `ASIN`, there is no restriction — `cot` maps\n  each period onto the whole real line.\n- **Range**: the open interval `(0, pi)`. Microsoft's Learn reference states the range as\n  0 to pi. Mathematically the endpoints are approached and never reached: `acot(x) -> 0+` as\n  `x -> +infinity` and `acot(x) -> pi-` as `x -> -infinity`.\n- **Monotonicity**: strictly decreasing on the whole line. `acot(-1) = 3pi/4`, `acot(0) = pi/2`,\n  `acot(1) = pi/4`.\n- **Reflection**: `acot(-x) = pi - acot(x)`. Antisymmetric about `(0, pi/2)`, like `ACOS`.\n- **Derivative**: `d/dx acot x = -1/(1 + x^2)` — bounded, never zero, and the negative of\n  `ATAN`'s. `ACOT` is smooth and well conditioned everywhere; the difficulties on this page are\n  about representation, not about conditioning.\n- **Asymptotics**: `acot(x) = 1/x - 1/(3x^3) + 1/(5x^5) - ...` for large `|x| > 1`; near zero,\n  `acot(x) = pi/2 - x + x^3/3 - ...`.\n\n### The branch convention, which is the whole point\n\nThere are two incompatible conventions for arccotangent in the literature, and Excel picks one:\n\n| Convention | Range | Behaviour at `x -> 0-` |\n|---|---|---|\n| **Continuous** (Excel, per the Learn reference) | `(0, pi)` | continuous through zero: `acot(0) = pi/2` |\n| **Odd**, i.e. `atan(1/x)` | `[-pi/2, 0) ∪ (0, pi/2]` | jumps by `pi` across zero |\n\nOn the **continuous** convention the identity is\n\n    acot(x) = pi/2 - atan(x)      for every real x\n\nwhich is smooth everywhere. On the **odd** convention `acot(x) = atan(1/x)`, which is undefined at\nzero and discontinuous across it. The two agree for `x > 0` and differ by exactly `pi` for\n`x < 0`.\n\nThis is not a pedantic distinction. `ACOT(-1)` is `3pi/4` on Excel's stated convention and\n`-pi/4` on the other, and a formula ported from a language whose `acot` is `atan(1/x)` will\nsilently be wrong by `pi` on every negative input. Abramowitz & Stegun record both conventions;\nKahan's branch-cut paper is the standard argument for treating the choice as a real decision.\n\n\n\n### Arguments\n\n\n| Argument | Meaning | Default |\n|---|---|---|\n| `number` | The cotangent of the angle you want. Required. | — |\n\nThat description is Microsoft's, from the Learn reference: \"the cotangent of the angle that you\nwant\". No constraint on the argument is documented, and none is needed.\n\nThe misunderstood position is, again, not the slot: it is that `number` is a *cotangent*, not an\nangle, and that a reader who wants \"the angle whose tangent is x\" wants `ATAN`.\n\n\n"
  },
  "signature": {
    "display": "ACOT(number)",
    "parameters": [
      {
        "description": null,
        "name": "number",
        "optional": false,
        "repeats": false
      }
    ],
    "trailing_repeats": false
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 1,
        "min": 1
      },
      "category": "Math and trigonometry functions",
      "classification": {
        "arg_preparation_profile": "ValuesOnlyPreAdapter",
        "coercion_lift_profile": "UnaryNumericScalarOrArrayElementwise",
        "determinism_class": "Deterministic",
        "error_collapse_profile": "None",
        "fec_dependency_profile": "None",
        "host_interaction_class": "None",
        "kernel_signature_class": "NumToNum",
        "rich_value_usage": "RichBlind",
        "surface_fec_dependency_profile": "RefOnly",
        "thread_safety_class": "SafePure",
        "volatility_class": "NonVolatile"
      },
      "descriptions": {
        "long": null,
        "short": "Angle in radians, from 0 to pi, whose cotangent is the given number",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns the arccotangent of a number",
        "microsoft_url": "https://support.microsoft.com/en-us/office/acot-function-dc7e5008-fe6b-402e-bdd6-2eea8383d905"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "ACOT"
        },
        {
          "locale": "bg-BG",
          "name": "ACOT"
        },
        {
          "locale": "cs-CZ",
          "name": "ACOT"
        },
        {
          "locale": "da-DK",
          "name": "ARCCOT"
        },
        {
          "locale": "de-DE",
          "name": "ACOT"
        },
        {
          "locale": "el-GR",
          "name": "ACOT"
        },
        {
          "locale": "en-AU",
          "name": "ACOT"
        },
        {
          "locale": "en-GB",
          "name": "ACOT"
        },
        {
          "locale": "en-US",
          "name": "ACOT"
        },
        {
          "locale": "es-ES",
          "name": "ACOT"
        },
        {
          "locale": "et-EE",
          "name": "ACOT"
        },
        {
          "locale": "fi-FI",
          "name": "ACOT"
        },
        {
          "locale": "fr-FR",
          "name": "ACOT"
        },
        {
          "locale": "he-IL",
          "name": "ACOT"
        },
        {
          "locale": "hr-HR",
          "name": "ACOT"
        },
        {
          "locale": "hu-HU",
          "name": "ARCCOT"
        },
        {
          "locale": "id-ID",
          "name": "ACOT"
        },
        {
          "locale": "it-IT",
          "name": "ACOT"
        },
        {
          "locale": "ja-JP",
          "name": "ACOT"
        },
        {
          "locale": "ko-KR",
          "name": "ACOT"
        },
        {
          "locale": "lt-LT",
          "name": "ACOT"
        },
        {
          "locale": "lv-LV",
          "name": "ACOT"
        },
        {
          "locale": "nb-NO",
          "name": "ACOT"
        },
        {
          "locale": "nl-NL",
          "name": "BOOGCOT"
        },
        {
          "locale": "pl-PL",
          "name": "ACOT"
        },
        {
          "locale": "pt-BR",
          "name": "ACOT"
        },
        {
          "locale": "pt-PT",
          "name": "ACOT"
        },
        {
          "locale": "ro-RO",
          "name": "ACOT"
        },
        {
          "locale": "ru-RU",
          "name": "ACOT"
        },
        {
          "locale": "sk-SK",
          "name": "ACOT"
        },
        {
          "locale": "sl-SI",
          "name": "ACOT"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "ACOT"
        },
        {
          "locale": "sv-SE",
          "name": "ARCCOT"
        },
        {
          "locale": "th-TH",
          "name": "ACOT"
        },
        {
          "locale": "tr-TR",
          "name": "ACOT"
        },
        {
          "locale": "uk-UA",
          "name": "ACOT"
        },
        {
          "locale": "vi-VN",
          "name": "ACOT"
        },
        {
          "locale": "zh-CN",
          "name": "ACOT"
        },
        {
          "locale": "zh-HK",
          "name": "ACOT"
        },
        {
          "locale": "zh-TW",
          "name": "ACOT"
        }
      ],
      "signature": {
        "display": "ACOT(number)",
        "parameters": [
          {
            "description": null,
            "name": "number",
            "optional": false,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "ACOT",
      "version_marker": null,
      "xlcall": {
        "code": "548",
        "symbol": "xlfAcot"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/acot-function-dc7e5008-fe6b-402e-bdd6-2eea8383d905"
  },
  "try_it": {
    "formula": "=ACOT(-1)"
  },
  "url": "https://handbook.dnacalc.com/functions/ACOT.html",
  "variants": [],
  "versions": [
    {
      "behaviour": "45 captured inputs are indexed for this environment. Capture dates are not recorded. This is a reading count, not a comparison with another build.",
      "excel_build": "16.0 build 19929",
      "platform": "Windows, bitness not recorded, CPU not recorded",
      "sources": [
        "https://github.com/DnaCalc/ExcelFunctionsHandbook/blob/5dc75391aa5125ccc5abdb095da85950980d6fd8/content/evidence/environments/FUNC.ACOT.json"
      ]
    },
    {
      "behaviour": "16,924 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.",
      "excel_build": "16.0 build 20430",
      "platform": "Windows, 64-bit, CPU not recorded",
      "sources": [
        "https://github.com/DnaCalc/ExcelFunctionsHandbook/blob/5dc75391aa5125ccc5abdb095da85950980d6fd8/content/evidence/environments/FUNC.ACOT.json"
      ]
    }
  ]
}