{
  "category": "Text functions",
  "display_name": "UPPER",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.UPPER",
  "implementation_state": {
    "answer_bank": {
      "excel_builds": [
        "20527"
      ],
      "larger_numeric": 0,
      "last_bit": 0,
      "matched": 5,
      "other_mismatch": 0,
      "refused": 0,
      "rows": 5,
      "unread": 0,
      "worst_ulp": 0
    },
    "detail": "Recorded: 5 in the answer bank and 5 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 10 recorded answers",
    "workbook_corpus": {
      "cells": 5,
      "matched": 5
    }
  },
  "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#L280-L280"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/text_functions::cased",
        "ported/text_kernels::text",
        "ported/text_kernels::text_from_str",
        "ported/text_kernels::push_singleton_or_original",
        "ported/text_kernels::push_upper",
        "ported/text_kernels::is_well_formed",
        "ported/text_kernels::upper"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/text_functions.rs#L280-L280",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 10 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.UPPER.json",
  "name": "UPPER",
  "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- `LOWER` — the mirror function, same implementation module upstream, and subject to every question\n  on this page in the opposite direction. Note that lowercase has its own asymmetries: Greek final\n  sigma is context-dependent in a way no uppercase mapping is.\n- `PROPER` — the third member of the case family. Upstream records its word-boundary behaviour as\n  restarting capitalisation at non-letter separators including apostrophes and digits, which is why\n  `PROPER(\"o'brien\")` is not what a reader expects. `PROPER` is not `UPPER` of the first letter.\n- `EXACT` — the case-sensitive comparison. `EXACT(UPPER(a), UPPER(b))` is the usual hand-rolled\n  case-insensitive comparison, and it inherits every mapping question above.\n- `=` (the comparison operator) is already case-insensitive for text, which makes `UPPER` unnecessary\n  in many comparisons where people reach for it out of habit from other languages.\n- `SEARCH` versus `FIND`, and the `match_mode` arguments of [`TEXTAFTER`](FUNC.TEXTAFTER.md),\n  [`TEXTBEFORE`](FUNC.TEXTBEFORE.md) and [`TEXTSPLIT`](FUNC.TEXTSPLIT.md), express\n  case-insensitivity directly and are usually better than uppercasing both sides.\n- [`ASC`](FUNC.ASC.md) and [`DBCS`](FUNC.DBCS.md) are the *width* conversions, sometimes mistaken\n  for case conversions because they also \"change letters\". They do not touch case.\n\n\n",
    "how-to-implement": "\n### Notes for implementers\n\n\n- **Name your mapping.** Write down which of the four mappings you implement and treat it as part\n  of the signature. A port that silently uses the host language's default (`to_uppercase` in Rust\n  is full Unicode; `ToUpper` in .NET is culture-sensitive; `str.upper` in Python is full Unicode)\n  will inherit that language's choice as Excel semantics.\n- **Culture-sensitive APIs are a trap in both directions.** `ToUpper()` on a Turkish thread gives a\n  different answer than on an invariant one. If you want reproducibility, use the invariant form\n  explicitly — and record that you did, because it may be a divergence from Excel rather than a fix.\n- **Allow the length to change** in your buffers and in your result-cap check. In-place uppercase\n  over a fixed-size UTF-16 buffer is only correct for simple mapping.\n- **Operate on scalars, not code units.** Case mapping of a surrogate pair requires decoding it\n  first; a code-unit loop leaves supplementary-plane letters (Deseret, Adlam, Warang Citi) unmapped.\n- **Lift a single array-valued argument.**\n\n\n",
    "quirks": "\n### Result and edge cases\n\n\nThe return kind is `Text`. `UPPER(\"\")` is `\"\"`.\n\nBoundaries worth naming:\n\n- **Length can change.** If Excel implements full Unicode uppercase, `UPPER` can return a longer\n  string than it was given — the `ß` → `SS` case. A caller that assumes `LEN(UPPER(x)) = LEN(x)`\n  is making an assumption about which of the four mappings Excel uses.\n- **The 32,767-code-unit cap** therefore becomes reachable from below; see\n  [the value universe](../model/01-value-universe.md) for how the cap behaves on the formula path.\n- **`UPPER` is not a normaliser.** It does not compose or decompose combining marks. `UPPER` of a\n  decomposed `e` + combining acute is not guaranteed to equal `UPPER` of the precomposed `é`, and\n  `EXACT` will tell you they differ.\n- **`UPPER` is not injective**, so it is not safely reversible: `LOWER(UPPER(x))` is not `x` in\n  general.\n- **An empty referenced cell** delivers `Empty`, distinct from an omitted argument.\n- **Errors propagate.**\n\n\n\n### Errors\n\n\nMicrosoft's page is the authority and is linked below; it was not retrievable while this entry was\nwritten, so nothing here paraphrases it. `UPPER` is a total function over text and there is no\ndocumented domain restriction to state. The reachable errors are the ordinary ones:\n\n| Error | Condition |\n|---|---|\n| any error value | Propagated from the argument; coercion does not discard worksheet errors. |\n| `#VALUE!` | An argument kind with no text conversion in this context, or a result that exceeds the text cap on the formula path. |\n\nThe second row's cap behaviour is described in [the value universe](../model/01-value-universe.md)\nas an observed distinction between the formula and interop paths; whether `UPPER` in particular\nreaches it has not been probed.\n\n\n",
    "sources": "- Microsoft Support, UPPER function —\n  <https://support.microsoft.com/en-us/office/upper-function-c11f29b3-d1a3-4537-8df6-04d0049963d6>\n  (the authority for signature and description; not retrievable while this entry was written, so it\n  is cited by reference and nothing here paraphrases it).\n- Handbook `content/model/01-value-universe.md` (UTF-16 code units, the 32,767 cap and its two\n  enforcement paths), `02-coercion-and-lifting.md` (to-text coercion, lifting, error propagation).\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`UPPER` returns the argument text with every character replaced by its uppercase form.\n\nThat sentence is short, and every hard question about the function hides inside \"its uppercase\nform\". Case mapping is not a property of a character in isolation; it is a function of a character,\na mapping table, and — in the general case — a locale and the surrounding context. The four\nmappings a text function might implement are genuinely different:\n\n1. **ASCII only.** `a`–`z` map to `A`–`Z`; everything else is left alone. Simple, locale-free, and\n   wrong for most of the world.\n2. **Simple Unicode uppercase.** One code point maps to one code point, using Unicode's simple\n   uppercase mapping. `é` becomes `É`.\n3. **Full Unicode uppercase.** One code point may map to several. The canonical example is `ß`,\n   whose full uppercase mapping is `SS` — a mapping that *changes the length of the string*.\n4. **Locale-tailored uppercase.** Turkish and Azerbaijani map dotless `ı` to `I` and dotted `i` to\n   `İ`, which differs from every other locale's mapping of `i`.\n\nThese four disagree on real, ordinary text, and the difference is observable in a spreadsheet.\n`UPPER` is therefore one of the functions where \"it just uppercases\" is not a specification.\n**Which of the four Excel implements, this Handbook has not established.** That is the honest state\nand it is why the \"What has not been checked\" section below is unusually specific.\n\n\n### Arguments\n\n\n`UPPER(text)`\n\n| Argument | Required | Meaning |\n|---|---|---|\n| `text` | yes | The text to convert. |\n\nOne argument, no options — in particular no locale argument, which is the reason locale-tailored\nmapping is such a live question: if Excel does tailor, it must be doing so from ambient state, and\nambient state is exactly what makes a formula's result depend on the machine it runs on.\n\nNon-text arguments convert to text first. Upstream records the specific rule that `LOWER` and\n`UPPER` textify logicals on the ordinary values-only seam, so `UPPER(TRUE)` is the string `TRUE`\nrather than an error or a number. Numbers arrive as their general-format rendering; since digits\nand the exponent marker have no distinct cases, `UPPER` of a number is generally that rendering\nunchanged, though the marker's case in scientific notation is worth checking rather than assuming.\n\n\n"
  },
  "signature": {
    "display": "UPPER(text)",
    "parameters": [
      {
        "description": null,
        "name": "text",
        "optional": false,
        "repeats": false
      }
    ],
    "trailing_repeats": false
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 1,
        "min": 1
      },
      "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": "TextToText",
        "rich_value_usage": "RichBlind",
        "surface_fec_dependency_profile": "RefOnly",
        "thread_safety_class": "SafePure",
        "volatility_class": "NonVolatile"
      },
      "descriptions": {
        "long": null,
        "short": "Text in upper case",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Converts text to uppercase",
        "microsoft_url": "https://support.microsoft.com/en-us/office/upper-function-c11f29b3-d1a3-4537-8df6-04d0049963d6"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "UPPER"
        },
        {
          "locale": "bg-BG",
          "name": "UPPER"
        },
        {
          "locale": "cs-CZ",
          "name": "UPPER"
        },
        {
          "locale": "da-DK",
          "name": "UPPER"
        },
        {
          "locale": "de-DE",
          "name": "UPPER"
        },
        {
          "locale": "el-GR",
          "name": "UPPER"
        },
        {
          "locale": "en-AU",
          "name": "UPPER"
        },
        {
          "locale": "en-GB",
          "name": "UPPER"
        },
        {
          "locale": "en-US",
          "name": "UPPER"
        },
        {
          "locale": "es-ES",
          "name": "UPPER"
        },
        {
          "locale": "et-EE",
          "name": "UPPER"
        },
        {
          "locale": "fi-FI",
          "name": "ISOT"
        },
        {
          "locale": "fr-FR",
          "name": "UPPER"
        },
        {
          "locale": "he-IL",
          "name": "UPPER"
        },
        {
          "locale": "hr-HR",
          "name": "UPPER"
        },
        {
          "locale": "hu-HU",
          "name": "UPPER"
        },
        {
          "locale": "id-ID",
          "name": "UPPER"
        },
        {
          "locale": "it-IT",
          "name": "UPPER"
        },
        {
          "locale": "ja-JP",
          "name": "UPPER"
        },
        {
          "locale": "ko-KR",
          "name": "UPPER"
        },
        {
          "locale": "lt-LT",
          "name": "UPPER"
        },
        {
          "locale": "lv-LV",
          "name": "UPPER"
        },
        {
          "locale": "nb-NO",
          "name": "UPPER"
        },
        {
          "locale": "nl-NL",
          "name": "UPPER"
        },
        {
          "locale": "pl-PL",
          "name": "UPPER"
        },
        {
          "locale": "pt-BR",
          "name": "UPPER"
        },
        {
          "locale": "pt-PT",
          "name": "UPPER"
        },
        {
          "locale": "ro-RO",
          "name": "UPPER"
        },
        {
          "locale": "ru-RU",
          "name": "UPPER"
        },
        {
          "locale": "sk-SK",
          "name": "UPPER"
        },
        {
          "locale": "sl-SI",
          "name": "UPPER"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "UPPER"
        },
        {
          "locale": "sv-SE",
          "name": "UPPER"
        },
        {
          "locale": "th-TH",
          "name": "UPPER"
        },
        {
          "locale": "tr-TR",
          "name": "BÜYÜKHARF"
        },
        {
          "locale": "uk-UA",
          "name": "UPPER"
        },
        {
          "locale": "vi-VN",
          "name": "UPPER"
        },
        {
          "locale": "zh-CN",
          "name": "UPPER"
        },
        {
          "locale": "zh-HK",
          "name": "UPPER"
        },
        {
          "locale": "zh-TW",
          "name": "UPPER"
        }
      ],
      "signature": {
        "display": "UPPER(text)",
        "parameters": [
          {
            "description": null,
            "name": "text",
            "optional": false,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "UPPER",
      "version_marker": null,
      "xlcall": {
        "code": "113",
        "symbol": "xlfUpper"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/upper-function-c11f29b3-d1a3-4537-8df6-04d0049963d6"
  },
  "try_it": {
    "formula": "=UPPER(\"\")"
  },
  "url": "https://handbook.dnacalc.com/functions/UPPER.html",
  "variants": [],
  "versions": []
}