{
  "category": "Math and trigonometry functions",
  "display_name": "SECH",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.SECH",
  "implementation_state": {
    "answer_bank": {
      "excel_builds": [
        "20430"
      ],
      "larger_numeric": 0,
      "last_bit": 1,
      "matched": 30423,
      "other_mismatch": 0,
      "refused": 0,
      "rows": 30424,
      "unread": 0,
      "worst_ulp": 1
    },
    "detail": "Everything else matches (30,424 in the answer bank and 3 workbook cells). Last-bit means a finite number within 16 ULP of Excel's.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "close",
    "state_label": "Close: last-bit deviations remain",
    "summary": "Close: 1 of 30,427 recorded answers differ in the last bits, worst 1 ULP",
    "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#L71-L71",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/ported/sech.rs#L3-L7"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/math::unary",
        "ported/cosh::cosh_kernel",
        "ported/excel_numeric::binary_with",
        "ported/excel_numeric::excel_x87_add",
        "ported/excel_numeric::excel_x87_recip",
        "ported/excel_numeric/x87::add",
        "ported/excel_numeric/x87::recip"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/math.rs#L71-L71",
      "state": "close",
      "suite": null,
      "summary": "Close: 1 of 30,427 recorded answers differ in the last bits, worst 1 ULP"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.SECH.json",
  "name": "SECH",
  "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\n- **`COSH`** — the reciprocal. `SECH(x)` and `1/COSH(x)` should agree; whether they do, and\n  whether both are available where the other is not, is the natural consistency probe. `COSH`\n  overflows to `#NUM!` under the no-infinities convention while `SECH` of the same argument is a\n  perfectly ordinary small number — so `SECH` is *strictly more capable* than the expression it is\n  shorthand for, in exactly the band where it matters.\n- **`CSCH`** — the other reciprocal hyperbolic, `1/sinh`. Unlike `SECH` it *does* have a pole, at\n  `x = 0`, and it shares `SECH`'s `non_finite=allow` declaration — which for `CSCH` is a\n  substantive question rather than a benign one.\n- **`TANH`** — related by `sech²x + tanh²x = 1`, the hyperbolic Pythagorean identity, which gives\n  the alternative evaluation `sech x = √(1 − tanh²x)`. That route is well conditioned for large\n  `|x|` (where `tanh → ±1` and the subtraction cancels catastrophically — so it is in fact the\n  *worse* route there) and fine near zero. The identity is more useful in the other direction.\n- **[SEC](FUNC.SEC.md)** — the circular namesake, `sech(x) = sec(ix)`. Beyond the name and the\n  Euler numbers in their series they have almost nothing in common.\n- **There is no `ASECH`.** The inverse must be written `ACOSH(1/x)`, defined for `0 < x ≤ 1`.\n- **`2/(EXP(x)+EXP(-x))`** — the hand-written form, which overflows earlier than `SECH` and should\n  not be used.\n\n\n",
    "how-to-implement": "\n### Numerical notes\n\n\n**`sech` is a well-conditioned function, and that is unusual enough to say plainly.** Its condition\nnumber is `|x tanh x|`, which grows only linearly in `|x|` — compare the unbounded amplification of\n[SEC](FUNC.SEC.md) near its poles. There is no cancellation anywhere: the denominator\n`eˣ + e⁻ˣ` is a sum of positive terms, so no digits are lost forming it. Near zero the series is\nalternating but the terms decay fast and the value is near 1, so relative accuracy is easy. The\nonly difficulty in the entire function is *range*, not accuracy.\n\n**The premature-underflow band, and the fix.** For `|x|` beyond about 710 the correct formulation\nis not `1/cosh(x)` but\n\n    sech x = 2·e^{−|x|} / (1 + e^{−2|x|})\n\nin which every intermediate is bounded: `e^{−|x|}` underflows gracefully rather than overflowing,\nand the denominator tends to 1. This is the standard Cody & Waite treatment of the hyperbolic\nfunctions applied in the reciprocal direction, and it extends the usable domain by the full ~35\nunits and gives correctly rounded subnormals throughout. An even simpler variant for the far tail\nis `exp(ln 2 − |x|)`, which is a single exponential and is accurate to within the error of `exp`\nuntil the result underflows to zero at the true boundary.\n\nThe remaining question — one an implementation must answer explicitly — is what to return once even\nthat underflows: `+0` is the correct rounding of a positive value smaller than the smallest\nsubnormal, and it is also what the naive route returns 35 units too early. The two zeros are\nindistinguishable at the value level, which is why this defect is so easy to ship.\n\n**Small-argument accuracy.** For `|x| < 2⁻²⁶`, `sech x` rounds to exactly 1, and any implementation\nthat computes `1/cosh(x)` gets that for free because `cosh` rounds to 1 first. No special case is\nneeded, which is a pleasant contrast with almost every other function in this batch.\n\n**Evenness should be structural.** Fold the argument to `|x|` at the top of the kernel. An\nimplementation that does not, and that has any asymmetry in its exponential, will return different\nvalues for `x` and `−x` — a defect that no accuracy test looking only at magnitudes will find.\n\n\n",
    "quirks": "\n### Result and edge cases\n\n\nReturns `Number` in `(0, 1]`.\n\n- **`SECH(0)` is exactly 1**, and it is the maximum.\n- **`SECH(−x) = SECH(x)`** exactly, for every representable `x`: the function is even and any\n  reasonable implementation is symmetric by construction.\n- **Arrays.** Elementwise lift, element-local failures.\n\n\n\n### Errors\n\n\n| Error | Condition | Source |\n|---|---|---|\n| `#VALUE!` | The argument does not convert to a number | shared coercion model |\n| propagated | The argument is an error value | shared coercion model |\n\n",
    "sources": "- Microsoft, \"WorksheetFunction.Sech method (Excel)\" —\n  <https://learn.microsoft.com/en-us/office/vba/api/excel.worksheetfunction.sech> (the entire\n  documented content, including the \"angle in radians\" phrasing; no remarks, no errors).\n- Abramowitz & Stegun, *Handbook of Mathematical Functions*, section 4.5 — hyperbolic functions,\n  the Euler-number series and the Gudermannian.\n- Cody & Waite, *Software Manual for the Elementary Functions* — the bounded-intermediate\n  formulation for large arguments.\n- Handbook, [SEC](FUNC.SEC.md), [Coercion and lifting](../model/02-coercion-and-lifting.md),\n  [About implementation options](../model/07-implementation-options.md).\n- Handbook projections `data/functions/FUNC.SECH.json` (`arg_domain_guard=none`,\n  `non_finite=allow` — contrast `data/functions/FUNC.COSH.json`, which declares `non_finite=num`)\n  and `data/presence/FUNC.SECH.json` (own module, no shared surfaces, no defect streams).\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 | 39 |\n| 20430 | Windows, 64-bit, CPU not recorded | 30,424 |\n\n- XC-SECH-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.SECH.json).",
    "what-it-does": "\n`SECH(number)` returns the hyperbolic secant.\n\n    sech x = 1 / cosh x = 2 / (eˣ + e⁻ˣ)\n\n**Domain.** All real `x` — there are no poles, because `cosh x ≥ 1` everywhere. **Range.**\n`(0, 1]`, attaining 1 only at `x = 0` and approaching 0 as `|x| → ∞`. The function is even,\nsmooth, strictly decreasing in `|x|`, and asymptotically\n\n    sech x ~ 2e^{−|x|}   as |x| → ∞\n\nIts derivative is `−sech x · tanh x`, its integral is the Gudermannian function\n`gd(x) = arctan(sinh x)`, and its Maclaurin series is again the Euler-number generating function,\nthis time with alternating signs:\n\n    sech x = Σ_{n≥0} E_{2n} x^{2n} / (2n)!  =  1 − x²/2 + 5x⁴/24 − 61x⁶/720 + …\n\nconvergent for `|x| < π/2` — the radius set by the nearest *complex* pole at `iπ/2`, which is the\nonly trace the poles of [SEC](FUNC.SEC.md) leave on this function. (A&S 4.5.65.)\n\n`sech²` is also, up to normalisation, the density of the hyperbolic secant distribution and the\nderivative of `tanh`, which is why this function turns up in logistic modelling and in neural\nnetwork derivatives far more often than its trigonometric namesake turns up anywhere.\n\n**The contrast with `SEC` is the point of the page.** `SEC` is unbounded, has infinitely many\npoles, is periodic, and is refused above a large-argument threshold. `SECH` is bounded by 1, has no\npoles, no periodicity, and no threshold. They differ by an `i`.\n\n\n\n### Arguments\n\n\n| Argument | Meaning | Default |\n|---|---|---|\n| `number` | The value whose hyperbolic secant is wanted. Required. | — |\n\nMicrosoft's page describes it as \"Angle in radians\", which is the standard documentation phrasing\ninherited from the circular functions; the hyperbolic argument is not an angle and is not in\nradians — it is a dimensionless real number, or, if one insists on a geometric reading, twice the\narea of a hyperbolic sector. The wording is harmless and worth not taking literally.\n\nMicrosoft's VBA page states no remarks and no error conditions.\n\n\n"
  },
  "signature": {
    "display": "SECH(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": "Hyperbolic secant",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns the hyperbolic secant of an angle",
        "microsoft_url": "https://support.microsoft.com/en-us/office/sech-function-e05a789f-5ff7-4d7f-984a-5edb9b09556f"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "SECH"
        },
        {
          "locale": "bg-BG",
          "name": "SECH"
        },
        {
          "locale": "cs-CZ",
          "name": "SECH"
        },
        {
          "locale": "da-DK",
          "name": "SECH"
        },
        {
          "locale": "de-DE",
          "name": "SECH"
        },
        {
          "locale": "el-GR",
          "name": "SECH"
        },
        {
          "locale": "en-AU",
          "name": "SECH"
        },
        {
          "locale": "en-GB",
          "name": "SECH"
        },
        {
          "locale": "en-US",
          "name": "SECH"
        },
        {
          "locale": "es-ES",
          "name": "SECH"
        },
        {
          "locale": "et-EE",
          "name": "SECH"
        },
        {
          "locale": "fi-FI",
          "name": "SEKH"
        },
        {
          "locale": "fr-FR",
          "name": "SECH*"
        },
        {
          "locale": "he-IL",
          "name": "SECH"
        },
        {
          "locale": "hr-HR",
          "name": "SECH"
        },
        {
          "locale": "hu-HU",
          "name": "SECH"
        },
        {
          "locale": "id-ID",
          "name": "SECH"
        },
        {
          "locale": "it-IT",
          "name": "SECH"
        },
        {
          "locale": "ja-JP",
          "name": "SECH"
        },
        {
          "locale": "ko-KR",
          "name": "SECH"
        },
        {
          "locale": "lt-LT",
          "name": "SECH"
        },
        {
          "locale": "lv-LV",
          "name": "SECH"
        },
        {
          "locale": "nb-NO",
          "name": "SECH"
        },
        {
          "locale": "nl-NL",
          "name": "SECH"
        },
        {
          "locale": "pl-PL",
          "name": "SECH"
        },
        {
          "locale": "pt-BR",
          "name": "SECH"
        },
        {
          "locale": "pt-PT",
          "name": "SECH"
        },
        {
          "locale": "ro-RO",
          "name": "SECH"
        },
        {
          "locale": "ru-RU",
          "name": "SECH"
        },
        {
          "locale": "sk-SK",
          "name": "SECH"
        },
        {
          "locale": "sl-SI",
          "name": "SECH"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "SECH"
        },
        {
          "locale": "sv-SE",
          "name": "SEKH"
        },
        {
          "locale": "th-TH",
          "name": "SECH"
        },
        {
          "locale": "tr-TR",
          "name": "SECH"
        },
        {
          "locale": "uk-UA",
          "name": "SECH"
        },
        {
          "locale": "vi-VN",
          "name": "SECH"
        },
        {
          "locale": "zh-CN",
          "name": "SECH"
        },
        {
          "locale": "zh-HK",
          "name": "SECH"
        },
        {
          "locale": "zh-TW",
          "name": "SECH"
        }
      ],
      "signature": {
        "display": "SECH(number)",
        "parameters": [
          {
            "description": null,
            "name": "number",
            "optional": false,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "SECH",
      "version_marker": null,
      "xlcall": {
        "code": "555",
        "symbol": "xlfSech"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/sech-function-e05a789f-5ff7-4d7f-984a-5edb9b09556f"
  },
  "try_it": {
    "formula": "=SECH(0)"
  },
  "url": "https://handbook.dnacalc.com/functions/SECH.html",
  "variants": [],
  "versions": [
    {
      "behaviour": "39 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.SECH.json"
      ]
    },
    {
      "behaviour": "30,424 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.SECH.json"
      ]
    }
  ]
}