Excel 16.0 build 19929
Windows, bitness not recorded, CPU not recorded
39 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: 1 of 30,427 recorded answers differ in the last bits, worst 1 ULP
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. How we measure this · See the Rust code
| Language | Name in Excel |
|---|---|
| Arabic | SECH |
| Bulgarian | SECH |
| Czech | SECH |
| Danish | SECH |
| German | SECH |
| Greek | SECH |
| English (Australia) | SECH |
| English (United Kingdom) | SECH |
| English (United States) | SECH |
| Spanish | SECH |
| Estonian | SECH |
| Finnish | SEKH |
| French | SECH |
| Hebrew | SECH |
| Croatian | SECH |
| Hungarian | SECH |
| Indonesian | SECH |
| Italian | SECH |
| Japanese | SECH |
| Korean | SECH |
| Lithuanian | SECH |
| Latvian | SECH |
| Norwegian | SECH |
| Dutch | SECH |
| Polish | SECH |
| Portuguese (Brazil) | SECH |
| Portuguese (Portugal) | SECH |
| Romanian | SECH |
| Russian | SECH |
| Slovak | SECH |
| Slovenian | SECH |
| Serbian (Latin) | SECH |
| Swedish | SEKH |
| Thai | SECH |
| Turkish | SECH |
| Ukrainian | SECH |
| Vietnamese | SECH |
| Chinese (Simplified) | SECH |
| Chinese (Hong Kong) | SECH |
| Chinese (Traditional) | SECH |
Names from Microsoft's support site.
SECH(number)
SECH(number) returns the hyperbolic secant.
sech x = 1 / cosh x = 2 / (eˣ + e⁻ˣ)
Domain. All real x — there are no poles, because cosh x ≥ 1 everywhere. Range.
(0, 1], attaining 1 only at x = 0 and approaching 0 as |x| → ∞. The function is even,
smooth, strictly decreasing in |x|, and asymptotically
sech x ~ 2e^{−|x|} as |x| → ∞
Its derivative is −sech x · tanh x, its integral is the Gudermannian function
gd(x) = arctan(sinh x), and its Maclaurin series is again the Euler-number generating function,
this time with alternating signs:
sech x = Σ_{n≥0} E_{2n} x^{2n} / (2n)! = 1 − x²/2 + 5x⁴/24 − 61x⁶/720 + …
convergent for |x| < π/2 — the radius set by the nearest complex pole at iπ/2, which is the
only trace the poles of SEC leave on this function. (A&S 4.5.65.)
sech² is also, up to normalisation, the density of the hyperbolic secant distribution and the
derivative of tanh, which is why this function turns up in logistic modelling and in neural
network derivatives far more often than its trigonometric namesake turns up anywhere.
The contrast with SEC is the point of the page. SEC is unbounded, has infinitely many
poles, is periodic, and is refused above a large-argument threshold. SECH is bounded by 1, has no
poles, no periodicity, and no threshold. They differ by an i.
| Argument | Meaning | Default |
|---|---|---|
number | The value whose hyperbolic secant is wanted. Required. | — |
Microsoft's page describes it as "Angle in radians", which is the standard documentation phrasing inherited from the circular functions; the hyperbolic argument is not an angle and is not in radians — it is a dimensionless real number, or, if one insists on a geometric reading, twice the area of a hyperbolic sector. The wording is harmless and worth not taking literally.
Microsoft's VBA page states no remarks and no error conditions.
Returns Number in (0, 1].
SECH(0) is exactly 1, and it is the maximum.SECH(−x) = SECH(x) exactly, for every representable x: the function is even and any
reasonable implementation is symmetric by construction.| Error | Condition | Source |
|---|---|---|
#VALUE! | The argument does not convert to a number | shared coercion model |
| propagated | The argument is an error value | shared coercion model |
sech is a well-conditioned function, and that is unusual enough to say plainly. Its condition
number is |x tanh x|, which grows only linearly in |x| — compare the unbounded amplification of
SEC near its poles. There is no cancellation anywhere: the denominator
eˣ + e⁻ˣ is a sum of positive terms, so no digits are lost forming it. Near zero the series is
alternating but the terms decay fast and the value is near 1, so relative accuracy is easy. The
only difficulty in the entire function is range, not accuracy.
The premature-underflow band, and the fix. For |x| beyond about 710 the correct formulation
is not 1/cosh(x) but
sech x = 2·e^{−|x|} / (1 + e^{−2|x|})
in which every intermediate is bounded: e^{−|x|} underflows gracefully rather than overflowing,
and the denominator tends to 1. This is the standard Cody & Waite treatment of the hyperbolic
functions applied in the reciprocal direction, and it extends the usable domain by the full ~35
units and gives correctly rounded subnormals throughout. An even simpler variant for the far tail
is exp(ln 2 − |x|), which is a single exponential and is accurate to within the error of exp
until the result underflows to zero at the true boundary.
The remaining question — one an implementation must answer explicitly — is what to return once even
that underflows: +0 is the correct rounding of a positive value smaller than the smallest
subnormal, and it is also what the naive route returns 35 units too early. The two zeros are
indistinguishable at the value level, which is why this defect is so easy to ship.
Small-argument accuracy. For |x| < 2⁻²⁶, sech x rounds to exactly 1, and any implementation
that computes 1/cosh(x) gets that for free because cosh rounds to 1 first. No special case is
needed, which is a pleasant contrast with almost every other function in this batch.
Evenness should be structural. Fold the argument to |x| at the top of the kernel. An
implementation that does not, and that has any asymmetry in its exponential, will return different
values for x and −x — a defect that no accuracy test looking only at magnitudes will find.
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.
SECH · 1 lines · calc-func/src/catalogue/math.rs on GitHub17 sech "SECH" (1, 1) [V "number"] |s, a, sv| { unary(s, a, k::sech::sech_kernel) }
sech_kernel · 5 lines · calc-func/src/ported/sech.rs on GitHubpub fn sech_kernel(n: f64) -> Result<f64, WorksheetErrorCode> {
// Live Excel 16.0 b20326: SECH(x)=1/COSH(x) 40/40 on the COSH EXP-pair grid.
let result = crate::ported::excel_numeric::excel_x87_recip(crate::ported::cosh::cosh_kernel(n));
Ok(if result.abs() < f64::MIN_POSITIVE { 0.0 } else { result })
}
unary catalogue/mathcosh_kernel ported/coshbinary_with ported/excel_numericexcel_x87_add ported/excel_numericexcel_x87_recip ported/excel_numericadd ported/excel_numeric/x87recip 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 | 39 |
| 20430 | Windows, 64-bit, CPU not recorded | 30,424 |
Agreement on these compared inputs does not establish agreement on unmeasured inputs.
Recorded environments and comparison details.
Windows, bitness not recorded, CPU not recorded
39 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
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.
COSH — the reciprocal. SECH(x) and 1/COSH(x) should agree; whether they do, and
whether both are available where the other is not, is the natural consistency probe. COSH
overflows to #NUM! under the no-infinities convention while SECH of the same argument is a
perfectly ordinary small number — so SECH is strictly more capable than the expression it is
shorthand for, in exactly the band where it matters.CSCH — the other reciprocal hyperbolic, 1/sinh. Unlike SECH it does have a pole, at
x = 0, and it shares SECH's non_finite=allow declaration — which for CSCH is a
substantive question rather than a benign one.TANH — related by sech²x + tanh²x = 1, the hyperbolic Pythagorean identity, which gives
the alternative evaluation sech x = √(1 − tanh²x). That route is well conditioned for large
|x| (where tanh → ±1 and the subtraction cancels catastrophically — so it is in fact the
worse route there) and fine near zero. The identity is more useful in the other direction.sech(x) = sec(ix). Beyond the name and the
Euler numbers in their series they have almost nothing in common.ASECH. The inverse must be written ACOSH(1/x), defined for 0 < x ≤ 1.2/(EXP(x)+EXP(-x)) — the hand-written form, which overflows earlier than SECH and should
not be used.No named variants are recorded yet.
Suggest a correction or contribute an implementation · For agents