{
  "category": "Math and trigonometry functions",
  "display_name": "FACTDOUBLE",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.FACTDOUBLE",
  "implementation_state": {
    "answer_bank": {
      "excel_builds": [
        "20430"
      ],
      "larger_numeric": 0,
      "last_bit": 0,
      "matched": 2710,
      "other_mismatch": 0,
      "refused": 0,
      "rows": 2710,
      "unread": 0,
      "worst_ulp": 0
    },
    "detail": "Recorded: 2,710 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 2,713 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#L118-L121",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/ported/factdouble.rs#L5-L9",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/ported/factorial_common.rs#L3-L8",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/ported/factorial_common.rs#L24-L37"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/math::unary"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/math.rs#L118-L121",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 2,713 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.FACTDOUBLE.json",
  "name": "FACTDOUBLE",
  "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- **[FACT](FUNC.FACT.md)** — joined by `n! = n!! · (n-1)!!`, a free cross-surface identity that\n  neither page's evidence covers and that requires no oracle to test.\n- **`GAMMA`, `GAMMALN`** — the odd branch is a half-integer gamma value: `(2k-1)!! = 2^k\n  Γ(k+½)/√π`. Excel exposes `GAMMA`, so `FACTDOUBLE(2k-1)` and\n  `2^k · GAMMA(k+0.5) / SQRT(PI())` are two routes to one number, across two surfaces with\n  different substrates. That is a strong probe and it is unused.\n- **`SQRTPI`** — appears in the same identity, and exists on the worksheet surface precisely\n  because `√π` shows up wherever half-integer gammas do.\n- **[COMBIN](FUNC.COMBIN.md), `MULTINOMIAL`** — the other combinatorial surfaces with factorial\n  overflow hazards. The central binomial coefficient is\n  `C(2k, k) = 2^k · (2k-1)!! / k!`, another cross-surface bridge.\n- **`BESSELJ`, `BESSELY`, `BESSELI`, `BESSELK`** — their series coefficients are double\n  factorials; the odd branch is where it appears.\n- **`SERIESSUM`** — the natural consumer, for the same reason.\n\n\n",
    "how-to-implement": "\n### Numerical notes\n\n\nThe two branches deserve different implementations, and the reason is a fact about binary64\nrather than about combinatorics.\n\n**The even branch is free.** `(2k)!! = 2^k · k!`. Multiplication by a power of two is exact in\nbinary64 — it adjusts the exponent field and touches no significand bit — so the even branch is\nexactly as accurate as `FACT` is, and exactly representable for the same `k`. That is why the\nexactness boundary sits at `n = 44`: it is `2 × 22`, and 22 is the largest `k` with `k!`\nexactly representable. An implementation that computes the even branch as a product loop throws\nthis away for nothing; computing it as `2^k · FACT(k)` inherits `FACT`'s accuracy and the\nscaling costs no error at all.\n\n**The odd branch is not free.** `(2k+1)!! = (2k+1)!/(2^k k!)` is a genuine ratio, and its\nexactness boundary is much lower — `n = 29` — because the odd product accumulates factors with\nno trailing zero bits at all. Odd numbers are odd; the product of `k` of them has no factor of\ntwo to give it trailing zeros, so it consumes significand bits at full rate. This asymmetry is\nthe single most useful implementation fact on this page and it is invisible from the\ndocumentation.\n\n**The domain is small enough to tabulate — twice.** There are 151 even arguments up to `300`\nand 150 odd ones up to `299`, so 301 correctly rounded doubles cover the entire function. As on\n[FACT](FUNC.FACT.md), a table is faster than a loop, exact where exactness is possible, and\ncorrectly rounded everywhere else. There is no reason to ship anything else.\n\n**What a product loop costs.** Rounding at every step, accumulating roughly as the square root\nof the number of factors in the best case. For the odd branch at `n = 299` that is 150\nmultiplications, and a few ulp of drift by the end is unremarkable. Ascending and descending\nloops give different answers, which is the same op-graph question\n[COMBIN](FUNC.COMBIN.md)'s evidence turns on — and unlike `COMBIN`, here the correct answer is\nknown independently, so the question is decidable without an oracle for every argument.\n\n**For consumers**: the double factorial is almost always wanted inside a ratio — a Legendre\ncoefficient, a Bessel term, a sphere volume — and the ratio is better computed by its own\nrecurrence than by dividing two `FACTDOUBLE` results. `(2k+1)!!/(2k)!!` stays around `√(2k/π)`\nfor all `k`, while both halves overflow past 300.\n\n\n",
    "quirks": "\n### Result and edge cases\n\n\nReturns `Number`, mathematically always a positive integer.\n\n- **`FACTDOUBLE(0)` and `FACTDOUBLE(1)`** — both 1, by the empty and singleton product\n  conventions. Microsoft's page states the negative rule but does not state these two values\n  explicitly; they follow from the printed product forms read at their boundaries.\n- **`FACTDOUBLE(-1)`** — **a documented divergence from the standard convention.** In the\n  mathematical literature `(-1)!! = 1`, and that convention is not decorative: it is what makes\n  the recurrence `n!! = n·(n-2)!!` and the gamma relation extend correctly, and it is used in the\n  series expansions the odd branch appears in. Microsoft's page documents negative arguments as\n  `#NUM!`, which excludes `-1`. Either Excel refuses a value the literature defines, or the\n  documentation is broader than the implementation. The Handbook has not checked, and this is\n  the first probe below.\n- **Fractional arguments** — truncate. As on [FACT](FUNC.FACT.md), whether the domain check\n  sees the raw or the truncated argument decides the interval `(-1, 0)`, and the documentation\n  does not say.\n- **Parity is decided after truncation**, necessarily, since a fractional argument has no\n  parity. That means `FACTDOUBLE(7.9)` follows the odd branch.\n- **Above the exactness boundaries** — the result is rounded. Note the boundaries are *far*\n  apart for the two branches: the even branch stays exact to `44` and the odd branch only to\n  `29`. See the numerical notes for why.\n\n\n\n### Errors\n\n\nAs documented on Microsoft's `FACTDOUBLE` page:\n\n| Error | Condition |\n|---|---|\n| `#NUM!` | `number` is negative |\n| `#VALUE!` | `number` is non-numeric |\n\n| Error | Condition | Source |\n|---|---|---|\n| `#NUM!` | The true result is not finite | `EV-MATH-0008`, which names `FACTDOUBLE` — a kind and error-code convention, no count |\n\n\n",
    "sources": "- Handbook evidence records `EV-MATH-0018` (the spot check, with its scope-trap warning about\n  the upstream catalogue row header) and `EV-MATH-0008` (the FINITE error-code convention, no\n  count). Read both reader warnings.\n- Abramowitz & Stegun, chapter 6, in particular 6.1.12 — the half-integer gamma relation; and\n  the series in chapters 8 and 9 where the odd branch appears.\n- Press et al., *Numerical Recipes* — the tabulation strategy.\n- Muller et al., *Handbook of Floating-Point Arithmetic* — exactness of power-of-two scaling.\n- Handbook, [FACT](FUNC.FACT.md) and [COMBIN](FUNC.COMBIN.md);\n  [Coercion and lifting](../model/02-coercion-and-lifting.md).\n- Handbook projections `data/functions/FUNC.FACTDOUBLE.json` (the `non_finite=num` axis value)\n  and `data/presence/FUNC.FACTDOUBLE.json` (implementing module and the two defect streams that\n  mention it).\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 | 29 |\n| 20430 | Windows, 64-bit, CPU not recorded | 2,710 |\n\n- XC-FACTDOUBLE-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.FACTDOUBLE.json).",
    "what-it-does": "\n`FACTDOUBLE(number)` returns the double factorial: the product of the argument with every\nsecond integer below it, down to 2 or to 1. Microsoft's page gives both branches:\n\n    n!! = n·(n-2)·(n-4)·…·4·2    for even n\n    n!! = n·(n-2)·(n-4)·…·3·1    for odd n\n\nThe name is misleading and worth clearing up once: `n!!` is **not** `(n!)!`, and it is not\n`2·n!`. It is a product with every other factor removed.\n\n| Property | Statement |\n|---|---|\n| Domain (documented) | non-negative; non-integers truncated |\n| Range | positive integers |\n| Recurrence | `n!! = n · (n-2)!!` |\n| Base cases | `0!! = 1` and `1!! = 1` (empty and singleton products) |\n| Even closed form | `(2k)!! = 2^k · k!` |\n| Odd closed form | `(2k+1)!! = (2k+1)! / (2^k · k!)` |\n| Bridge to factorial | `n! = n!! · (n-1)!!` |\n| Gamma relation | `(2k-1)!! = 2^k · Γ(k + ½) / √π` (A&S 6.1.12) |\n| Exactly representable | even `n ≤ 44`; odd `n ≤ 29` |\n| Largest finite | `300!!` for even, `299!!` for odd |\n\nThe two branches are genuinely different objects. The even branch is a factorial scaled by a\npower of two — which in binary64 costs *nothing*, since scaling by `2^k` only shifts the\nexponent field. The odd branch is a ratio, and it is the one that appears in the coefficients of\nLegendre polynomials, in the Wallis product, in Bessel-function series and in the volume of the\n`n`-sphere. Half of the reason this function exists on a worksheet is the odd branch.\n\n\n\n### Arguments\n\n\n| Argument | Meaning | Constraint (as documented) |\n|---|---|---|\n| `number` | The value whose double factorial is wanted. Required. | non-negative; non-integers truncated |\n\n"
  },
  "signature": {
    "display": "FACTDOUBLE(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": "Custom",
        "rich_value_usage": "RichBlind",
        "surface_fec_dependency_profile": "RefOnly",
        "thread_safety_class": "SafePure",
        "volatility_class": "NonVolatile"
      },
      "descriptions": {
        "long": null,
        "short": "Double factorial: the product of every second number down from n",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns the double factorial of a number",
        "microsoft_url": "https://support.microsoft.com/en-us/office/factdouble-function-e67697ac-d214-48eb-b7b7-cce2589ecac8"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "bg-BG",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "cs-CZ",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "da-DK",
          "name": "DOBBELT.FAKULTET"
        },
        {
          "locale": "de-DE",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "el-GR",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "en-AU",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "en-GB",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "en-US",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "es-ES",
          "name": "FACT.DOBLE"
        },
        {
          "locale": "et-EE",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "fi-FI",
          "name": "KERTOMA.OSA"
        },
        {
          "locale": "fr-FR",
          "name": "FACTDOUBLE*"
        },
        {
          "locale": "he-IL",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "hr-HR",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "hu-HU",
          "name": "FAKTDUPLA"
        },
        {
          "locale": "id-ID",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "it-IT",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "ja-JP",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "ko-KR",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "lt-LT",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "lv-LV",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "nb-NO",
          "name": "DOBBELFAKT"
        },
        {
          "locale": "nl-NL",
          "name": "DUBBELE.FACULTEIT"
        },
        {
          "locale": "pl-PL",
          "name": "SILNIA.DWUKR"
        },
        {
          "locale": "pt-BR",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "pt-PT",
          "name": "FACTDUPLO"
        },
        {
          "locale": "ro-RO",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "ru-RU",
          "name": "ДВФАКТР"
        },
        {
          "locale": "sk-SK",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "sl-SI",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "sv-SE",
          "name": "DUBBELFAKULTET"
        },
        {
          "locale": "th-TH",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "tr-TR",
          "name": "ÇİFTFAKTÖR işlevi"
        },
        {
          "locale": "uk-UA",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "vi-VN",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "zh-CN",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "zh-HK",
          "name": "FACTDOUBLE"
        },
        {
          "locale": "zh-TW",
          "name": "FACTDOUBLE"
        }
      ],
      "signature": {
        "display": "FACTDOUBLE(number)",
        "parameters": [
          {
            "description": null,
            "name": "number",
            "optional": false,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "FACTDOUBLE",
      "version_marker": null,
      "xlcall": {
        "code": "415",
        "symbol": "xlfFactdouble"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/factdouble-function-e67697ac-d214-48eb-b7b7-cce2589ecac8"
  },
  "try_it": {
    "formula": "=FACTDOUBLE(0)"
  },
  "url": "https://handbook.dnacalc.com/functions/FACTDOUBLE.html",
  "variants": [],
  "versions": [
    {
      "behaviour": "29 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.FACTDOUBLE.json"
      ]
    },
    {
      "behaviour": "2,710 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.FACTDOUBLE.json"
      ]
    }
  ]
}