{
  "category": "Statistical functions",
  "display_name": "LARGE",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.LARGE",
  "implementation_state": {
    "answer_bank": null,
    "detail": "Recorded: 7 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 7 recorded answers",
    "workbook_corpus": {
      "cells": 7,
      "matched": 7
    }
  },
  "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/statistics.rs#L297-L297"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/statistics::list",
        "catalogue/statistics::sorted",
        "catalogue/statistics::nth"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/statistics.rs#L297-L297",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 7 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.LARGE.json",
  "name": "LARGE",
  "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- **[SMALL](FUNC.SMALL.md)** — the ascending mirror, with the exact index identity given\n  above. The two are the same algorithm with a reversed comparator, and an implementation that\n  does not share code between them is duplicating the delicate part twice.\n- **[MAX](FUNC.MAX.md)** / **[MIN](FUNC.MIN.md)** — the `k = 1` and `k = n` special cases,\n  with different argument shapes: `MAX` takes a variadic argument list, `LARGE` takes exactly\n  one array. `MAX` also has a documented \"returns 0 if there are no numbers\" behaviour where\n  `LARGE` errors — the two disagree deliberately on the empty case.\n- **[PERCENTILE.INC](FUNC.PERCENTILE.INC.md)** / **`PERCENTILE.EXC`**\n  / **[QUARTILE.INC](FUNC.QUARTILE.INC.md)** — the interpolating relatives. `PERCENTILE.INC`\n  at `p = (n−k)/(n−1)` equals `LARGE(array, k)` exactly, because at the knots the linear\n  interpolation is degenerate. Away from the knots they differ, and that is the whole point.\n- **[RANK.EQ](FUNC.RANK.EQ.md)** / **[RANK.AVG](FUNC.RANK.AVG.md)** — the inverse direction:\n  given a value, return its position. `RANK.EQ` and `LARGE` are inverses on data with no ties\n  and are *not* inverses when ties are present, because `RANK.EQ` collapses tied ranks while\n  `LARGE` does not.\n- **[SORT](FUNC.SORT.md)** and **[TAKE](FUNC.TAKE.md)** — the modern dynamic-array route to\n  \"the top k\", which returns all of them at once and makes the tie behaviour visible.\n- **Confused with:** `LARGE` and `MAX` when the data contain text — the scan policy decides\n  which values count, and it is the same policy for both, so a disagreement between them is a\n  signal that something else is wrong.\n\n\n",
    "how-to-implement": "\n### Numerical notes\n\n\n`LARGE` performs no arithmetic, so it has no rounding error and no residual plate worth\ndrawing. Its entire correctness question is the **comparison predicate** and the **selection\nalgorithm**.\n\n**The comparison predicate.** Selecting an order statistic requires a total order on the\nadmitted values. Three questions have to be answered and none of them is answered by\nMicrosoft's page:\n\n1. Is the comparison raw IEEE-754 `<`, or is it the tolerant, truncation-style\n   15-significant-digit comparison that Excel uses in several other families? The reference\n   engine's upstream record documents a family split on exactly this point for the criteria\n   functions. If `LARGE` were tolerant, `LARGE({0.3, 0.1+0.2}, 1)` and `LARGE({0.3, 0.1+0.2},\n   2)` would be free to return either representation; if it is exact, the two are ordered.\n2. How are `+0` and `−0` ordered? IEEE comparison calls them equal, so a stable selection\n   returns whichever came first in scan order and an unstable one may not.\n3. Excel has no NaN in its value universe, so the usual NaN-ordering trap does not arise —\n   but an implementation built on a generic float comparator has to decide what it does with\n   one anyway, and the safe choice is to make it unreachable.\n\n**The selection algorithm.** Selecting the `k`-th largest of `n` values does not require\nsorting. The classical options are:\n\n- **Full sort**, `O(n log n)` — simplest, and for spreadsheet-sized data usually fastest in\n  practice. Must be a stable or at least well-defined sort if the `±0` question above matters.\n- **Quickselect** (Hoare's FIND), expected `O(n)`, worst case `O(n²)` on adversarial input.\n  See Knuth, *The Art of Computer Programming* volume 3 §5.3.3, and Numerical Recipes §8.5,\n  which presents exactly this problem under the name \"selection of the M-th largest\".\n- **Median-of-medians** (Blum, Floyd, Pratt, Rivest, Tarjan), worst-case `O(n)`, with a\n  constant large enough that it is rarely the right choice here.\n- **A bounded heap of size `k`**, `O(n log k)` — the right choice when `k` is small and `n` is\n  a whole column, which is the common spreadsheet shape.\n\nA recomputation-heavy workbook that calls `LARGE(A:A, k)` for `k = 1…10` in ten cells sorts\nthe same column ten times unless the engine caches; that is an engine question, not a\nfunction-semantics question, and the Handbook does not assert what Excel does.\n\nThe one genuinely numerical remark: because the result is a copy of an input value, `LARGE`\ncan never introduce error, and it can never *remove* it either. `LARGE` over a column of\ncomputed values inherits whatever error those computations had, and selecting the maximum of a\nnoisy set is a biased operation — the expected maximum of `n` samples of a quantity plus noise\nexceeds the maximum of the noiseless quantity. That is a statistics observation, not an\nimplementation defect, and it is the reason \"take the best of `n` runs\" is a poor estimator.\n\n\n",
    "quirks": "\n### Result and edge cases\n\n\nReturns `Number` — one of the input values, unmodified.\n\n- **`k = 1`** coincides with [MAX](FUNC.MAX.md) over the same admitted set, and `k = n` with\n  [MIN](FUNC.MIN.md). Whether the three surfaces agree on which *bits* they return when the\n  extremum is attained by values that compare equal but differ in representation (`0` and\n  `−0`) is unverified.\n- **`k` non-integer**, `k ≤ 0`, or `k > n` → `#NUM!` as documented.\n- **A direct logical** in either slot is coerced by the direct-argument rules — `TRUE` becomes\n  `1` in both positions — while a logical inside a referenced range is ignored. This is the\n  standard asymmetry of chapter 02, and it means `LARGE(TRUE, TRUE)` is a well-formed call.\n- **Error values** in `array` propagate rather than being skipped.\n\n\n\n### Errors\n\n\n| Error | Condition | Basis |\n|---|---|---|\n| `#NUM!` | `array` is empty, or `k < 1`, or `k` exceeds the number of admitted values | Documented by Microsoft on the `LARGE` page |\n| `#VALUE!` | An argument cannot be converted — a non-numeric `k`, or a directly-passed non-numeric `array` | Shared coercion rule, chapter 02 |\n| propagated | An error value in `array` | Shared coercion rule, chapter 02 |\n\n",
    "sources": "- Knuth, *The Art of Computer Programming*, volume 3, §5.3.3 — minimum-comparison selection.\n- Press, Teukolsky, Vetterling and Flannery, *Numerical Recipes*, §8.5 — \"Selection of the\n  M-th largest\", including the heap and quickselect trade-off.\n- Blum, Floyd, Pratt, Rivest and Tarjan, *Time bounds for selection* (1973) — worst-case\n  linear selection.\n- Handbook [Coercion and lifting](../model/02-coercion-and-lifting.md) — the direct-argument\n  versus range-scan split, and the tolerant-comparison family split.\n- Handbook projections `data/functions/FUNC.LARGE.json` (arity 2, `xlfLarge`) and\n  `data/presence/FUNC.LARGE.json` (module `large_fn.rs`, unshared, no defect stream named).\n\n",
    "version-differences": "No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.",
    "what-it-does": "\n`LARGE(array, k)` returns the **k-th largest** value of the numeric data in `array`.\n\nFormally, let `x₍₁₎ ≤ x₍₂₎ ≤ … ≤ x₍ₙ₎` be the admitted values sorted ascending — the *order\nstatistics* of the sample. Then\n\n    LARGE(array, k) = x₍ₙ₋ₖ₊₁₎\n\nso `LARGE(array, 1)` is the maximum, `LARGE(array, n)` is the minimum, and `k` counts down\nfrom the top. **Ties count with multiplicity**: in `{5, 5, 3}` both `LARGE(·,1)` and\n`LARGE(·,2)` are `5`. This is the point most often missed — `LARGE` is not \"the k-th largest\n*distinct* value\", and there is no built-in that is.\n\n**Domain.** `1 ≤ k ≤ n`, where `n` is the count of numeric values actually admitted from\n`array`. `k` outside that range has no order statistic to name. **Range:** exactly one of the\ninput values — `LARGE` is a *selector*, and its result is always bit-identical to some element\nof the data. No arithmetic is performed, which is the property that distinguishes it from the\npercentile family.\n\nThat last point deserves emphasis, because it is the whole reason `LARGE` exists alongside\n[PERCENTILE.INC](FUNC.PERCENTILE.INC.md). `PERCENTILE.INC(array, p)` interpolates linearly\nbetween adjacent order statistics and can return a number that appears nowhere in the data.\n`LARGE` never does. If you need \"the third-highest actual observation\", `LARGE` is the correct\nfunction and a percentile is not.\n\nThe complementary identity with [SMALL](FUNC.SMALL.md) is exact:\n\n    LARGE(array, k) = SMALL(array, n − k + 1)\n\n\n\n### Arguments\n\n\n| Argument | Meaning | Admissible values |\n|---|---|---|\n| `array` | The data set to select from | Array or reference; required |\n| `k` | The rank, counted from the largest | Number; required; `1 ≤ k ≤ n` |\n\n`k` is a numeric slot subject to ordinary to-number coercion; `array` is a scanned collection\ngoverned by the range-scan policy. The expected handling of a non-integer `k` is truncation\ntoward zero before the range check, which is the convention the rest of the index-taking\nsurface uses, but Microsoft's page does not state it on this function and the Handbook has\nnot confirmed it. See [Coercion and lifting](../model/02-coercion-and-lifting.md).\n\nA subtlety worth stating: `n` is the count of values that survive the scan, not the number of\ncells in the range. Blanks and text in a referenced range are ignored by the usual aggregate\nscan policy, so `LARGE(A1:A10, 10)` over a column with two blanks is an out-of-range request\neven though the range has ten cells. That is a common and silent source of `#NUM!`.\n\n\n"
  },
  "signature": {
    "display": "LARGE(array, k)",
    "parameters": [
      {
        "description": null,
        "name": "array",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "k",
        "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": "Custom",
        "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": "The k-th largest value",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns the k-th largest value in a data set",
        "microsoft_url": "https://support.microsoft.com/en-us/office/large-function-3af0af19-1190-42bb-bb8b-01672ec00a64"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "LARGE"
        },
        {
          "locale": "bg-BG",
          "name": "LARGE"
        },
        {
          "locale": "cs-CZ",
          "name": "LARGE"
        },
        {
          "locale": "da-DK",
          "name": "STØRSTE"
        },
        {
          "locale": "de-DE",
          "name": "KGRÖSSTE"
        },
        {
          "locale": "el-GR",
          "name": "LARGE"
        },
        {
          "locale": "en-AU",
          "name": "LARGE"
        },
        {
          "locale": "en-GB",
          "name": "LARGE"
        },
        {
          "locale": "en-US",
          "name": "LARGE"
        },
        {
          "locale": "es-ES",
          "name": "K.ESIMO.MAYOR"
        },
        {
          "locale": "et-EE",
          "name": "LARGE"
        },
        {
          "locale": "fi-FI",
          "name": "SUURI"
        },
        {
          "locale": "fr-FR",
          "name": "GRANDE.VALEUR"
        },
        {
          "locale": "he-IL",
          "name": "LARGE"
        },
        {
          "locale": "hr-HR",
          "name": "LARGE"
        },
        {
          "locale": "hu-HU",
          "name": "NAGY"
        },
        {
          "locale": "id-ID",
          "name": "LARGE"
        },
        {
          "locale": "it-IT",
          "name": "GRANDE"
        },
        {
          "locale": "ja-JP",
          "name": "LARGE"
        },
        {
          "locale": "ko-KR",
          "name": "LARGE"
        },
        {
          "locale": "lt-LT",
          "name": "LARGE"
        },
        {
          "locale": "lv-LV",
          "name": "LARGE"
        },
        {
          "locale": "nb-NO",
          "name": "N.STØRST"
        },
        {
          "locale": "nl-NL",
          "name": "GROOTSTE"
        },
        {
          "locale": "pl-PL",
          "name": "MAX.K"
        },
        {
          "locale": "pt-BR",
          "name": "MAIOR"
        },
        {
          "locale": "pt-PT",
          "name": "MAIOR"
        },
        {
          "locale": "ro-RO",
          "name": "LARGE"
        },
        {
          "locale": "ru-RU",
          "name": "НАИБОЛЬШИЙ"
        },
        {
          "locale": "sk-SK",
          "name": "LARGE"
        },
        {
          "locale": "sl-SI",
          "name": "LARGE"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "LARGE"
        },
        {
          "locale": "sv-SE",
          "name": "STÖRSTA"
        },
        {
          "locale": "th-TH",
          "name": "LARGE"
        },
        {
          "locale": "tr-TR",
          "name": "BÜYÜK"
        },
        {
          "locale": "uk-UA",
          "name": "LARGE"
        },
        {
          "locale": "vi-VN",
          "name": "LARGE"
        },
        {
          "locale": "zh-CN",
          "name": "LARGE"
        },
        {
          "locale": "zh-HK",
          "name": "LARGE"
        },
        {
          "locale": "zh-TW",
          "name": "LARGE"
        }
      ],
      "signature": {
        "display": "LARGE(array, k)",
        "parameters": [
          {
            "description": null,
            "name": "array",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "k",
            "optional": false,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "LARGE",
      "version_marker": null,
      "xlcall": {
        "code": "325",
        "symbol": "xlfLarge"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/large-function-3af0af19-1190-42bb-bb8b-01672ec00a64"
  },
  "try_it": {
    "formula": "=LARGE({1;5;3},2)"
  },
  "url": "https://handbook.dnacalc.com/functions/LARGE.html",
  "variants": [],
  "versions": []
}