{
  "category": "Logical functions",
  "display_name": "XOR",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.XOR",
  "implementation_state": {
    "answer_bank": {
      "excel_builds": [
        "20430"
      ],
      "larger_numeric": 0,
      "last_bit": 0,
      "matched": 1212,
      "other_mismatch": 0,
      "refused": 0,
      "rows": 1212,
      "unread": 0,
      "worst_ulp": 0
    },
    "detail": "Recorded: 1,212 in the answer bank and 25 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 1,237 recorded answers",
    "workbook_corpus": {
      "cells": 25,
      "matched": 25
    }
  },
  "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/logical.rs#L102-L102",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/logical.rs#L158-L164"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/aggregate::reader",
        "catalogue/aggregate::read_reference",
        "catalogue/logical::logicals",
        "catalogue/logical::decide",
        "catalogue/logical::tally",
        "catalogue/logical::direct",
        "catalogue/logical::held",
        "catalogue/logical::not_callable"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/logical.rs#L102-L102",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 1,237 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.XOR.json",
  "name": "XOR",
  "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- `OR` and `XOR` agree whenever at most one item is true and diverge as soon as two are.\n- `AND` is the conjunction over the same scan.\n- `XOR` was added in Excel 2013; workbooks that must open in earlier versions use\n  `MOD(SUMPRODUCT(--(conditions)), 2) = 1` or nested `IF` chains instead. The Handbook does not\n  treat `XOR` as a Compatibility-category replacement pair — it supersedes an idiom, not a\n  function.\n- `BITXOR` is a different function entirely: bitwise exclusive-or on integers, not a logical\n  reduction. Readers searching for \"XOR\" frequently want that one.\n\n\n",
    "how-to-implement": "\n### Notes for implementers\n\n\n1. Accumulate parity as a single boolean toggled on each true item. Counting and then testing the\n   low bit is equivalent but invites overflow thinking that does not apply here.\n2. The \"saw at least one classified item\" flag is separate from the parity accumulator, exactly as\n   in `AND` and `OR`; the empty scan is not `FALSE`.\n3. `XOR` is associative and commutative over the classified items, so scan order does not affect\n   the value — but it *does* affect which error surfaces first if more than one error is present.\n   Order is therefore still observable.\n\n\n",
    "quirks": "\n### Result and edge cases\n\n\nReturns a `Logical`, or an `Error`.\n\n- **Single argument.** `XOR(x)` is just the truthiness of `x` — parity of one item.\n- **Two arguments.** Behaves as exclusive disjunction; this is the only arity at which the\n  intuitive reading and the implemented rule agree for all inputs.\n- **Three or more.** Parity. `XOR(TRUE,TRUE,TRUE)` is `TRUE`.\n- **Zero versus nonzero.** Nonzero numbers are true; only exact zero is false.\n- **Text and empty in ranges.** Skipped, so they do not disturb the parity count.\n- **All items skipped.** `#VALUE!`.\n- **Arrays.** Scanned whole, not lifted elementwise.\n\n\n",
    "sources": "- Handbook call-model chapters\n  [02 Coercion and lifting](../model/02-coercion-and-lifting.md) and\n  [03 The call pipeline](../model/03-call-pipeline.md).\n- `data/functions/FUNC.XOR.json`, `data/presence/FUNC.XOR.json`.\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 | 1,212 |\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.XOR.json).",
    "what-it-does": "\n`XOR` shares the truth scan of `AND` and `OR` but performs a different reduction: it returns the\n**parity** of the true items, not a threshold test.\n\nFormally, let `T` be the number of items in the scan that classified as true. Then `XOR` returns\n`TRUE` when `T` is odd and `FALSE` when `T` is even — including `T = 0`, provided at least one\nitem classified at all.\n\nThis is worth stating carefully because the name misleads. In two-argument use, parity and\n\"exactly one is true\" coincide, so `XOR(a, b)` reads like exclusive disjunction. With three or\nmore arguments they diverge: `XOR(TRUE, TRUE, TRUE)` is `TRUE` (three is odd), not `FALSE`. If you\nwant \"exactly one of these is true\" over three conditions, `XOR` is the wrong function — the\ncounting idiom `SUM(--(conditions)) = 1` is what you mean.\n\nThe scan and its classification are identical to `AND`'s:\n\n| Item | Classification |\n|---|---|\n| `Logical` | its own truth value |\n| `Number` | false if exactly 0, true otherwise |\n| Text or empty inside an array or reference argument | skipped |\n| `Error` | the scan stops and that error is the result |\n\nAnd, as with `AND` and `OR`, a scan in which **nothing** classified returns `#VALUE!` rather than\nthe algebraic identity `FALSE`.\n\n\n\n### Arguments\n\n\n`XOR(logical1, [logical2], ...)`\n\n- Each argument is a condition or a container of conditions, scanned in row-major order.\n- An omitted slot delivers `Missing` and contributes nothing.\n\nThe misunderstood position here is not any one slot but the **count**: readers reach for `XOR`\nwith more than two arguments expecting uniqueness and get parity.\n\n\n"
  },
  "signature": {
    "display": "XOR(logical1, [logical2], ...)",
    "parameters": [
      {
        "description": null,
        "name": "logical1",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "logical2",
        "optional": true,
        "repeats": true
      }
    ],
    "trailing_repeats": true
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 254,
        "min": 1
      },
      "category": "Logical 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": "TRUE when an odd number of the arguments are TRUE",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns a logical exclusive OR of all arguments",
        "microsoft_url": "https://support.microsoft.com/en-us/office/xor-function-1548d4c2-5e47-4f77-9a92-0533bba14f37"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "XOR"
        },
        {
          "locale": "bg-BG",
          "name": "XOR"
        },
        {
          "locale": "cs-CZ",
          "name": "XOR"
        },
        {
          "locale": "da-DK",
          "name": "XELLER"
        },
        {
          "locale": "de-DE",
          "name": "XOR"
        },
        {
          "locale": "el-GR",
          "name": "XOR"
        },
        {
          "locale": "en-AU",
          "name": "XOR"
        },
        {
          "locale": "en-GB",
          "name": "XOR"
        },
        {
          "locale": "en-US",
          "name": "XOR"
        },
        {
          "locale": "es-ES",
          "name": "XO"
        },
        {
          "locale": "et-EE",
          "name": "XOR"
        },
        {
          "locale": "fi-FI",
          "name": "EHDOTON.TAI"
        },
        {
          "locale": "fr-FR",
          "name": "OUX*"
        },
        {
          "locale": "he-IL",
          "name": "XOR"
        },
        {
          "locale": "hr-HR",
          "name": "XOR"
        },
        {
          "locale": "hu-HU",
          "name": "XVAGY"
        },
        {
          "locale": "id-ID",
          "name": "XOR"
        },
        {
          "locale": "it-IT",
          "name": "XOR"
        },
        {
          "locale": "ja-JP",
          "name": "XOR"
        },
        {
          "locale": "ko-KR",
          "name": "XOR"
        },
        {
          "locale": "lt-LT",
          "name": "XOR"
        },
        {
          "locale": "lv-LV",
          "name": "XOR"
        },
        {
          "locale": "nb-NO",
          "name": "XOR"
        },
        {
          "locale": "nl-NL",
          "name": "EX.OF"
        },
        {
          "locale": "pl-PL",
          "name": "XOR"
        },
        {
          "locale": "pt-BR",
          "name": "XOR"
        },
        {
          "locale": "pt-PT",
          "name": "XOU"
        },
        {
          "locale": "ro-RO",
          "name": "XOR"
        },
        {
          "locale": "ru-RU",
          "name": "ИСКЛИЛИ"
        },
        {
          "locale": "sk-SK",
          "name": "XOR"
        },
        {
          "locale": "sl-SI",
          "name": "XOR"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "XOR"
        },
        {
          "locale": "sv-SE",
          "name": "XELLER"
        },
        {
          "locale": "th-TH",
          "name": "XOR"
        },
        {
          "locale": "tr-TR",
          "name": "ÖZELVEYA"
        },
        {
          "locale": "uk-UA",
          "name": "XOR"
        },
        {
          "locale": "vi-VN",
          "name": "XOR"
        },
        {
          "locale": "zh-CN",
          "name": "XOR"
        },
        {
          "locale": "zh-HK",
          "name": "XOR"
        },
        {
          "locale": "zh-TW",
          "name": "XOR"
        }
      ],
      "signature": {
        "display": "XOR(logical1, [logical2], ...)",
        "parameters": [
          {
            "description": null,
            "name": "logical1",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "logical2",
            "optional": true,
            "repeats": true
          }
        ],
        "trailing_repeats": true
      },
      "surface_name": "XOR",
      "version_marker": null,
      "xlcall": {
        "code": "569",
        "symbol": "xlfXor"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/xor-function-1548d4c2-5e47-4f77-9a92-0533bba14f37"
  },
  "try_it": {
    "formula": "=XOR(TRUE,TRUE,FALSE)"
  },
  "url": "https://handbook.dnacalc.com/functions/XOR.html",
  "variants": [],
  "versions": [
    {
      "behaviour": "1,212 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.XOR.json"
      ]
    }
  ]
}