{
  "category": "Statistical functions",
  "display_name": "MEDIAN",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.MEDIAN",
  "implementation_state": {
    "answer_bank": {
      "excel_builds": [
        "20430"
      ],
      "larger_numeric": 0,
      "last_bit": 0,
      "matched": 43412,
      "other_mismatch": 0,
      "refused": 0,
      "rows": 43412,
      "unread": 0,
      "worst_ulp": 0
    },
    "detail": "Recorded: 43,412 in the answer bank and 8 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 43,420 recorded answers",
    "workbook_corpus": {
      "cells": 8,
      "matched": 8
    }
  },
  "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#L260-L276"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/statistics::all",
        "catalogue/statistics::direct_first",
        "catalogue/statistics::sorted"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/statistics.rs#L260-L276",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 43,420 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.MEDIAN.json",
  "name": "MEDIAN",
  "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- **[AVERAGE](FUNC.AVERAGE.md)** — the other location statistic, with the same coercion split\n  and a completely different robustness profile. Comparing the two on the same data is the\n  standard skewness diagnostic: `MEDIAN < AVERAGE` indicates right skew.\n- **[PERCENTILE.INC](FUNC.PERCENTILE.INC.md)** at `p = 0.5` and\n  **[QUARTILE.INC](FUNC.QUARTILE.INC.md)** at `quart = 2` compute the same quantity by the same\n  interpolation convention, so all three must agree. They are separate registered surfaces and\n  may reach the answer by different code; whether they agree in bits is a first-class question\n  the Handbook has not settled. **`PERCENTILE.EXC`** at `p = 0.5` also\n  equals the median, because the two percentile conventions coincide exactly at the centre —\n  which makes the centre a poor place to test the difference between them, and a good place to\n  test that they agree.\n- **[LARGE](FUNC.LARGE.md)** / **[SMALL](FUNC.SMALL.md)** — the general order-statistic\n  selectors. On an odd count, `MEDIAN` equals `LARGE(array, (n+1)/2)` exactly; on an even count\n  it does not equal any `LARGE`.\n- **[MODE.SNGL](FUNC.MODE.SNGL.md)** / **`MODE.MULT`** — the third classical\n  measure of centre. Mean, median and mode answer different questions and coincide only for\n  symmetric unimodal data.\n- **[TRIMMEAN](FUNC.TRIMMEAN.md)** — the tunable compromise between mean and median, discarding\n  a proportion from each tail.\n- **[SUBTOTAL](FUNC.SUBTOTAL.md)** (function numbers 12 and 112) and\n  **[AGGREGATE](FUNC.AGGREGATE.md)** (function number 12) — the filter-aware and error-skipping\n  medians. `AGGREGATE` is the only route to a median that ignores error values.\n- **Confused with:** \"the middle cell of the range\", which is what a reader sometimes assumes\n  when the data are already sorted in the sheet — the two coincide only by accident, and stop\n  coinciding the moment a blank appears.\n\n\n",
    "how-to-implement": "\n### Numerical notes\n\n\n`MEDIAN` divides into a **selection** problem and, on even counts, a **one-operation\narithmetic** problem. Both are small and both have a right answer.\n\n**Selection.** Finding the middle order statistic does not require a full sort. The classical\nroutes are quickselect (expected linear, quadratic worst case), the median-of-medians\nalgorithm of Blum, Floyd, Pratt, Rivest and Tarjan (worst-case linear), and simply sorting\n(`O(n log n)`, and usually fastest at spreadsheet sizes). Knuth's *The Art of Computer\nProgramming* volume 3 §5.3.3 treats minimum-comparison selection; Numerical Recipes §8.5\npresents exactly this problem, including the two-element case that even counts require. An even\ncount needs **both** middle elements, which a naive single-selection routine does not give —\nrunning quickselect twice is wasteful and a single partition pass can yield both.\n\n**The average of two.** This is the only arithmetic in the function and it has three\nformulations that are not equivalent in floating point:\n\n    (a + b) / 2          overflows when |a + b| exceeds the largest double\n    a/2 + b/2            never overflows; can underflow both halves to zero for subnormals\n    a + (b − a)/2        never overflows; exact for a == b; the usual recommendation\n\nThe third is the standard \"midpoint without overflow\" formula and is what a careful\nimplementation uses; it also guarantees the result lies in `[min(a,b), max(a,b)]`, which the\nfirst formulation does *not* guarantee under directed rounding. For a median that must be\n`a` when `a == b`, only the third form is exact by construction. The discussion in Sterbenz's\n*Floating-Point Computation* and in Higham's *Accuracy and Stability of Numerical Algorithms*\n(chapter 2, on the perils of naive averaging) covers the general case; the same reasoning is\nwhy `(low + high)/2` is the famous binary-search overflow bug.\n\nFor ordinary spreadsheet data all three agree to the last bit, and the difference appears only\nat the extremes of the exponent range. That makes the extremes the only place a residual plate\nfor `MEDIAN` would show anything, and it makes them worth probing precisely because nothing\nelse will reveal which formulation is in use.\n\n**Comparison predicate.** The selection needs a total order, with the same open questions as on\n[LARGE](FUNC.LARGE.md): raw IEEE `<` versus a tolerant truncation-style comparison, and the\n`±0` tie. For `MEDIAN` a tolerant comparator could reorder near-equal values and thereby change\n*which* two values are averaged on an even count — a slightly larger consequence than for a\npure selector.\n\n**Robustness is not stability.** The median's `50%` breakdown point is a statistical property\nof the estimator, not a numerical one. A median computed by a numerically careless route is\nstill a median; a median of badly-computed inputs is still garbage. The two robustness stories\nare independent and are frequently conflated.\n\n\n",
    "quirks": "\n### Result and edge cases\n\n\nReturns `Number`.\n\n- **`n = 1`** — the single value, returned unchanged.\n- **`n = 2`** — the arithmetic mean of the two, which is where the rounding question below\n  first bites.\n- **Ties and repeated values** need no special handling; multiplicity is preserved by the\n  ordering and the middle position is well defined regardless.\n- **Very large values.** `MEDIAN` over two values near the largest finite double is the\n  overflow probe: `(a + b)/2` overflows to infinity where `a + (b − a)/2` does not. Excel has\n  no infinity in its published value universe, so an implementation that overflows internally\n  must produce *something* — a `#NUM!`, a saturated value, or a correct answer, depending on\n  how the mean is formed. Which one is unverified and is on the probe list.\n- **`+0` and `−0`.** On an odd count the returned representation is whichever value was\n  selected; on an even count `(+0 + −0)/2` is `+0` under round-to-nearest, so the sign\n  information is destroyed. Observable through `1/MEDIAN(...)`.\n- **Arrays** are consumed by scanning, not lifted elementwise; `MEDIAN` is not a lift kernel.\n\n\n",
    "sources": "- Knuth, *The Art of Computer Programming*, volume 3, §5.3.3 — selection.\n- Press, Teukolsky, Vetterling and Flannery, *Numerical Recipes*, §8.5 — selection, including\n  simultaneous selection of two adjacent order statistics.\n- Blum, Floyd, Pratt, Rivest and Tarjan, *Time bounds for selection* (1973).\n- Sterbenz, *Floating-Point Computation*; and Higham, *Accuracy and Stability of Numerical\n  Algorithms*, 2nd ed., chapter 2 — the analysis of naive averaging and the overflow-safe\n  midpoint.\n- Handbook [Coercion and lifting](../model/02-coercion-and-lifting.md) — the direct-argument\n  versus range-scan split.\n\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| 20430 | Windows, 64-bit, CPU not recorded | 43,412 |\n\nThe record contains no same-input comparison between these environments. Reading different inputs on different builds does not establish either a version change or cross-build agreement.\n\n[Recorded environments and comparison details](https://github.com/DnaCalc/ExcelFunctionsHandbook/blob/5dc75391aa5125ccc5abdb095da85950980d6fd8/content/evidence/environments/FUNC.MEDIAN.json).",
    "what-it-does": "\n`MEDIAN(number1, [number2], …)` returns the middle value of the numeric data it admits.\n\nLet `x₍₁₎ ≤ x₍₂₎ ≤ … ≤ x₍ₙ₎` be the order statistics of the admitted values. Then\n\n    n odd :   MEDIAN = x₍₍ₙ₊₁₎/₂₎\n    n even:   MEDIAN = ( x₍ₙ/₂₎ + x₍ₙ/₂₊₁₎ ) / 2\n\nMicrosoft states the even case directly: \"If there is an even number of numbers in the set,\nthen MEDIAN calculates the average of the two numbers in the middle.\" The documented worked\nexample is `MEDIAN({2, 3, 3, 5, 7, 10}) = 4`, the average of `3` and `5`.\n\nTwo consequences that are the whole character of the function:\n\n1. **On an odd count `MEDIAN` is a selector** — its result is bit-identical to one of the\n   inputs, with no arithmetic performed. **On an even count it is not**: it returns a mean of\n   two data points, which need not be in the data and *is* subject to floating-point rounding.\n   `MEDIAN` is therefore the one member of the order-statistic group whose answer can differ in\n   the last bits between two correct implementations. See Numerical notes.\n2. **The median is the minimiser of mean absolute deviation**, `argmin_c Σ|xᵢ − c|`, as the\n   mean is the minimiser of mean squared deviation. On an even count the minimiser is not\n   unique — every point of the closed interval `[x₍ₙ/₂₎, x₍ₙ/₂₊₁₎]` achieves the same total\n   absolute deviation — and the mid-average convention is a *choice* of representative from\n   that interval, not a derivation. Other conventions (lower median, upper median,\n   interpolated median) are equally defensible and are used elsewhere; this one is Excel's, and\n   it agrees with the mainstream statistical convention.\n\n**Domain.** At least one admitted numeric value. **Range:** the closed interval\n`[min, max]` of the data; the median is a location statistic and cannot leave the convex hull\nof the sample.\n\nThe median is the **50th percentile**, the second quartile, and the most robust common measure\nof centre: its breakdown point is `50%`, meaning up to half the data can be replaced by\narbitrary values before the median can be forced anywhere. The arithmetic mean's breakdown\npoint is `0%` — a single value moves it arbitrarily far. That contrast is the reason `MEDIAN`\nexists next to [AVERAGE](FUNC.AVERAGE.md), and it is the right basis for choosing between them.\n\n\n\n### Arguments\n\n\n| Argument | Meaning | Notes |\n|---|---|---|\n| `number1` | The first value or range | Required |\n| `number2, …` | Further values or ranges | Optional; up to 254 more |\n\nThe coercion behaviour is the family-standard split documented on Microsoft's page:\n\n| Value | Typed **directly** into the argument list | Reached inside an **array or reference** |\n|---|---|---|\n| Number | counted | counted |\n| Zero | counted | **counted** — Microsoft states this explicitly |\n| `TRUE` / `FALSE` | counted (as 1 / 0) | ignored |\n| Text that reads as a number | counted | ignored |\n| Text that does not read as a number | error | ignored |\n| Empty cell | — | ignored |\n| Error value | error | error |\n\nThe zero row is called out on Microsoft's page for a reason: users routinely expect a \"blank\nor zero\" range to contribute nothing, and blanks and zeros are treated oppositely. A column\nwhere missing readings were entered as `0` has a very different median from one where they were\nleft blank, and the function gives no signal about which situation it is in.\n\nSee [Coercion and lifting](../model/02-coercion-and-lifting.md) for the general rule this\ninstantiates.\n\n\n"
  },
  "signature": {
    "display": "MEDIAN(number1, [number2], ...)",
    "parameters": [
      {
        "description": null,
        "name": "number1",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "number2",
        "optional": true,
        "repeats": true
      }
    ],
    "trailing_repeats": true
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 255,
        "min": 1
      },
      "category": "Statistical functions",
      "classification": {
        "arg_preparation_profile": "ValuesOnlyPreAdapter",
        "coercion_lift_profile": "AggregateDirectAndRangeDualPolicy",
        "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": "Middle value of the numbers once sorted",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns the median of the given numbers",
        "microsoft_url": "https://support.microsoft.com/en-us/office/median-function-d0916313-4753-414c-8537-ce85bdd967d2"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "MEDIAN"
        },
        {
          "locale": "bg-BG",
          "name": "MEDIAN"
        },
        {
          "locale": "cs-CZ",
          "name": "MEDIAN"
        },
        {
          "locale": "da-DK",
          "name": "MEDIAN"
        },
        {
          "locale": "de-DE",
          "name": "MEDIAN"
        },
        {
          "locale": "el-GR",
          "name": "MEDIAN"
        },
        {
          "locale": "en-AU",
          "name": "MEDIAN"
        },
        {
          "locale": "en-GB",
          "name": "MEDIAN"
        },
        {
          "locale": "en-US",
          "name": "MEDIAN"
        },
        {
          "locale": "es-ES",
          "name": "MEDIANA"
        },
        {
          "locale": "et-EE",
          "name": "MEDIAN"
        },
        {
          "locale": "fi-FI",
          "name": "MEDIAANI"
        },
        {
          "locale": "fr-FR",
          "name": "MEDIANE"
        },
        {
          "locale": "he-IL",
          "name": "MEDIAN"
        },
        {
          "locale": "hr-HR",
          "name": "MEDIAN"
        },
        {
          "locale": "hu-HU",
          "name": "MEDIÁN"
        },
        {
          "locale": "id-ID",
          "name": "MEDIAN"
        },
        {
          "locale": "it-IT",
          "name": "MEDIANA"
        },
        {
          "locale": "ja-JP",
          "name": "MEDIAN"
        },
        {
          "locale": "ko-KR",
          "name": "MEDIAN"
        },
        {
          "locale": "lt-LT",
          "name": "MEDIAN"
        },
        {
          "locale": "lv-LV",
          "name": "MEDIAN"
        },
        {
          "locale": "nb-NO",
          "name": "MEDIAN"
        },
        {
          "locale": "nl-NL",
          "name": "MEDIAAN"
        },
        {
          "locale": "pl-PL",
          "name": "MEDIANA"
        },
        {
          "locale": "pt-BR",
          "name": "MED"
        },
        {
          "locale": "pt-PT",
          "name": "MED"
        },
        {
          "locale": "ro-RO",
          "name": "MEDIAN"
        },
        {
          "locale": "ru-RU",
          "name": "МЕДИАНА"
        },
        {
          "locale": "sk-SK",
          "name": "MEDIAN"
        },
        {
          "locale": "sl-SI",
          "name": "MEDIAN"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "MEDIAN"
        },
        {
          "locale": "sv-SE",
          "name": "MEDIAN"
        },
        {
          "locale": "th-TH",
          "name": "MEDIAN"
        },
        {
          "locale": "tr-TR",
          "name": "ORTANCA"
        },
        {
          "locale": "uk-UA",
          "name": "MEDIAN"
        },
        {
          "locale": "vi-VN",
          "name": "MEDIAN"
        },
        {
          "locale": "zh-CN",
          "name": "MEDIAN"
        },
        {
          "locale": "zh-HK",
          "name": "MEDIAN"
        },
        {
          "locale": "zh-TW",
          "name": "MEDIAN"
        }
      ],
      "signature": {
        "display": "MEDIAN(number1, [number2], ...)",
        "parameters": [
          {
            "description": null,
            "name": "number1",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "number2",
            "optional": true,
            "repeats": true
          }
        ],
        "trailing_repeats": true
      },
      "surface_name": "MEDIAN",
      "version_marker": null,
      "xlcall": {
        "code": "227",
        "symbol": "xlfMedian"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/median-function-d0916313-4753-414c-8537-ce85bdd967d2"
  },
  "try_it": {
    "formula": "=MEDIAN(1)"
  },
  "url": "https://handbook.dnacalc.com/functions/MEDIAN.html",
  "variants": [],
  "versions": [
    {
      "behaviour": "43,412 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.MEDIAN.json"
      ]
    }
  ]
}