{
  "category": "Operators",
  "display_name": "Multiplication (*)",
  "entry_kind": "built_in_operator",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.OP_MULTIPLY",
  "implementation_state": {
    "answer_bank": null,
    "detail": "Recorded: 5,661 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 5,661 recorded answers",
    "workbook_corpus": {
      "cells": 5664,
      "matched": 5661,
      "pending": 3,
      "worst_ulp": 0
    }
  },
  "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/arithmetic.rs#L40-L40",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/arithmetic.rs#L63-L68"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/arithmetic::flushed",
        "catalogue/arithmetic::binary",
        "catalogue/arithmetic::operands"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/arithmetic.rs#L40-L40",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 5,661 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.OP_MULTIPLY.json",
  "name": "OP_MULTIPLY",
  "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- [`FUNC.OP_DIVIDE`](FUNC.OP_DIVIDE.md) — the inverse operation, and the one that adds an\n  error lane (`#DIV/0!`) `*` does not have.\n- [`FUNC.OP_POWER`](FUNC.OP_POWER.md) — repeated multiplication when the exponent is an exact\n  integer; see that page for the publication subtlety.\n- `PRODUCT` — the aggregate. As with `SUM` versus `+`, `PRODUCT` scans ranges under an\n  aggregate policy and is not `*` folded over a list.\n- `SUMPRODUCT`, `MMULT` — elementwise-then-sum and matrix product. `MMULT` is emphatically\n  not `*`: `*` on two arrays broadcasts elementwise, `MMULT` contracts an index.\n- `IMPRODUCT` — complex multiplication over text-encoded complex numbers.\n\n\n",
    "how-to-implement": "\n### Notes for implementers\n\n\n- The elementwise-versus-matrix distinction is the single most common user-facing confusion\n  on this row. An implementation that \"helpfully\" contracts conformable arrays is wrong;\n  `*` broadcasts.\n- Do not fuse. A fused multiply-add (`a*b+c` computed with one rounding) gives a different,\n  usually more accurate, result than Excel's two-rounding sequence. For the\n  `excel-bitexact` flavour, fusion must be disabled explicitly — many compilers will\n  introduce it at higher optimization levels without asking.\n- Guard the array orientation before the kernel. Broadcast shape selection belongs in the\n  shared lift layer so that `*`, `+`, `-`, `/` and `^` cannot drift apart.\n\n\n",
    "quirks": "\n### Result and edge cases\n\n- **Text and logical operands.** Shared to-number rules; `*` adds nothing of its own.\n- **Zero times anything finite** is zero, with the sign given by the operand signs. The\n  Handbook has not recorded whether the sign of that zero is observable in a published Excel\n  result.\n- **Empty and omitted operands.** Per-family policy under chapter 02; unrecorded here.\n- **Overflow and underflow.** The recorded real-result policy is `non_finite=allow`, and the\n  entry marks that axis `default-unexamined`. Overflow of a product is easy to reach\n  (`1E300 * 1E300`), so this is not a hypothetical lane; it is simply unrecorded.\n\n\n",
    "sources": "- `data/presence/FUNC.OP_MULTIPLY.json` — implementing module\n  `earlier-implementation/operator_arithmetic_family.rs`.\n- Handbook `content/model/01-value-universe.md`, `02-coercion-and-lifting.md`,\n  `03-call-pipeline.md`.\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`A * B` converts each operand to a number and returns the IEEE-754 binary64 product, rounded\nonce to nearest with ties to even.\n\nThree properties that matter in practice:\n\n1. **One rounding, not two.** The exact product of two doubles generally needs about twice\n   the significand; the operation rounds it once. That single rounding is what makes\n   `a*b` reproducible across conforming platforms, and what makes `(a*b)*c ≠ a*(b*c)` in\n   general — multiplication is commutative but not associative in binary64.\n2. **Underflow is gradual, then total.** A product whose magnitude falls below the smallest\n   normal double becomes subnormal and loses significand bits; below the smallest subnormal\n   it becomes zero. The zero is signed, and the sign is the XOR of the operand signs.\n3. **The coercion is doing most of the work in real workbooks.** `=(A1>5)*(B1<3)` multiplies\n   two logicals — the classic array-formula spelling of AND — and depends entirely on the\n   shared to-logical-to-number rule (TRUE→1, FALSE→0) of\n   [coercion and lifting](../model/02-coercion-and-lifting.md), not on anything specific to\n   `*`.\n\n\n\n### Arguments\n\n\n| Position | Name | Meaning |\n|---|---|---|\n| 0 | `A` | Left factor. Required. |\n| 1 | `B` | Right factor. Required. |\n\nArity is exactly 2; no optional arguments, no defaults. Multiplication is commutative on\nfinite numbers, so operand order does not change the value — but it does change the\nbroadcast orientation when the operands are arrays of different shapes, so the positions are\nnot interchangeable in the array case.\n\n\n"
  },
  "signature": {
    "display": "number1 * number2",
    "parameters": [
      {
        "description": null,
        "name": "number1",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "number2",
        "optional": false,
        "repeats": false
      }
    ],
    "trailing_repeats": false
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 2,
        "min": 2
      },
      "category": "Operators",
      "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": "NumsToNum",
        "rich_value_usage": "RichBlind",
        "surface_fec_dependency_profile": "RefOnly",
        "thread_safety_class": "SafePure",
        "volatility_class": "NonVolatile"
      },
      "descriptions": {
        "long": null,
        "short": null,
        "short_source": "no-short-description"
      },
      "docs": null,
      "entry_kind": "built_in_operator",
      "localized_family_names": null,
      "localized_names": [],
      "signature": {
        "display": "number1 * number2",
        "parameters": [
          {
            "description": null,
            "name": "number1",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "number2",
            "optional": false,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "OP_MULTIPLY",
      "version_marker": null,
      "xlcall": null
    },
    "microsoft": null
  },
  "try_it": {
    "formula": "=3*4"
  },
  "url": "https://handbook.dnacalc.com/functions/OP_MULTIPLY.html",
  "variants": [],
  "versions": []
}