Excel 16.0 build 19929
Windows, bitness not recorded, CPU not recorded
24 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
Matches all 2,712 recorded answers
Recorded: 2,709 in the answer bank and 3 workbook cells. How we measure this · See the Rust code
| Language | Name in Excel |
|---|---|
| Arabic | FACT |
| Bulgarian | FACT |
| Czech | FAKTORIÁL |
| Danish | FAKULTET |
| German | FACT |
| Greek | FACT |
| English (Australia) | FACT |
| English (United Kingdom) | FACT |
| English (United States) | FACT |
| Spanish | FACT |
| Estonian | FACT |
| Finnish | KERTOMA |
| French | FACT |
| Hebrew | FACT |
| Croatian | FACT |
| Hungarian | FAKT |
| Indonesian | FACT |
| Italian | FACT |
| Japanese | FACT |
| Korean | FACT |
| Lithuanian | FACT |
| Latvian | FACT |
| Norwegian | OPPLYSNING |
| Dutch | FACULTEIT |
| Polish | SILNIA |
| Portuguese (Brazil) | FACT |
| Portuguese (Portugal) | FACTORIAL |
| Romanian | FACT |
| Russian | ФАКТР |
| Slovak | FACT |
| Slovenian | FACT |
| Serbian (Latin) | FACT |
| Swedish | FAKULTET |
| Thai | FACT |
| Turkish | ÇARPINIM işlevi |
| Ukrainian | FACT |
| Vietnamese | FACT |
| Chinese (Simplified) | FACT |
| Chinese (Hong Kong) | FACT |
| Chinese (Traditional) | FACT |
Names from Microsoft's support site.
FACT(number)
FACT(number) returns the factorial. Microsoft's page states the definition as the product
1·2·3·…·number and states that a non-integer argument is truncated.
n! = ∏_{i=1}^{n} i, with 0! = 1
| Property | Statement |
|---|---|
| Domain (documented) | non-negative; non-integers truncated |
| Range | positive integers |
| Recurrence | n! = n · (n-1)! |
| Base case | 0! = 1 — the empty product |
| Gamma relation | n! = Γ(n+1), and Γ extends the factorial to all complex arguments except the non-positive integers |
| Growth | Stirling: n! ~ √(2πn) · (n/e)^n |
| Log form | ln(n!) = lnΓ(n+1), the quantity GAMMALN supplies |
| Exactly representable | for n ≤ 22 only |
| Largest finite | 170!; 171! exceeds the binary64 range |
Two boundaries govern this function and they are far apart. Above n = 22 the true factorial is
no longer a binary64 value, so every larger result is rounded. Above n = 170 it is not even
close — the value exceeds the format's range entirely. The whole interesting domain of FACT is
therefore the 148 integers between them, which is small enough that an implementation can simply
tabulate every correctly-rounded answer. Few functions in this Handbook have that property.
The reason 22 is the exactness limit is worth stating, because it is not obvious: n! has
n - s₂(n) trailing zero bits, where s₂(n) is the population count of n. Exact
representability needs the bit-length of n! minus those trailing zeros to fit in 53 bits, and
23! is the first factorial for which it does not.
| Argument | Meaning | Constraint (as documented) |
|---|---|---|
number | The value whose factorial is wanted. Required. | non-negative; non-integers are truncated |
Returns Number, mathematically always a positive integer.
FACT(0) — 1, documented. The empty product convention, and the value that makes the
binomial coefficient formula work at its boundaries.#NUM!. This is a genuine mathematical statement rather
than an implementation limit: Γ has poles at every non-positive integer, so (-1)! is
infinite, and the values between the poles alternate in sign with no combinatorial meaning.(-1, 0) becomes
0 and would give 1 rather than an error. Whether Excel truncates before or after the
domain check is not documented, and it is the sharpest edge case on this page.As documented on Microsoft's FACT page:
| Error | Condition |
|---|---|
#NUM! | number is negative |
| Error | Condition | Source |
|---|---|---|
#VALUE! | Non-numeric argument | Shared call model; the page's worked examples imply it, and the sibling FACTDOUBLE page states it explicitly |
#NUM! | The true result is not finite | EV-MATH-0008, which names FACT — a kind and error-code convention, no count |
The split above is deliberate: only the first row is documented on the FACT page itself.
FACT is the clearest case in this batch of a function where the best implementation is a
table, and where any cleverness is a mistake.
The argument. The whole domain is 0 … 170. That is 171 values. Storing 171 correctly
rounded doubles costs about 1.4 kilobytes, gives a correctly-rounded answer for every input, is
faster than any loop, and removes the question of accumulated error entirely. Numerical Recipes'
factrl does exactly this (with a smaller table and a log-gamma fallback), and there is no
argument for anything else on a domain this size.
What a product loop costs. Computing n! as a running product in binary64 rounds at every
step above the exactness boundary. The errors accumulate roughly as √n ulp in the best case
and linearly in the worst, so by n = 170 a naive loop can be several ulp from the correctly
rounded value. It is never catastrophic and it is entirely avoidable. Note also that the loop's
order matters: multiplying ascending and descending give different results, which is the same
op-graph question that COMBIN's evidence turns on.
What the log-gamma route costs. exp(lnΓ(n+1)) extends past 170 in the sense that it does
not overflow internally, but the answer still does, and below 170 it is markedly less accurate
than either a table or a loop — the same amplification described on
COMBINA, where a small relative error in a large logarithm becomes a large
relative error in the result. For FACT specifically there is no reason to pay it.
The one place the mathematics is genuinely subtle is the interaction of truncation with the
domain check. FACT(-0.5) truncates to 0 and is therefore in the documented domain, while
-0.5 itself is not; FACT(-1.5) truncates to -1, which is not. An implementation that
checks the sign of the raw argument and one that checks the sign of the truncated argument
disagree on exactly the interval (-1, 0). The documentation does not say which order applies.
For consumers: when a formula needs a ratio of factorials, never form the factorials.
n!/(n-k)! is a product of k terms; n!/(k!(n-k)!) is COMBIN. Both stay
finite far past where FACT stops, and both are more accurate. The presence of FACT on the
worksheet is not a licence to write the textbook formula.
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.
FACT · 1 lines · calc-func/src/catalogue/math.rs on GitHub32 fact "FACT" (1, 1) [V "number"] |s, a, sv| { unary(s, a, k::fact::fact_kernel) }
fact_reverse_product · 13 lines · calc-func/src/ported/fact.rs on GitHubfn fact_reverse_product(n: i64) -> f64 {
// Live Excel 16.0 b20326: FACT(n) is the reverse native product
// n*(n-1)*...*2 (empty product 1 for n<=1). Forward product diverges
// (FACT(170) forward misses). FACT(171) still overflows to #NUM!.
if n <= 1 {
return 1.0;
}
let mut acc = 1.0;
for k in (2..=n).rev() {
acc *= k as f64;
}
acc
}
fact_kernel · 11 lines · calc-func/src/ported/fact.rs on GitHubpub fn fact_kernel(n: f64) -> Result<f64, WorksheetErrorCode> {
// Excel checks the original sign before truncation: FACT(-0.1) is #NUM!,
// while FACTDOUBLE deliberately has a different negative-domain rule.
// Bound the product before converting to an integer, including huge inputs.
if !n.is_finite() || n >= 171.0 {
return Err(WorksheetErrorCode::Num);
}
let truncated = trunc_nonnegative(n)?;
ExcelRealPolicy::FINITE
.publish(n, fact_reverse_product(truncated))
}
unary catalogue/mathtrunc_nonnegative ported/factorial_commonNo 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 | 24 |
| 20430 | Windows, 64-bit, CPU not recorded | 2,709 |
Agreement on these compared inputs does not establish agreement on unmeasured inputs.
Recorded environments and comparison details.
Windows, bitness not recorded, CPU not recorded
24 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
2,709 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.
n·(n-2)·(n-4)·…, related by
n! = n!! · (n-1)!!. That identity is a free cross-surface test and neither page's evidence
covers it.GAMMA — the continuous extension: GAMMA(n+1) = FACT(n). Excel exposes both, and they
must agree at the integers; whether they do bitwise is unchecked and is a strong probe.GAMMALN, GAMMALN.PRECISE — the logarithm, which is what any implementation must use
above n = 170 if it wants an answer at all. LN(FACT(n)) and GAMMALN(n+1) are the two
routes to the same quantity and differ.PERMUT — the combinatorial
surfaces whose documented formulas are written in factorials and whose implementations must
not be. See the numerical notes on COMBIN for why.MULTINOMIAL — the multinomial coefficient, a ratio of factorials with the same overflow
hazard.SERIESSUM, EXP — Taylor-series machinery where factorials appear as denominators; in
that role the reciprocal 1/n! is what is wanted, and it underflows gracefully where n!
overflows abruptly.POISSON.DIST, BINOM.DIST — distributions with factorial kernels, which is why they
are implemented through log-gamma rather than through FACT.No named variants are recorded yet.
Suggest a correction or contribute an implementation · For agents