{
  "category": "Statistical functions",
  "display_name": "PERMUT",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.PERMUT",
  "implementation_state": {
    "answer_bank": {
      "excel_builds": [
        "20131",
        "20430",
        "?"
      ],
      "larger_numeric": 0,
      "last_bit": 0,
      "matched": 3432,
      "other_mismatch": 0,
      "refused": 0,
      "rows": 3432,
      "unread": 0,
      "worst_ulp": 0
    },
    "detail": "Recorded: 3,432 in the answer bank and 4 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 3,436 recorded answers",
    "workbook_corpus": {
      "cells": 4,
      "matched": 4
    }
  },
  "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#L128-L130",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/ported/permut_fn.rs#L4-L26"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/math::binary",
        "ported/excel_numeric::binary_with",
        "ported/excel_numeric::excel_x87_mul",
        "ported/excel_numeric/x87::mul",
        "ported/factorial_common::trunc_nonnegative"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/math.rs#L128-L130",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 3,436 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.PERMUT.json",
  "name": "PERMUT",
  "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- **[PERMUTATIONA](FUNC.PERMUTATIONA.md)** is ordered selection **with** replacement: `n^k`\n  rather than the falling factorial. Note the naming trap — the `A` suffix here does not mean\n  what it means in `AVERAGEA`, `COUNTA`, `MAXA` and `STDEVA`, where it marks a variant that\n  admits text and logicals. On `PERMUTATIONA` and `COMBINA` the suffix marks *repetition\n  allowed*. Two unrelated conventions share one letter.\n- **`COMBIN`** is the unordered counterpart: `COMBIN(n, k) = PERMUT(n, k) / FACT(k)`. That\n  identity is exact in the integers and only approximately reproducible in floating point,\n  which makes it a useful residual probe rather than a substitute computation.\n- **`COMBINA`** completes the two-by-two grid: ordered/unordered against\n  with/without replacement. `PERMUT` (ordered, without), `PERMUTATIONA` (ordered, with),\n  `COMBIN` (unordered, without), `COMBINA` (unordered, with).\n- **`FACT`** is the `k = n` diagonal, and `FACTDOUBLE` is unrelated despite the neighbouring\n  name.\n- **Confused with**: `COMBIN`, constantly. If order matters — podium finishes, PINs,\n  arrangements — it is `PERMUT`; if it does not — hands of cards, committees — it is `COMBIN`.\n\n\n",
    "how-to-implement": "\n### Numerical notes\n\n\n`PERMUT` looks like a function with no numerical content and is in fact a small case study in\nhow staging changes answers.\n\n**The factorial-ratio staging is wrong twice over.** Computing `n!` and `(n-k)!` and dividing\nloses in two independent ways. First, it manufactures an overflow the function does not have:\n`n!` is not representable for `n ≥ 171`, so a perfectly small `PERMUT(200, 2)` fails.\nSecond, each factorial is itself a rounded double once past `2^53`, and the quotient of two\nrounded values is not the rounded quotient — the two errors do not cancel. The evidence record\nattached to this page names exactly this staging as ruled out, reporting it as off by a\nrecorded residual on the catalogue's own witness and as spuriously overflowing beyond `n = 170`.\n\n**The product staging is the right shape, and its details are still observable.** Multiplying\nthe `k` factors accumulates one rounding per multiply, so the answer depends on:\n\n1. **Direction.** Ascending (`n-k+1` upward to `n`) and descending (`n` downward to `n-k+1`)\n   are different sequences of roundings and give different last bits once the accumulator\n   passes `2^53`. Neither is universally better; the accurate-summation intuition (combine\n   small terms first) does not transfer cleanly to products.\n2. **Working precision.** A product accumulated in 80-bit extended precision and rounded once\n   per step to 64 bits is a third answer again, distinct from a pure-double accumulation and\n   from a fully extended accumulation rounded once at the end. On x86 this is not an exotic\n   choice — it is what a legacy x87 code path does by default.\n\n**What a careful independent implementation does.** For results below `2^53` the honest answer\nis exact and any staging that avoids intermediate overflow will produce it; the correct\nstrategy is to detect that regime and return the exact integer. Above it, the choice is\nbetween reproducing a target platform's staging (the `excel-bitexact` flavour's job) and\ncomputing the correctly rounded value (the `math-correct` flavour's job) — for which the\nstandard route is `exp(lgamma(n+1) - lgamma(n-k+1))` with a corrective term, or an\nextended-precision product with a final single rounding. Those two answers differ, and the\nHandbook's position is that both are right for their stated purpose. See\n[About implementation options](../model/07-implementation-options.md).\n\n\n",
    "quirks": "\n### Result and edge cases\n\n\nReturns `Number` — an integer value where the integer is representable, and a rounded double\nwhere it is not.\n\n- **Non-integer arguments** are truncated before any validation, as documented.\n- **`k = 0`** yields the empty arrangement, `1`, for every admissible `n`.\n- **`k = n`** yields `n!` and therefore inherits the factorial's overflow wall: the largest\n  representable factorial in binary64 is `170!`, so `PERMUT(n, n)` cannot succeed for\n  `n ≥ 171`. But `PERMUT` is *not* limited to `n ≤ 170` in general — `PERMUT(1000, 3)` is a\n  small number — and an implementation that computes `n!/(n-k)!` inherits a limit the function\n  does not have. That is not hypothetical: it is one of the stagings the evidence record named\n  below explicitly rules out.\n\n\n\n### Errors\n\n\nAs documented by Microsoft on the `PERMUT` page (retrieved for this page):\n\n| Error | Documented condition |\n|---|---|\n| `#VALUE!` | `number` or `number_chosen` is nonnumeric |\n| `#NUM!` | `number ≤ 0`, or `number_chosen < 0` |\n| `#NUM!` | `number < number_chosen` |\n\nError values arriving in either argument propagate under the ordinary coercion rules; see\n[Coercion and lifting](../model/02-coercion-and-lifting.md).\n\n\n\n### A documented boundary the earlier implementation does not honour\n\n\nMicrosoft's stated condition is `number ≤ 0`, not `number < 0`. Read literally, `PERMUT(0, 0)`\nis a `#NUM!` — even though the mathematics is unambiguous that there is exactly one\narrangement of nothing chosen from nothing, and even though `PERMUT(n, 0) = 1` holds for every\nother `n`.\n\nThe Handbook publishes this as a divergence rather than picking a side, because both readings\nare defensible and neither has been checked against Excel here:\n\n- Microsoft's inequality may be a documentation infelicity — `n ≤ 0` written where `n < 0` was\n  meant — inherited from a `COMBIN`-style page where the same wording appears.\n\n\n`PERMUT(0, 0)` is therefore the single highest-value probe on this page: one cell decides\nwhich of two published descriptions of Excel is wrong.\n\n\n",
    "sources": "- Microsoft, \"PERMUT function\" —\n  <https://support.microsoft.com/en-us/office/permut-function-3bd1cb9a-2880-41ab-a197-f246a7a602d3>\n  (syntax, the integer-truncation rule, the `n!/(n-k)!` equation, and the four documented\n  error conditions including `number ≤ 0`). Retrieved for this page.\n- Handbook evidence record `EV-MATH-0008` — the \"Excel never publishes an infinity\" convention,\n  cited here for context only; `PERMUT` is not among its subjects and no claim about `PERMUT`\n  is drawn from it.\n- Abramowitz & Stegun, *Handbook of Mathematical Functions*, chapter 24 — combinatorial\n  analysis; the falling factorial and its identities.\n- Handbook, [Coercion and lifting](../model/02-coercion-and-lifting.md) and\n  [About implementation options](../model/07-implementation-options.md).\n- `data/functions/FUNC.PERMUT.json` — arity 2, `NumsToNum`, `UnaryNumericScalarOnly` coercion\n  profile, `real_result_policy … non_finite=allow`, XLL symbol `xlfPermut`.\n- `data/presence/FUNC.PERMUT.json` — implementing module\n  `earlier-implementation/permut_fn.rs`, shared with no other surface.\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 | 140 |\n| 20131 | Windows, bitness not recorded, AMD Ryzen 7 4800H with Radeon Graphics | 702 |\n| 20430 | Windows, 64-bit, CPU not recorded | 2,730 |\n\n- XC-PERMUT-001: build 19929 versus build 20131; 1 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- XC-PERMUT-002: 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.PERMUT.json).",
    "what-it-does": "\n`PERMUT(number, number_chosen)` returns the number of ordered arrangements of `number_chosen`\ndistinct objects drawn without replacement from `number` objects.\n\nWriting `n` for `number` and `k` for `number_chosen`, this is the **falling factorial**:\n\n    P(n, k) = n! / (n - k)!\n            = n · (n-1) · (n-2) · … · (n-k+1)        (k factors)\n\nThe two right-hand sides are the same integer and are *not* the same computation; the whole of\nthe Numerical notes section below is about that difference.\n\n**Domain and range.** After truncation to integers the documented domain is `n ≥ 1`, `k ≥ 0`,\n`k ≤ n`. On that domain `P(n, k)` is a positive integer, non-decreasing in `n` and, for fixed\n`n`, non-decreasing in `k` up to `k = n`. Boundary identities:\n\n    P(n, 0) = 1          the empty arrangement\n    P(n, 1) = n\n    P(n, n) = n!         = FACT(n)\n    P(n, n-1) = n!       the last factor is 1, so k = n-1 and k = n agree\n\nThe last of those is the cheapest self-consistency probe there is: two different calls that\nmust return the same integer.\n\n`P(n, k)` is exact in binary64 precisely while it is below `2^53`. Beyond that the true value\nis an integer that a double cannot name, and every implementation is returning a rounded\nanswer — which is why the *order* of the multiplications becomes observable.\n\n\n\n### Arguments\n\n\n| Argument | Meaning | Default |\n|---|---|---|\n| `number` | The size of the pool. Required. | — |\n| `number_chosen` | How many are arranged. Required. | — |\n\nMicrosoft describes both as integers and states that **both arguments are truncated to\nintegers**, so `PERMUT(5.9, 2.9)` is the same call as `PERMUT(5, 2)`. Truncation is toward\nzero, which matters only for negative inputs, and negative inputs are a documented `#NUM!`\ncondition anyway.\n\n"
  },
  "signature": {
    "display": "PERMUT(number, number_chosen)",
    "parameters": [
      {
        "description": null,
        "name": "number",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "number_chosen",
        "optional": false,
        "repeats": false
      }
    ],
    "trailing_repeats": false
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 2,
        "min": 2
      },
      "category": "Statistical functions",
      "classification": {
        "arg_preparation_profile": "ValuesOnlyPreAdapter",
        "coercion_lift_profile": "UnaryNumericScalarOnly",
        "determinism_class": "Deterministic",
        "error_collapse_profile": "None",
        "fec_dependency_profile": "None",
        "host_interaction_class": "None",
        "kernel_signature_class": "NumsToNum",
        "rich_value_usage": "RichBlind",
        "surface_fec_dependency_profile": "RefOnly",
        "thread_safety_class": "SafePure",
        "volatility_class": "NonVolatile"
      },
      "descriptions": {
        "long": null,
        "short": "Number of ordered arrangements of k items chosen from n",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns the number of permutations for a given number of objects",
        "microsoft_url": "https://support.microsoft.com/en-us/office/permut-function-3bd1cb9a-2880-41ab-a197-f246a7a602d3"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "PERMUT"
        },
        {
          "locale": "bg-BG",
          "name": "PERMUT"
        },
        {
          "locale": "cs-CZ",
          "name": "PERMUTACE"
        },
        {
          "locale": "da-DK",
          "name": "PERMUT"
        },
        {
          "locale": "de-DE",
          "name": "PERMUT"
        },
        {
          "locale": "el-GR",
          "name": "PERMUT"
        },
        {
          "locale": "en-AU",
          "name": "PERMUT"
        },
        {
          "locale": "en-GB",
          "name": "PERMUT"
        },
        {
          "locale": "en-US",
          "name": "PERMUT"
        },
        {
          "locale": "es-ES",
          "name": "PERMUTACIONES"
        },
        {
          "locale": "et-EE",
          "name": "PERMUT"
        },
        {
          "locale": "fi-FI",
          "name": "PERMUTAATIO"
        },
        {
          "locale": "fr-FR",
          "name": "PERMUTATION*"
        },
        {
          "locale": "he-IL",
          "name": "PERMUT"
        },
        {
          "locale": "hr-HR",
          "name": "PERMUT"
        },
        {
          "locale": "hu-HU",
          "name": "VARIÁCIÓK"
        },
        {
          "locale": "id-ID",
          "name": "PERMUT"
        },
        {
          "locale": "it-IT",
          "name": "PERMUT"
        },
        {
          "locale": "ja-JP",
          "name": "PERMUT"
        },
        {
          "locale": "ko-KR",
          "name": "PERMUT"
        },
        {
          "locale": "lt-LT",
          "name": "PERMUT"
        },
        {
          "locale": "lv-LV",
          "name": "PERMUT"
        },
        {
          "locale": "nb-NO",
          "name": "PERMUT"
        },
        {
          "locale": "nl-NL",
          "name": "PERMUTATIES"
        },
        {
          "locale": "pl-PL",
          "name": "PERMUTACJE"
        },
        {
          "locale": "pt-BR",
          "name": "PERMUT"
        },
        {
          "locale": "pt-PT",
          "name": "PERMUTAR"
        },
        {
          "locale": "ro-RO",
          "name": "PERMUT"
        },
        {
          "locale": "ru-RU",
          "name": "ПЕРЕСТ"
        },
        {
          "locale": "sk-SK",
          "name": "PERMUT"
        },
        {
          "locale": "sl-SI",
          "name": "PERMUT"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "PERMUT"
        },
        {
          "locale": "sv-SE",
          "name": "PERMUT"
        },
        {
          "locale": "th-TH",
          "name": "PERMUT"
        },
        {
          "locale": "tr-TR",
          "name": "PERMÜTASYON işlevi"
        },
        {
          "locale": "uk-UA",
          "name": "PERMUT"
        },
        {
          "locale": "vi-VN",
          "name": "PERMUT"
        },
        {
          "locale": "zh-CN",
          "name": "PERMUT"
        },
        {
          "locale": "zh-HK",
          "name": "PERMUT"
        },
        {
          "locale": "zh-TW",
          "name": "PERMUT"
        }
      ],
      "signature": {
        "display": "PERMUT(number, number_chosen)",
        "parameters": [
          {
            "description": null,
            "name": "number",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "number_chosen",
            "optional": false,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "PERMUT",
      "version_marker": null,
      "xlcall": {
        "code": "299",
        "symbol": "xlfPermut"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/permut-function-3bd1cb9a-2880-41ab-a197-f246a7a602d3"
  },
  "try_it": {
    "formula": "=PERMUT(5.9, 2.9)"
  },
  "url": "https://handbook.dnacalc.com/functions/PERMUT.html",
  "variants": [],
  "versions": [
    {
      "behaviour": "140 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.PERMUT.json"
      ]
    },
    {
      "behaviour": "702 captured inputs are indexed for this environment. Capture dates: 2026-07-11 to 2026-07-11. This is a reading count, not a comparison with another build.",
      "excel_build": "16.0 build 20131",
      "platform": "Windows, bitness not recorded, AMD Ryzen 7 4800H with Radeon Graphics",
      "sources": [
        "https://github.com/DnaCalc/ExcelFunctionsHandbook/blob/5dc75391aa5125ccc5abdb095da85950980d6fd8/content/evidence/environments/FUNC.PERMUT.json"
      ]
    },
    {
      "behaviour": "2,730 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.PERMUT.json"
      ]
    }
  ]
}