{
  "category": "Text functions",
  "display_name": "EXACT",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.EXACT",
  "implementation_state": {
    "answer_bank": null,
    "detail": "Recorded: 8 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 8 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/text_functions.rs#L296-L300"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/text_functions::side_count",
        "catalogue/text_functions::left",
        "catalogue/text_functions::right",
        "ported/text_kernels::text",
        "ported/text_kernels::text_from_str",
        "ported/text_kernels::date_integer_floor",
        "ported/text_kernels::nonnegative_count",
        "ported/text_kernels::unit_width",
        "ported/text_kernels::character_boundary",
        "ported/text_kernels::slice_character_count",
        "ported/text_kernels::character_scan_end",
        "ported/text_kernels::len_character_count",
        "ported/text_kernels::take_left",
        "ported/text_kernels::take_right",
        "ported/text_kernels::truncated",
        "ported/text_kernels::push_singleton_or_original",
        "ported/text_kernels::push_upper",
        "ported/text_kernels::upper"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/text_functions.rs#L296-L300",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 8 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.EXACT.json",
  "name": "EXACT",
  "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- **`=` (the equality operator, `FUNC.OP_EQ`)** is the case-insensitive counterpart. Choosing\n  between them is the single most common reason to reach for `EXACT`.\n- **`FIND` / `SEARCH`** carry the same case-sensitivity split for substring search: `FIND` is\n  case-sensitive, `SEARCH` is not. `EXACT` is to `=` as `FIND` is to `SEARCH`.\n- **`LOWER` / `UPPER`** are the usual way to build a case-insensitive comparison explicitly.\n  Note that `EXACT(LOWER(a),LOWER(b))` and `a=b` are not the same predicate — case folding\n  merges pairs that Excel's own comparison may or may not merge.\n- **`DELTA`** is the numeric analogue (equality as a returned value rather than a branch), for\n  numbers rather than text.\n\n\n",
    "how-to-implement": "\n### Notes for implementers\n\n1. **Pick a comparison level and declare it.** Code-unit equality, code-point equality,\n   NFC-then- compare, and full case-sensitive collation are four different functions. They\n   agree on ASCII, so ASCII tests cannot distinguish them.\n2. **Do not use a locale collator.** Collation is designed to make visually-equivalent strings\n   compare equal and is exactly the wrong tool here; `EXACT` is a sameness test, not an\n   ordering.\n3. **Ill-formed UTF-16 must not panic.** The value-universe chapter records lone surrogates as\n   a reachable state in Excel text, so the comparison has to be defined over raw code units\n   even if the rest of the implementation decodes.\n\n\n",
    "quirks": "\n### Result and edge cases\n\n\nThe return kind is `Logical` — `TRUE` or `FALSE`, not 1 or 0, though it converts to those in\nnumeric contexts.\n\n- Leading and trailing spaces count. Microsoft's own example set includes `\"w ord\"` versus\n  `\"word\"` as `FALSE`; a difference in internal spacing is a difference.\n- Two empty texts compare `TRUE`.\n- The function is symmetric and reflexive on any input it accepts. It is not transitive across\n  coercion boundaries in the way readers assume: `EXACT(1,\"1\")` and `EXACT(\"1\",\"1.0\")` do not\n  compose, because the coercion happens once, on entry.\n\n\n\n### Errors\n\n\nThe article lists no error conditions of the function's own. Reachable errors are the shared\nones: an error value in either argument propagates\n([chapter 02](../model/02-coercion-and-lifting.md)), and a value kind with no text conversion\nsurfaces `#VALUE!` under the shared coercion rules.\n\nNote the asymmetry with the comparison operator: `=\"a\"=\"a\"` never errors, while `EXACT`\ninherits the whole coercion pipeline and therefore can.\n\n\n",
    "sources": "- Microsoft, \"EXACT function\" —\n  <https://support.microsoft.com/en-us/office/exact-function-d3087698-fc15-4a15-9631-12575cf29926>\n  (the comparison statement; case sensitivity; that formatting differences are disregarded; the\n  `\"w ord\"` versus `\"word\"` example). Retrieved for this page.\n- Handbook `content/model/01-value-universe.md` (text as UTF-16 code units; Empty versus empty\n  text) and `content/model/02-coercion-and-lifting.md` (to-text conversion, error propagation).\n\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`EXACT` compares two text values and returns `TRUE` if they are the same and `FALSE` otherwise.\nMicrosoft's article adds the two qualifications that make it a distinct function rather than a\nsynonym for `=`: the comparison **is case-sensitive**, and it **ignores formatting\ndifferences**.\n\nBoth qualifications are worth stating precisely.\n\n*Case-sensitive* means `EXACT(\"Word\",\"word\")` is `FALSE`, where the equality operator\n`A1=\"word\"` would be `TRUE` for the same pair. This is the whole reason the function exists:\nExcel's `=` comparison of text is case-insensitive, and there is no operator that is not.\n\nWhat the documentation does not say is what \"the same\" means below the level of characters.\nText in the Handbook's value model is a sequence of UTF-16 code units\n([chapter 01](../model/01-value-universe.md)), and two strings can look identical, print\nidentically, and still differ:\n\n- **é as one code point** (U+00E9) versus **e followed by a combining acute** (U+0065 U+0301).\n  These are canonically equivalent under Unicode normalisation and different as code-unit\n  sequences.\n- The same glyph reached through different variation selectors or through compatibility\n  characters.\n\nAn implementation that normalises before comparing and one that compares code units answer\ndifferently on those inputs. Microsoft's article does not choose; it is the sharpest unresolved\nquestion on this page.\n\n\n\n### Arguments\n\n\n`text1`, `text2` — both required; the article describes them simply as the first and second\ntext strings. Both are text arguments, so a number or a logical converts to text before\ncomparison. Two consequences readers hit regularly:\n\n- `EXACT(1,\"1\")` compares the *text* `1` against the text `1`. The number's General rendering\n  is what is compared, so this is a comparison of renderings, not of values.\n- `EXACT(A1,\"\")` with `A1` an empty cell compares empty text against empty text. Empty and\n  empty-string are different value kinds at the call boundary\n  ([chapter 01](../model/01-value-universe.md)) but they converge here, which is why `EXACT`\n  cannot distinguish a blank cell from a cell containing `=\"\"`. Use `ISBLANK` for that\n  question.\n\nThere is no third argument: no locale, no normalisation form, no \"ignore whitespace\" option.\n\n\n"
  },
  "signature": {
    "display": "EXACT(text1, text2)",
    "parameters": [
      {
        "description": null,
        "name": "text1",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "text2",
        "optional": false,
        "repeats": false
      }
    ],
    "trailing_repeats": false
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 2,
        "min": 2
      },
      "category": "Text functions",
      "classification": {
        "arg_preparation_profile": "ValuesOnlyPreAdapter",
        "coercion_lift_profile": "None",
        "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": "TRUE when two texts are identical, letter case included",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Checks to see if two text values are identical",
        "microsoft_url": "https://support.microsoft.com/en-us/office/exact-function-d3087698-fc15-4a15-9631-12575cf29926"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "EXACT"
        },
        {
          "locale": "bg-BG",
          "name": "EXACT"
        },
        {
          "locale": "cs-CZ",
          "name": "STEJNÉ"
        },
        {
          "locale": "da-DK",
          "name": "EXACT"
        },
        {
          "locale": "de-DE",
          "name": "IDENTISCH"
        },
        {
          "locale": "el-GR",
          "name": "EXACT"
        },
        {
          "locale": "en-AU",
          "name": "EXACT"
        },
        {
          "locale": "en-GB",
          "name": "EXACT"
        },
        {
          "locale": "en-US",
          "name": "EXACT"
        },
        {
          "locale": "es-ES",
          "name": "EXACT"
        },
        {
          "locale": "et-EE",
          "name": "EXACT"
        },
        {
          "locale": "fi-FI",
          "name": "VERTAA"
        },
        {
          "locale": "fr-FR",
          "name": "EXACT"
        },
        {
          "locale": "he-IL",
          "name": "EXACT"
        },
        {
          "locale": "hr-HR",
          "name": "EXACT"
        },
        {
          "locale": "hu-HU",
          "name": "AZONOS"
        },
        {
          "locale": "id-ID",
          "name": "EXACT"
        },
        {
          "locale": "it-IT",
          "name": "EXACT"
        },
        {
          "locale": "ja-JP",
          "name": "EXACT"
        },
        {
          "locale": "ko-KR",
          "name": "EXACT"
        },
        {
          "locale": "lt-LT",
          "name": "EXACT"
        },
        {
          "locale": "lv-LV",
          "name": "EXACT"
        },
        {
          "locale": "nb-NO",
          "name": "EXACT"
        },
        {
          "locale": "nl-NL",
          "name": "GELIJK"
        },
        {
          "locale": "pl-PL",
          "name": "PORÓWNAJ"
        },
        {
          "locale": "pt-BR",
          "name": "EXATO"
        },
        {
          "locale": "pt-PT",
          "name": "EXATO"
        },
        {
          "locale": "ro-RO",
          "name": "EXACT"
        },
        {
          "locale": "ru-RU",
          "name": "Функция СОВПАД"
        },
        {
          "locale": "sk-SK",
          "name": "EXACT"
        },
        {
          "locale": "sl-SI",
          "name": "EXACT"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "EXACT"
        },
        {
          "locale": "sv-SE",
          "name": "EXACT"
        },
        {
          "locale": "th-TH",
          "name": "EXACT"
        },
        {
          "locale": "tr-TR",
          "name": "ÖZDEŞ"
        },
        {
          "locale": "uk-UA",
          "name": "EXACT"
        },
        {
          "locale": "vi-VN",
          "name": "EXACT"
        },
        {
          "locale": "zh-CN",
          "name": "EXACT"
        },
        {
          "locale": "zh-HK",
          "name": "EXACT"
        },
        {
          "locale": "zh-TW",
          "name": "EXACT"
        }
      ],
      "signature": {
        "display": "EXACT(text1, text2)",
        "parameters": [
          {
            "description": null,
            "name": "text1",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "text2",
            "optional": false,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "EXACT",
      "version_marker": null,
      "xlcall": {
        "code": "117",
        "symbol": "xlfExact"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/exact-function-d3087698-fc15-4a15-9631-12575cf29926"
  },
  "try_it": {
    "formula": "=EXACT(\"Word\",\"word\")"
  },
  "url": "https://handbook.dnacalc.com/functions/EXACT.html",
  "variants": [],
  "versions": []
}