{
  "category": "Statistical functions",
  "display_name": "NORM.S.DIST",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.NORM.S.DIST",
  "implementation_state": {
    "answer_bank": {
      "excel_builds": [
        "20131",
        "20430",
        "20527",
        "?"
      ],
      "larger_numeric": 0,
      "last_bit": 11075,
      "matched": 16422,
      "other_mismatch": 0,
      "refused": 0,
      "rows": 27497,
      "unread": 0,
      "worst_ulp": 11
    },
    "detail": "Everything else matches (27,497 in the answer bank and 6 workbook cells). Last-bit means a finite number within 16 ULP of Excel's.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "close",
    "state_label": "Close: last-bit deviations remain",
    "summary": "Close: 11,076 of 27,503 recorded answers differ in the last bits, worst 11 ULP",
    "workbook_corpus": {
      "cells": 6,
      "last_bit": 1,
      "matched": 5,
      "worst_ulp": 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/distributions.rs#L68-L71"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "ported/excel_numeric::binary_with",
        "ported/excel_numeric::excel_x87_add",
        "ported/excel_numeric::excel_x87_sub",
        "ported/excel_numeric::excel_x87_mul",
        "ported/excel_numeric::excel_x87_div",
        "ported/excel_numeric/x87::mul",
        "ported/excel_numeric/x87::add",
        "ported/excel_numeric/x87::sub",
        "ported/excel_numeric/x87::div",
        "ported/normal_dist_common::stored_horner",
        "ported/normal_dist_common::erf_approx",
        "ported/normal_dist_common::erfc_upper",
        "ported/normal_log_family::flush_subnormal",
        "ported/normal_log_family::identified_std_normal_cdf",
        "ported/normal_log_family::norm_cdf",
        "ported/normal_log_family::norm_s_dist_kernel",
        "ported/phi_fn::phi_kernel",
        "ported/special_dist_family::erfc_kernel",
        "ported/special_dist_family::erfc_precise_kernel"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/distributions.rs#L68-L71",
      "state": "close",
      "suite": null,
      "summary": "Close: 11,076 of 27,503 recorded answers differ in the last bits, worst 11 ULP"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.NORM.S.DIST.json",
  "name": "NORM.S.DIST",
  "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      NORMSDIST(z)  corresponds to  NORM.S.DIST(z, TRUE)\n\n  and there is no legacy spelling of the density branch at all. This is not a rename. Anyone\n  migrating formulas mechanically by inserting dots will produce calls that do not compile, and\n  anyone reasoning about the pair as \"the same function under two names\" is reasoning about\n  only half of the modern one.\n\n  And even for the branch that does correspond: **the correspondence is a signature and\n  mathematical correspondence, not a demonstrated identity of bits.** Excel dispatches\n  compatibility functions as their own surfaces. `EV-DIST-0018` names both `NORM.S.DIST` and\n  `NORMSDIST` among its subjects, but its figures are group totals with a reader warning\n  against per-surface attribution, so nothing in the Handbook's record establishes that the two\n  agree.\n- **[NORM.DIST](FUNC.NORM.DIST.md)** is the two-parameter surface. Microsoft's `NORM.DIST` page\n  states the documented identity `NORM.DIST(x, 0, 1, TRUE) = NORM.S.DIST(x, TRUE)`. Documented\n  identity, unmeasured bit agreement.\n- **[NORM.S.INV](FUNC.NORM.S.INV.md)** is the functional inverse of the cumulative branch.\n- **[PHI](FUNC.PHI.md)** computes the same value as `NORM.S.DIST(z, FALSE)`. The pointed fact\n  here: `EV-DIST-0022` identifies Excel's `PHI` as a squaring, an exponential and a multiply,\n  with **no erf and no CDF in the chain** — a route that a cumulative-capable surface cannot\n  be taking for its cumulative branch. Whether Excel's `NORM.S.DIST(z, FALSE)` shares `PHI`'s\n  chain or has its own is precisely the kind of question two surfaces for one function raise,\n  and it is unanswered.\n- **[GAUSS](FUNC.GAUSS.md)** is `NORM.S.DIST(z, TRUE) − 0.5`, i.e. `Φ(z) − ½`. `GAUSS` exists\n  because that subtraction loses precision near the origin when done by the user, and it is\n  one of the two surfaces `EV-DIST-0018` reports as having drifted at its sweep.\n- **`ERF` / `ERFC`** are the underlying special functions; `Φ(z) = ½ erfc(−z/√2)`.\n- **`Z.TEST`**, **`CONFIDENCE.NORM`** and **`STANDARDIZE`** are the usual consumers.\n\n\n",
    "how-to-implement": "\n### Numerical notes\n\n\n**The two branches are different numerical problems sharing a name.** The density branch is a\nsquaring and an exponential — see [PHI](FUNC.PHI.md) for why the squaring, not the exponential,\nsets the accuracy ceiling, and why the error grows quadratically in `z`. The cumulative branch\nis a special function requiring region-switched approximation. An implementation that treats\nthem as two branches of one routine is doing the right thing structurally, but it should not\nbe expected that accuracy claims transfer between them.\n\n**The cumulative branch, properly.** The route that survives is `erfc`:\n\n    Φ(z) = ½ · erfc(−z/√2)\n\nwritten that way and never as `½[1 + erf(z/√2)]`, because the latter subtracts nearly equal\nquantities in the left tail. Then `erfc` itself is region-switched: a rational approximation\nnear the origin, a different one for moderate argument, and for large argument the scaled form\n`erfc(u) = e^(−u²) · R(u) / u` with `R` from a continued fraction or the asymptotic series\n(A&S 7.1.13/7.1.14, 26.2.12), which keeps the exponential factored out so nothing underflows\nprematurely. Cody's rational Chebyshev approximations are the standard source; Cephes's `ndtr`\nis a widely used independent implementation; Boost's `erfc` carries stated bounds.\n\n**The `√2` in the argument is not free.** `−z/√2` is computed in floating point, and the\nrounding of that division is amplified into the result by the local logarithmic derivative,\nwhich grows like `|z|` in the tail. Carrying `z/√2` as a double-double — or equivalently\nmultiplying by a two-part representation of `1/√2` — is the standard fix and matters only\nwhere it matters, which is exactly the tail where users are least likely to check.\n\n**A note on what the identities buy you.** `Φ(0) = ½` and `Φ(z) + Φ(−z) = 1` are exact and\noracle-free. An implementation that is region-switched will generally *not* satisfy the\nreflection identity in the last bit unless it is written to compute one side and reflect,\nbecause the two sides go through different approximations. Whether that is a defect depends on\nwhat was promised. Recording it is not optional.\n\n**The published assessment record.** Excel's statistical lane, and the normal distribution\nfunctions in particular, have been examined in print for two decades — McCullough and Wilson in\n*Computational Statistics & Data Analysis*, Knüsel on the distribution functions specifically —\nwith revisions reported around Excel 2003 and again when the dotted names arrived. Morten\nWelinder's Gnumeric work is the standard practical account of getting this family right in a\nspreadsheet. The Handbook names these as literature and restates no figure from them.\n\n\n",
    "quirks": "\n### Density wording in the documentation\n\n\nMicrosoft's `NORM.S.DIST` syntax description calls the `FALSE` result a “probability mass function”, while its remarks call the equation a density. The `NORM.DIST` syntax uses density, although its example table also uses the mass label. Both pages were opened on 7 November 2026.\n\nFor a continuous normal distribution, the `FALSE` branch returns the height of the density curve. A probability over an interval is an integral of that curve; the density at one point is not the probability of that individual outcome. This is a documentation wording issue, not evidence of a change between Excel builds.\n\n\n\n### Result and edge cases\n\n\nReturns `Number`.\n\n- **`z = 0`.** The cumulative branch is exactly `0.5`; the density branch is the stored\n  constant `1/√(2π)`. Both are diagnostic single cells, for different reasons.\n- **Tail limits.** The CDF and density implementations flush final subnormal results to zero. This differs from preserving every positive IEEE binary64 subnormal. The density branch also rejects a nonfinite staged square; see [PHI](FUNC.PHI.md).\n- **Symmetry.** `Φ(z) + Φ(−z) = 1` and `φ(z) = φ(−z)` are exact mathematically. Whether the\n  implementation reproduces them in the last bit is a metamorphic property that can be tested\n  without any external oracle, and is on the probe list.\n- **Arrays.** The recorded profile is `Custom`; elementwise lifting is not settled here.\n\n\n\n### Errors\n\n\nAs documented by Microsoft on the `NORM.S.DIST` page (retrieved for this page):\n\n| Error | Documented condition |\n|---|---|\n| `#VALUE!` | `z` is nonnumeric |\n\nThat is the complete documented error surface — one row. Note what it omits: **nothing is\ndocumented about a nonnumeric `cumulative`**, and no `#NUM!` condition is stated at all, which\nis consistent with the mathematics since `Φ` and `φ` are defined on the whole real line.\n\nError values in either argument propagate under the ordinary coercion rules.\n\n\n",
    "sources": "- Microsoft, \"NORM.S.DIST function\" —\n  <https://support.microsoft.com/en-us/office/norm-s-dist-function-1e787282-3832-4520-a9ae-bd2a8d99ba88>\n  (syntax; both arguments required; the `cumulative` description, which calls the non-cumulative\n  branch a \"probability mass function\"; the single `#VALUE!` condition on a nonnumeric `z`).\n  Retrieved for this page.\n- Microsoft, \"NORM.DIST function\" —\n  <https://support.microsoft.com/en-us/office/norm-dist-function-edb1cc14-a21c-4e53-839d-8082074c9f8d>\n  (the documented identity at `mean = 0`, `standard_dev = 1`, `cumulative = TRUE`; and the\n  \"probability density function\" wording that the `NORM.S.DIST` page contradicts). Retrieved.\n- Handbook evidence record `EV-DIST-0018` — the ten-witness normal-group re-sweep, which names\n  `NORM.S.DIST` and `NORMSDIST` as subjects and whose group figure carries a reader warning\n  against per-surface attribution.\n- Handbook evidence record `EV-DIST-0022` — cited here only for the fact that Excel's `PHI` was\n  identified on a chain containing no erf and no CDF; `NORM.S.DIST` is not among its subjects\n  and no claim about this surface is drawn from it.\n- Abramowitz & Stegun, *Handbook of Mathematical Functions*, chapter 26 §26.2 and chapter 7\n  §7.1 — the normal probability function, the density, the tail asymptotics and the `erfc`\n  continued fraction.\n- W. J. Cody, \"Rational Chebyshev approximation for the error function\", *Mathematics of\n  Computation* 23 (1969); SPECFUN `ANORM`/`CALERF`. S. L. Moshier, Cephes `ndtr.c`.\n- B. D. McCullough and B. Wilson, *Computational Statistics & Data Analysis* (1999, 2002,\n  2005); L. Knüsel on Excel's distribution functions; M. Welinder's Gnumeric statistical work.\n  Named as literature; no figure restated.\n- Handbook, [Coercion and lifting](../model/02-coercion-and-lifting.md) and\n  [About implementation options](../model/07-implementation-options.md).\n- [Normal wrapper and publication stages](https://github.com/DnaCalc/DnaCalc/blob/481f4ab85d3bf5a95b6daf959bb75ccb2f8b40f8/crates/calc-func/src/ported/normal_log_family.rs) and [shared density kernel](https://github.com/DnaCalc/DnaCalc/blob/481f4ab85d3bf5a95b6daf959bb75ccb2f8b40f8/crates/calc-func/src/ported/normal_dist_common.rs).\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| 20131 | Windows, bitness not recorded, AMD Ryzen 7 4800H with Radeon Graphics | 16,495 |\n| 20430 | Windows, 64-bit, CPU not recorded | 10,978 |\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.NORM.S.DIST.json).",
    "what-it-does": "\n`NORM.S.DIST(z, cumulative)` evaluates the **standard** normal distribution — mean `0`,\nstandard deviation `1` — at `z`, returning either its density or its cumulative distribution\nfunction according to the second argument.\n\n    cumulative = FALSE :   φ(z) = (1 / √(2π)) · e^(−z²/2)\n    cumulative = TRUE  :   Φ(z) = ∫₋∞ᶻ φ(t) dt\n                                = ½ · [ 1 + erf(z/√2) ]\n                                = ½ · erfc(−z/√2)\n\nIn Abramowitz & Stegun's notation these are `Z(x)` and `P(x)` respectively (chapter 26 §26.2).\n\n**Domain and range.** Defined for every real `z`; no poles, no branch cuts, both forms entire.\n\n    φ:  strictly positive, even, range (0, 1/√(2π)],  maximum φ(0) = 1/√(2π)\n    Φ:  strictly increasing, range (0, 1),  Φ(−∞) = 0,  Φ(+∞) = 1\n\n**The identities that carry the function.**\n\n    Φ(0) = 1/2                          exactly\n    Φ(z) + Φ(−z) = 1                    the reflection identity\n    Φ'(z) = φ(z)\n    φ'(z) = −z φ(z)\n    1 − Φ(z) ~ φ(z)/z · (1 − 1/z² + 3/z⁴ − …)     as z → +∞    (A&S 26.2.12)\n\n`Φ(0) = 1/2` is exactly representable and is the single most useful test input this function\nhas: it removes the special function from the picture entirely and tests only whether the\nimplementation knows where the centre is. `φ(0) = 1/√(2π)` plays the same role for the density,\ntesting only the stored constant.\n\n**Tail probabilities and worksheet publication.** A stored CDF can round to one, losing the upper-tail probability in a later `1-CDF` subtraction. Evaluating the reflected lower tail avoids that subtraction. At the left end, the current DnaCalc wrapper flushes a result below `2^-1022` to zero; its source includes a `z=-37.52` control. That is a worksheet publication rule, not the point where IEEE binary64 runs out of representable positive values. The ERFC body inside the wrapper remains an open approximation.\n\n\n\n### Arguments\n\n\nMicrosoft's page gives two required arguments:\n\n| Argument | Meaning | Required |\n|---|---|---|\n| `z` | \"the value for which you want the distribution\" | yes |\n| `cumulative` | \"can be either TRUE or FALSE… If cumulative is TRUE then NORM.S.DIST returns the cumulative distribution function. If it is FALSE, it returns the probability mass function.\" | yes |\n\n`cumulative` has no default: the switch must be written.\n\nThe pinned catalogue supplies `NORM.S.DIST(z, cumulative)` with two required arguments. Keep the cumulative switch explicit.\n\n\n"
  },
  "signature": {
    "display": "NORM.S.DIST(z, cumulative)",
    "parameters": [
      {
        "description": null,
        "name": "z",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "cumulative",
        "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": "Standard normal distribution: density or cumulative",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns the standard normal cumulative distribution",
        "microsoft_url": "https://support.microsoft.com/en-us/office/norm-s-dist-function-1e787282-3832-4520-a9ae-bd2a8d99ba88"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "bg-BG",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "cs-CZ",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "da-DK",
          "name": "STANDARD.NORM.FORDELING"
        },
        {
          "locale": "de-DE",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "el-GR",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "en-AU",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "en-GB",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "en-US",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "es-ES",
          "name": "DISTR.NORM.ESTAND.N"
        },
        {
          "locale": "et-EE",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "fi-FI",
          "name": "NORM_JAKAUMA.NORMIT"
        },
        {
          "locale": "fr-FR",
          "name": "LOI.NORMALE.STANDARD.N*"
        },
        {
          "locale": "he-IL",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "hr-HR",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "hu-HU",
          "name": "NORM.S.ELOSZLÁS"
        },
        {
          "locale": "id-ID",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "it-IT",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "ja-JP",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "ko-KR",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "lt-LT",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "lv-LV",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "nb-NO",
          "name": "NORM.S.FORDELING"
        },
        {
          "locale": "nl-NL",
          "name": "NORM.S.VERD"
        },
        {
          "locale": "pl-PL",
          "name": "ROZKŁ.NORMALNY.S"
        },
        {
          "locale": "pt-BR",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "pt-PT",
          "name": "DIST.S.NORM"
        },
        {
          "locale": "ro-RO",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "ru-RU",
          "name": "НОРМ.СТ.РАСП"
        },
        {
          "locale": "sk-SK",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "sl-SI",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "sv-SE",
          "name": "NORM.S.FÖRD"
        },
        {
          "locale": "th-TH",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "tr-TR",
          "name": "NORM.S.DAĞ"
        },
        {
          "locale": "uk-UA",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "vi-VN",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "zh-CN",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "zh-HK",
          "name": "NORM.S.DIST"
        },
        {
          "locale": "zh-TW",
          "name": "NORM.S.DIST"
        }
      ],
      "signature": {
        "display": "NORM.S.DIST(z, cumulative)",
        "parameters": [
          {
            "description": null,
            "name": "z",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "cumulative",
            "optional": false,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "NORM.S.DIST",
      "version_marker": null,
      "xlcall": {
        "code": "539",
        "symbol": "xlfNorm_s_dist"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/norm-s-dist-function-1e787282-3832-4520-a9ae-bd2a8d99ba88"
  },
  "try_it": {
    "formula": "=NORM.S.DIST(1,TRUE)"
  },
  "url": "https://handbook.dnacalc.com/functions/NORM.S.DIST.html",
  "variants": [],
  "versions": [
    {
      "behaviour": "16,495 captured inputs are indexed for this environment. Capture dates: 2026-07-17 to 2026-07-17. 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.NORM.S.DIST.json"
      ]
    },
    {
      "behaviour": "10,978 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.NORM.S.DIST.json"
      ]
    }
  ]
}