{
  "category": "Math and trigonometry functions",
  "display_name": "LOG",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.LOG",
  "implementation_state": {
    "answer_bank": {
      "excel_builds": [
        "20430"
      ],
      "larger_numeric": 0,
      "last_bit": 0,
      "matched": 25233,
      "other_mismatch": 0,
      "refused": 0,
      "rows": 25233,
      "unread": 0,
      "worst_ulp": 0
    },
    "detail": "Recorded: 25,233 in the answer bank and 4 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 25,237 recorded answers",
    "workbook_corpus": {
      "cells": 4,
      "matched": 4
    }
  },
  "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/math.rs#L96-L105",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/ported/log_fn.rs#L2-L24"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "ported/excel_numeric::binary_with",
        "ported/excel_numeric::excel_x87_div",
        "ported/excel_numeric/x87::div",
        "ported/log10_fn::log10_kernel"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/math.rs#L96-L105",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 25,237 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.LOG.json",
  "name": "LOG",
  "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- **[LN](FUNC.LN.md)** — the natural logarithm, and (on the upstream finding below) the routine\n  `LOG` calls twice. `LOG(x, EXP(1))` and `LN(x)` are the same value mathematically; whether they\n  agree in the last bit is a different question and is not settled here.\n- **`POWER` and `^`** — the inverse relation: `POWER(b, LOG(x, b))` is *x*, up to rounding.\n- **`IMLOG10` / `IMLOG2`** — the complex-valued counterparts.\n  Excel publishes a complex base-2 logarithm but **no real one**: there is no `LOG2`. Base 2 on\n  the worksheet goes through `LOG(x, 2)`, which is exactly the case the finding below is about.\n\n**A retracted upstream claim, recorded here because it is instructive.** One of the reference\nengine's own documents asserted that Excel special-cases base 10 and base 2, using dedicated\n`log10`/`log2` routines that are more accurate than the naive quotient. The live-Excel sweep\nbehind this page's evidence record **refuted that**: on the sweep's own finding, `LOG(x, base)` is\nln(x)/ln(base) for *every* base, and the special-casing was removed. The two upstream documents\ncontradict each other and the record carries the retraction explicitly. The Handbook publishes\nboth sides rather than silently preferring one, and notes that the refuting evidence is the more\nrecent and the more direct.\n\n\n",
    "how-to-implement": "\n### Numerical notes\n\n\n`LOG` is the clearest case in the math category of a function whose difficulty is **not** in its\nkernel. The kernel is [LN](FUNC.LN.md), and its analysis belongs on that page. What belongs here\nis what the division does.\n\n**Two logarithms and a divide.** If each `ln` is correctly rounded to within half an ULP and the\ndivision adds another half, the quotient carries about 1.5 ULP of error in the best case — before\nany conditioning is considered. That is why a dedicated `log10` (which folds the 1/ln10 scaling\ninto the polynomial) beats `ln(x)/ln(10)`, and it is the reason the upstream claim of\nspecial-casing was plausible enough to be believed for a while. On the sweep's finding Excel does\n*not* take the more accurate route, which means a compatibility implementation must reproduce the\nquotient, including its extra rounding, rather than improve on it. This is one of the recurring\nshapes in this Handbook: matching Excel and being accurate are different objectives, and here\nthey point in different directions.\n\n**The base-near-1 pole is the real hazard.** The condition number of the quotient with respect to\nthe base is proportional to 1/ln *b*. As *b* → 1 the denominator goes to zero, so the relative\nerror in the *result* is amplified without bound:\n\n- At *b* = 1.0001, ln *b* is about 10⁻⁴, and every ULP of error in the denominator is amplified\n  by four orders of magnitude in the answer.\n- Worse, ln *b* for *b* near 1 is itself the ln(1+x) cancellation problem described on the `LN`\n  page: the base *as a double* has already lost the low bits of *b* − 1.\n\nSo `LOG(x, 1.0000001)` is a compounded disaster — an inaccurate denominator, divided into,\namplified. There is a correct way to compute it (evaluate the denominator as `log1p(b-1)` from the\nexact perturbation, which needs the perturbation rather than the perturbed value), and there is no\nway to reach it from the worksheet, because Excel publishes no `log1p`. A reader whose base is\nnear 1 — a growth rate, a per-period interest factor — should restructure the formula rather than\ntrust the function. The honest statement is that this is a domain where the *mathematics* is\nill-conditioned, not a domain where any implementation is at fault.\n\n**Argument reduction and the kernel** are `LN`'s, and the substrate identification, the ruled-out\nlibm list and the host-CPU caveat on the last bit all carry across from the same evidence record.\nFor the standard treatment of the underlying kernel see Cody & Waite, *Software Manual for the\nElementary Functions*, and Muller, *Elementary Functions*; Abramowitz & Stegun chapter 4,\nsection 4.1 tabulates the change-of-base relations.\n\n\n",
    "quirks": "\n### Result and edge cases\n\n\nReturns `Number`.\n\n- **Zero and negative first arguments** produce `#NUM!`.\n- **`LOG(TRUE)`** converts the logical to 1 and returns zero. Undocumented conversion.\n- **Numeric text** converts and evaluates.\n- **The largest finite double** and **the smallest positive subnormal** produce finite results,\n  both host-scoped.\n- **An inline array** in the first slot lifts elementwise.\n- **An empty range** produces `#VALUE!`.\n\nThe battery does not probe the base argument at all — every row exercises the default. The whole\nof `LOG`'s distinctive behaviour therefore sits outside the published battery, which is worth\nknowing before drawing any conclusion from it.\n\n\n",
    "sources": "- Microsoft, \"LOG function\" —\n  <https://support.microsoft.com/en-us/office/log-function-4e82f196-1ca9-4747-8fb0-6c4a3abb3280>.\n  Retrieved for this page: the syntax, both argument descriptions, the statement that an omitted\n  base is assumed to be 10, and the three worked examples. The page as retrieved documents no\n  error value.\n- Handbook evidence record `EV-MATH-0001` — live-Excel sweep naming `LOG` as a subject; carries\n  the host-CPU caveat, the per-surface/group distinction, the ruled-out list, and the retraction\n  of the base-10/base-2 special-casing claim.\n- M. Abramowitz and I. A. Stegun, *Handbook of Mathematical Functions*, chapter 4, section 4.1 —\n  logarithmic function relations including change of base.\n- W. J. Cody and W. Waite, *Software Manual for the Elementary Functions*; J.-M. Muller,\n  *Elementary Functions: Algorithms and Implementation*, 3rd edition — the kernel and its error\n  analysis, and the accuracy argument for a dedicated base-10 routine over a quotient.\n- Handbook, [LN](FUNC.LN.md) — the kernel this function is built on, including the ln(1+x)\n  cancellation that governs the base-near-1 case.\n- Handbook, [coercion and lifting](../model/02-coercion-and-lifting.md) — to-number outcomes,\n  lifting, error propagation.\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| 19929 | Windows, bitness not recorded, CPU not recorded | 130 |\n| 20430 | Windows, 64-bit, CPU not recorded | 25,233 |\n\n- XC-LOG-001: build 19929 versus build 20430; 3 same-input pairs, 0 differing answers. Compared axes: excel-build. Numeric answers were compared by their recorded binary64 bits; other answers by typed value.\n\nAgreement on these compared inputs does not establish agreement on unmeasured inputs.\n\n[Recorded environments and comparison details](https://github.com/DnaCalc/ExcelFunctionsHandbook/blob/5dc75391aa5125ccc5abdb095da85950980d6fd8/content/evidence/environments/FUNC.LOG.json).",
    "what-it-does": "\n`LOG(number, [base])` returns the logarithm of *number* to the given *base*: the power to which\nthe base must be raised to obtain the number. Microsoft's own gloss of the first example is\nexactly that — \"the power to which the base must be raised to equal 10.\"\n\n    LOG(x, b) = log_b x = ln x / ln b\n\nThe change-of-base identity in the second form is not one implementation choice among many; it is\nthe *definition* of a logarithm to an arbitrary base once the natural logarithm exists. Every\nother property follows:\n\n- **Domain.** *x* > 0 and *b* > 0 with *b* ≠ 1. The base must be positive because b^y is not\n  real-valued for negative *b* at fractional *y*, and it must differ from 1 because 1^y is 1 for\n  every *y* — there is no power of 1 that gives 2, and log₁ is not a function.\n- **Range.** All of ℝ.\n- **The pole in the base.** As *b* → 1, ln *b* → 0 and the quotient diverges. This is a genuine\n  pole of the two-variable function, and it is the numerical hazard specific to `LOG` — see\n  \"Numerical notes\".\n- **Monotonicity flips.** For *b* > 1 the function increases in *x*; for 0 < *b* < 1 it\n  decreases. log_b x and log_{1/b} x are negatives of one another.\n- **Fixed points.** LOG(b, b) = 1 and LOG(1, b) = 0 for every admissible base.\n\nMicrosoft's three documented examples cover the shape: base omitted gives base 10, an integer\nbase gives the expected integer answer for an exact power, and a base of approximately e\nreproduces the natural logarithm.\n\n\n\n### Arguments\n\n\n| Argument | Meaning | Default |\n|---|---|---|\n| `number` | \"The positive real number for which you want the logarithm.\" Required. | — |\n| `base` | \"The base of the logarithm. If base is omitted, it is assumed to be 10.\" | 10 |\n\nThe declared arity is one to two, matching. Both slots are numeric and subject to ordinary\nto-number coercion ([coercion and lifting](../model/02-coercion-and-lifting.md)).\n\n**The default is 10, not e.** This is the one thing about `LOG` that costs people real money:\nin most programming languages and in most mathematical writing outside engineering, an unadorned\n`log` means the natural logarithm. In Excel it means base 10. A formula ported from Python, R,\nC or MATLAB that reads `LOG(x)` is wrong by a constant factor of ln 10 ≈ 2.302585…, and it is\nwrong *quietly*, because the result is still a plausible number. The Excel spelling of the\nnatural logarithm is [LN](FUNC.LN.md).\n\n\n"
  },
  "signature": {
    "display": "LOG(number, [base])",
    "parameters": [
      {
        "description": null,
        "name": "number",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "base",
        "optional": true,
        "repeats": false
      }
    ],
    "trailing_repeats": false
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 2,
        "min": 1
      },
      "category": "Math and trigonometry 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": "Logarithm in a given base (10 when the base is left out)",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns the logarithm of a number to a specified base",
        "microsoft_url": "https://support.microsoft.com/en-us/office/log-function-4e82f196-1ca9-4747-8fb0-6c4a3abb3280"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "LOG"
        },
        {
          "locale": "bg-BG",
          "name": "LOG"
        },
        {
          "locale": "cs-CZ",
          "name": "LOG"
        },
        {
          "locale": "da-DK",
          "name": "LOG"
        },
        {
          "locale": "de-DE",
          "name": "LOG"
        },
        {
          "locale": "el-GR",
          "name": "LOG"
        },
        {
          "locale": "en-AU",
          "name": "LOG"
        },
        {
          "locale": "en-GB",
          "name": "LOG"
        },
        {
          "locale": "en-US",
          "name": "LOG"
        },
        {
          "locale": "es-ES",
          "name": "LOG"
        },
        {
          "locale": "et-EE",
          "name": "LOG"
        },
        {
          "locale": "fi-FI",
          "name": "LOG"
        },
        {
          "locale": "fr-FR",
          "name": "LOG"
        },
        {
          "locale": "he-IL",
          "name": "LOG"
        },
        {
          "locale": "hr-HR",
          "name": "LOG"
        },
        {
          "locale": "hu-HU",
          "name": "LOG"
        },
        {
          "locale": "id-ID",
          "name": "LOG"
        },
        {
          "locale": "it-IT",
          "name": "LOG"
        },
        {
          "locale": "ja-JP",
          "name": "LOG"
        },
        {
          "locale": "ko-KR",
          "name": "LOG"
        },
        {
          "locale": "lt-LT",
          "name": "LOG"
        },
        {
          "locale": "lv-LV",
          "name": "LOG"
        },
        {
          "locale": "nb-NO",
          "name": "LOG"
        },
        {
          "locale": "nl-NL",
          "name": "LOG"
        },
        {
          "locale": "pl-PL",
          "name": "LOG"
        },
        {
          "locale": "pt-BR",
          "name": "LOG"
        },
        {
          "locale": "pt-PT",
          "name": "LOG"
        },
        {
          "locale": "ro-RO",
          "name": "LOG"
        },
        {
          "locale": "ru-RU",
          "name": "LOG"
        },
        {
          "locale": "sk-SK",
          "name": "LOG"
        },
        {
          "locale": "sl-SI",
          "name": "LOG"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "LOG"
        },
        {
          "locale": "sv-SE",
          "name": "LOG"
        },
        {
          "locale": "th-TH",
          "name": "LOG"
        },
        {
          "locale": "tr-TR",
          "name": "LOG"
        },
        {
          "locale": "uk-UA",
          "name": "LOG"
        },
        {
          "locale": "vi-VN",
          "name": "LOG"
        },
        {
          "locale": "zh-CN",
          "name": "LOG"
        },
        {
          "locale": "zh-HK",
          "name": "LOG"
        },
        {
          "locale": "zh-TW",
          "name": "LOG"
        }
      ],
      "signature": {
        "display": "LOG(number, [base])",
        "parameters": [
          {
            "description": null,
            "name": "number",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "base",
            "optional": true,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "LOG",
      "version_marker": null,
      "xlcall": {
        "code": "109",
        "symbol": "xlfLog"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/log-function-4e82f196-1ca9-4747-8fb0-6c4a3abb3280"
  },
  "try_it": {
    "formula": "=LOG(100,10)"
  },
  "url": "https://handbook.dnacalc.com/functions/LOG.html",
  "variants": [],
  "versions": [
    {
      "behaviour": "130 captured inputs are indexed for this environment. Capture dates are not recorded. This is a reading count, not a comparison with another build.",
      "excel_build": "16.0 build 19929",
      "platform": "Windows, bitness not recorded, CPU not recorded",
      "sources": [
        "https://github.com/DnaCalc/ExcelFunctionsHandbook/blob/5dc75391aa5125ccc5abdb095da85950980d6fd8/content/evidence/environments/FUNC.LOG.json"
      ]
    },
    {
      "behaviour": "25,233 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.LOG.json"
      ]
    }
  ]
}