Statistical functions
T.DIST
Close: 1 of 5 recorded answers differ in the last bits, worst 1 ULP
Everything else matches (5 workbook cells). Last-bit means a finite number within 16 ULP of Excel's. How we measure this · See the Rust code
Local names in 40 languages
| Language | Name in Excel |
|---|---|
| Arabic | T.DIST |
| Bulgarian | T.DIST |
| Czech | T.DIST |
| Danish | T.FORDELING |
| German | T.DIST |
| Greek | T.DIST |
| English (Australia) | T.DIST |
| English (United Kingdom) | T.DIST |
| English (United States) | T.DIST |
| Spanish | DISTR.T.N |
| Estonian | T.DIST |
| Finnish | T.JAKAUMA |
| French | LOI.STUDENT.N |
| Hebrew | T.DIST |
| Croatian | T.DIST |
| Hungarian | T.ELOSZL |
| Indonesian | T.DIST |
| Italian | T.DIST |
| Japanese | T.DIST |
| Korean | T.DIST |
| Lithuanian | T.DIST |
| Latvian | T.DIST |
| Norwegian | T.DIST |
| Dutch | T.DIST |
| Polish | ROZKŁ.T |
| Portuguese (Brazil) | T.DIST |
| Portuguese (Portugal) | DIST.T |
| Romanian | T.DIST |
| Russian | СТЬЮДЕНТ.РАСП |
| Slovak | T.DIST |
| Slovenian | T.DIST |
| Serbian (Latin) | T.DIST |
| Swedish | T.FÖRD |
| Thai | T.DIST |
| Turkish | T.DAĞ |
| Ukrainian | T.DIST |
| Vietnamese | T.DIST |
| Chinese (Simplified) | T.DIST |
| Chinese (Hong Kong) | T.DIST |
| Chinese (Traditional) | T.DIST |
Names from Microsoft's support site.
What it does
T.DIST(x, deg_freedom, cumulative)
T.DIST(x, deg_freedom, cumulative) evaluates Student's t-distribution with ν degrees of
freedom — the density when cumulative is FALSE, the left-tail cumulative distribution
function when it is TRUE.
The density is
f(x; ν) = Γ((ν+1)/2) / ( sqrt(νπ) · Γ(ν/2) ) · (1 + x²/ν)^(−(ν+1)/2)
on the whole real line, for ν > 0. It is symmetric about zero, unimodal, and has tails that
decay like |x|^(−(ν+1)) — polynomially, not exponentially, which is the entire reason the
distribution exists as a separate object from the normal.
The cumulative form has no elementary closed form for general ν, but it has an exact expression
in the regularized incomplete beta function I_z(a, b):
F(x; ν) = 1 − ½ · I_{ν/(ν+x²)}(ν/2, ½) for x ≥ 0
F(x; ν) = ½ · I_{ν/(ν+x²)}(ν/2, ½) for x ≤ 0
Equivalently, if T ~ t_ν then T²/(T² + ν) ~ Beta(½, ν/2); the beta identity above is that
statement rearranged. Abramowitz & Stegun give the distribution and its integrals in section
26.7.
Domain and range: x ranges over all reals and F over (0, 1), strictly — the CDF attains
neither endpoint at any finite x. There are no poles and no branch cuts; f is real-analytic
in x for every ν > 0.
The limiting and special cases are worth keeping in view, because they are the cheapest correctness checks anyone has:
| ν | Distribution | Closed form for F |
|---|---|---|
| 1 | Standard Cauchy | ½ + arctan(x)/π |
| 2 | — | ½ · (1 + x / sqrt(x² + 2)) |
| ν → ∞ | Standard normal | Φ(x) |
Moments exist only up to order ν: the mean is 0 for ν > 1 and undefined for ν = 1, and the
variance is ν/(ν−2) for ν > 2 and infinite for 1 < ν ≤ 2. A t-distribution with one degree of
freedom has no mean at all, which is why the ν = 1 corner is a genuinely different object rather
than an extreme setting of the same one.
Arguments
| Argument | Meaning | Required |
|---|---|---|
x | The value at which the distribution is evaluated. | Yes |
deg_freedom | ν, "an integer indicating the number of degrees of freedom" (Microsoft). | Yes |
cumulative | TRUE selects the cumulative distribution function; FALSE selects the density. | Yes |
x may be negative. That is the whole point of this surface: the legacy TDIST spelling
documented a non-negative x and returned a tail area, while T.DIST is the ordinary
left-tail CDF over the full real line.
Microsoft describes deg_freedom as an integer but the T.DIST page — unlike the T.INV and
T.INV.2T pages — does not say what happens to a non-integer value. See "What has not been
checked".
The numeric slots are subject to ordinary to-number coercion; see Coercion and lifting.
Try it
Quirks
Result and edge cases
Returns Number, a probability in (0, 1) when cumulative is TRUE and a density value in
(0, f(0; ν)] when it is FALSE.
- Large positive
x, cumulative.F(x; ν)approaches 1 and, in double precision, becomes indistinguishable from 1 long before the true value reaches it. Everything informative about the upper tail has been rounded away.T.DIST.RTexists precisely to keep it, and is the surface to use for right-tail work. - Large negative
x, cumulative. The left tail underflows gracefully toward 0 and stays informative far longer than the upper tail does, because the value itself is small rather than being a small perturbation of 1. x = 0.F(0; ν) = ½exactly, for every ν, by symmetry. The density at zero isΓ((ν+1)/2) / (sqrt(νπ) Γ(ν/2)), which is1/πat ν = 1 and tends to1/sqrt(2π)as ν → ∞. Both are exact-value probes that cost nothing to run.- Symmetry.
T.DIST(−x, ν, TRUE) = 1 − T.DIST(x, ν, TRUE)andT.DIST(−x, ν, FALSE) = T.DIST(x, ν, FALSE)are exact mathematical identities. Whether Excel's published bits satisfy them is an empirical question nobody has answered here. - Very large ν. The distribution converges to the standard normal, so
T.DIST(x, ν, TRUE)should approachNORM.S.DIST(x, TRUE). How large ν has to be before the two agree to the last bit, and whether the approach is monotone in the published bits, is unprobed.
Empty, missing and error arguments follow the shared call model; see The value universe.
Errors
As documented on Microsoft's T.DIST page:
| Error | Documented condition |
|---|---|
#VALUE! | Any argument is nonnumeric. |
| unnamed error value | deg_freedom < 1. The page says only that the function "returns an error value" and that deg_freedom "needs to be at least 1". |
That second row is a documentation defect, not a summary of one. The sibling pages T.DIST.2T
and T.DIST.RT both name #NUM! for exactly the same condition; the T.DIST page declines to
name it. The Handbook records the gap rather than filling it in from the siblings — a reader who
needs the code should test for it, and a reader writing a compatibility implementation should
treat the code as unpinned by documentation.
Errors arriving in any argument propagate under the universal coercion rule. The Handbook has not verified any of this against Excel.
How to implement
Numerical notes
Three separate difficulties, and they are not the same difficulty.
The density. Evaluating Γ((ν+1)/2)/Γ(ν/2) directly overflows for moderate ν even though
the ratio is perfectly well scaled — it grows only like sqrt(ν/2). The standard remedy is
exp(lgamma((ν+1)/2) − lgamma(ν/2)), or the reciprocal of the beta function B(½, ν/2); Cody's
and the fdlibm-lineage lgamma are the usual sources for the log-gamma. The second factor wants
exp(−((ν+1)/2) · log1p(x²/ν)) rather than a literal pow(1 + x*x/ν, ...): the log1p form
keeps relative accuracy when x²/ν is small, which is exactly the region where the density is
largest and where a spreadsheet user is most likely to be looking.
The CDF. The workhorse is the regularized incomplete beta function. Numerical Recipes'
betai/betacf pair — the Lentz continued fraction for I_z(a, b), with the reflection
I_z(a,b) = 1 − I_{1−z}(b,a) applied when z > (a+1)/(a+b+2) so that the fraction is always
evaluated in its rapidly converging half — is the canonical treatment, and Cephes (incbet,
stdtr) and Boost.Math (ibeta, students_t_distribution) are the two implementations most
worth reading. For integer ν there is an alternative: A&S 26.7.3 and 26.7.4 give finite
closed-form expressions in arctan and powers of sin/cos, separately for odd and even ν.
These are exact in principle and fast, and they are also a trap — the alternating recursions in
them lose digits for large ν, which is why general-purpose libraries use the incomplete beta
instead. An implementation that switches on integer ν has to decide where to switch and be able
to defend the choice.
Which tail you compute. F(x; ν) for x > 0 written as 1 − ½ I(...) is a subtraction from
one, and the upper-tail information dies in it. A careful implementation computes the small
quantity directly — ½ I_{ν/(ν+x²)}(ν/2, ½) — and only then subtracts, and it exposes the
small quantity as its own surface. That is the design reason T.DIST.RT exists next to
T.DIST, and it is why the two are not interchangeable at the last bits even where they agree
mathematically.
Nothing here is a claim about what Excel does internally. The Handbook does not know Excel's algorithm for this surface.
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.
T.DIST · 4 lines · calc-func/src/catalogue/distributions.rs on GitHub40 t_dist "T.DIST" (3, 3) [V "x", V "deg_freedom", V "cumulative"] |s, a, sv| {
let [x, df] = nums::<2>(s, a)?;
out(s, cft::t_dist_kernel(x, df, flag(s, a, 2)?))
}
t_pdf · 19 lines · calc-func/src/ported/chi_f_t_family.rs on GitHubfn t_pdf(x: f64, deg_freedom: f64) -> Result<f64, WorksheetErrorCode> {
let v = truncate_positive_integer(deg_freedom)?;
if v == 1.0 {
// Live Excel 16.0 b20326: T.DIST(x,1,FALSE)=1/(PI()*(1+x*x)) 20/20.
// 1/PI()/(1+x*x) is 12/20; 1/(PI()+PI()*x*x) is 18/20.
return Ok(1.0 / (std::f64::consts::PI * (1.0 + x * x)));
}
if v == 2.0 {
// Live Excel 16.0 b20326: T.DIST(x,2,FALSE)=POWER(2+x*x,-1.5) 15/15.
// 1/EXP(1.5*LN) is 15/15 in Excel but only 10/15 via spilled excel_exp/log.
// excel_pow_chain is 15/15 including |x|=4,8.
return Ok(crate::ported::excel_numeric::excel_pow_chain(2.0 + x * x, -1.5));
}
let numerator = gamma((v + 1.0) / 2.0);
let denominator = (v * std::f64::consts::PI).sqrt()
* gamma(v / 2.0)
* crt_pow(1.0 + x * x / v, (v + 1.0) / 2.0);
Ok(numerator / denominator)
}
t_dist_kernel · 11 lines · calc-func/src/ported/chi_f_t_family.rs on GitHubpub fn t_dist_kernel(
x: f64,
deg_freedom: f64,
cumulative: bool,
) -> Result<f64, WorksheetErrorCode> {
if cumulative {
t_cdf(x, deg_freedom)
} else {
t_pdf(x, deg_freedom)
}
}
Kernels shared with other functions
numscatalogue/distributionstruncate_positive_integerported/chi_f_t_familyt_cdfported/chi_f_t_familybinary_withported/excel_numericexcel_pow_chainported/excel_numericexcel_x87_addported/excel_numericexcel_x87_mulported/excel_numericexcel_x87_mul_addported/excel_numericmulported/excel_numeric/x87addported/excel_numeric/x87pow2_positiveported/excel_numeric/x87_chainspow2ported/excel_numeric/x87_chainsexp_extported/excel_numeric/x87_chainsexp_withported/excel_numeric/x87_chainsexcel_expported/excel_numeric/x87_chainslog_withported/excel_numeric/x87_chainsexcel_logported/excel_numeric/x87_chainsln_gammaported/special_math_commongammaported/special_math_commonbratio_ftoiported/special_math_commonbratio_spmpar1ported/special_math_commonbratio_expargported/special_math_commonbratio_esumported/special_math_commonbratio_esum20ported/special_math_commonbratio_alnrelported/special_math_commonbratio_rlog1ported/special_math_commonbratio_gam1ported/special_math_commonbratio_gamln1ported/special_math_commonbratio_gamlnported/special_math_commonbratio_algdivported/special_math_commonbratio_bcorrported/special_math_commonbratio_gsumlnported/special_math_commonbratio_betalnported/special_math_commonbratio_betaln_60ported/special_math_commonbratio_erf_nswcported/special_math_commonbratio_erfc1ported/special_math_commonbratio_rexpported/special_math_commonbratio_psiported/special_math_commonbratio_fpserported/special_math_commonbratio_apserported/special_math_commonbratio_bpserported/special_math_commonbratio_bupported/special_math_commonbratio_brcompported/special_math_commonbratio_brcmp1ported/special_math_commonbratio_bfracported/special_math_commonbratio_bgratported/special_math_commonbratio_grat1ported/special_math_commonbratio_basymported/special_math_commonbratioported/special_math_common
Argument and result plumbing
No implementation has been published with a Handbook test suite for this function.
Version differences
No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.
Alternatives
Relationships
- T.DIST.RT is the right-tail complement:
1 − F(x; ν), computed directly rather than by subtraction, and therefore the accurate surface for small upper-tail probabilities. - T.DIST.2T is the two-tail area
P(|T| > x), defined only forx ≥ 0. - T.INV is this function's inverse in the cumulative sense:
T.INV(p, ν)is thexwithT.DIST(x, ν, TRUE) = p. T.INV.2T invertsT.DIST.2Tinstead. TDISTis the legacy compatibility spelling, and it is not this function.TDIST(x, ν, tails)takesx ≥ 0and returns a tail area — one-tailed fortails = 1, two-tailed fortails = 2— so its modern counterparts areT.DIST.RTandT.DIST.2T, notT.DIST.T.DISThas no legacy predecessor at all; the left-tail CDF and the density were both new surfaces when the dotted names arrived. Anyone mechanically rewritingTDISTtoT.DISTis changing the mathematics, not modernizing a name.NORM.S.DISTis the ν → ∞ limit;F.DISTis a relative, sinceT² ~ F(1, ν), which givesF.DIST.RT(x², 1, ν) = T.DIST.2T(x, ν)as an identity worth probing across the pair.
Named variants
No named variants are recorded yet.
Suggest a correction or contribute an implementation · For agents