{
  "category": "Financial functions",
  "display_name": "DDB",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.DDB",
  "implementation_state": {
    "answer_bank": {
      "excel_builds": [
        "20430"
      ],
      "larger_numeric": 0,
      "last_bit": 0,
      "matched": 1761,
      "other_mismatch": 0,
      "refused": 0,
      "rows": 1761,
      "unread": 0,
      "worst_ulp": 0
    },
    "detail": "Recorded: 1,761 in the answer bank and 9 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 1,770 recorded answers",
    "workbook_corpus": {
      "cells": 9,
      "matched": 9
    }
  },
  "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/financial.rs#L295-L299",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/ported/depreciation_family.rs#L387-L400"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "ported/depreciation_family::validate_finite",
        "ported/depreciation_family::publish_depreciation",
        "ported/depreciation_family::depreciation_integer_power",
        "ported/depreciation_family::ddb_period_depreciation",
        "ported/excel_numeric::backend::sqrt",
        "ported/excel_numeric::binary_with",
        "ported/excel_numeric::excel_pow_positive",
        "ported/excel_numeric::excel_pow_chain",
        "ported/excel_numeric::excel_x87_sub",
        "ported/excel_numeric::excel_x87_mul",
        "ported/excel_numeric::excel_x87_div",
        "ported/excel_numeric::excel_x87_recip",
        "ported/excel_numeric/x87::mul",
        "ported/excel_numeric/x87::sub",
        "ported/excel_numeric/x87::div",
        "ported/excel_numeric/x87::recip",
        "ported/excel_numeric/x87_chains::pow2_positive",
        "ported/excel_numeric/x87_chains::pow2",
        "ported/excel_numeric/x87_chains::exp_ext",
        "ported/excel_numeric/x87_chains::exp_with",
        "ported/excel_numeric/x87_chains::excel_exp",
        "ported/excel_numeric/x87_chains::log_with",
        "ported/excel_numeric/x87_chains::excel_log",
        "ported/power_fn::exact_integer_magnitude",
        "ported/power_fn::accept_negative_base_odd_root",
        "ported/power_fn::binexp_positive",
        "ported/power_fn::power_kernel"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/financial.rs#L295-L299",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 1,770 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.DDB.json",
  "name": "DDB",
  "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- **[DB](FUNC.DB.md)** — the other declining-balance function, which derives and rounds its rate\n  and prorates the first year by a `month` count. See the comparison table above.\n- **`SLN`** — the straight-line charge `(cost − salvage)/life`. Comparing `DDB` against `SLN`\n  period by period is how you find where a switching method would switch, and therefore where\n  `DDB` starts under-charging relative to accounting practice.\n- **`SYD`** — sum-of-years-digits: also accelerated, but it *does* exhaust `cost − salvage`\n  exactly.\n- **[AMORDEGRC](FUNC.AMORDEGRC.md)** — the French accelerated method. Its acceleration\n  coefficient looks like `factor` but is derived from `rate` and cannot be supplied, and its\n  last two periods are forced to 50 and 100 per cent. Not a substitute.\n- **Confused with**: `VDB` (above), and with the assumption that a `DDB` column sums to\n  `cost − salvage`.\n\n\n",
    "how-to-implement": "\n### Numerical notes\n\n2. **The clamp is a `min` and therefore a branch.** Near the crossover the two terms are close,\n   and which one wins is decided by a floating-point comparison. Two implementations that agree\n   on both terms to the last bit can still disagree on the answer at exactly one period.\n3. **`factor / life` is one division**, not a per-period recomputation. Forming it once and\n   multiplying is not the same as multiplying by `factor` and dividing by `life` each period;\n   pin the choice.\n4. **No transcendentals.** Unlike [DB](FUNC.DB.md), which needs a general power, `DDB` is\n   multiplication, subtraction and comparison throughout. It is the most numerically\n   straightforward member of the family — which makes it a good calibration surface for a future\n   vector suite, since any disagreement is semantic rather than about a library `pow`.\n5. **The fractional-period proration is an extension**, not a documented behaviour. It reuses the\n   `VDB` interval logic on a unit interval, which is a defensible reading and is not the only\n   one.\n\n\n",
    "quirks": "\n### The clamp, and why DDB never switches\n\n\nDeclining balance has a well-known defect: `book × factor/life` shrinks geometrically and never\nreaches zero, so the asset is never fully written off within its life. Standard accounting\npractice is to **switch to straight line** for the remaining periods once straight line would\ngive the larger charge.\n\n**`DDB` does not do that.** Microsoft is explicit: \"Use the VDB function if you want to switch to\nthe straight-line depreciation method when depreciation is greater than the declining balance\ncalculation.\" `DDB` runs pure declining balance, clamped at `salvage`, for the whole life.\n\nSo a `DDB` schedule summed over `1 … life` does **not** generally reach `cost − salvage`. It\napproaches it geometrically and stops short — unless the clamp cuts in near the end, which\nhappens only when `salvage` is large enough for the geometric tail to reach it. This is the\nsingle most common surprise in the depreciation category, and it is documented behaviour, not a\ndefect.\n\nThe comparison that makes the family legible:\n\n| | rate | `salvage` used for | switches to straight line | first-period proration |\n|---|---|---|---|---|\n| `SLN` | implicit, flat | the whole charge | n/a | none |\n| [DB](FUNC.DB.md) | derived from the salvage ratio, rounded to 3 dp | deriving the rate | no | `month` |\n| `DDB` | `factor / life`, supplied | a clamp only | **no** | none |\n| `VDB` | `factor / life`, supplied | a clamp only | **optional** | period range |\n| `SYD` | implicit, declining | the whole charge | n/a | none |\n\n\n\n### Result and edge cases\n\n\nReturns a `Number`: the charge for the requested period, in the units of `cost`.\n\n- **`salvage` is invisible early.** For any period where `book × factor/life` is below\n  `book − salvage`, the answer does not depend on `salvage` at all. A spreadsheet in which\n  changing `salvage` changes nothing is behaving correctly.\n- **The clamp can zero the charge.** Once the book value has fallen to `salvage`, every later\n  period returns 0 rather than an error.\n- **`factor` > `life`** makes `factor/life` exceed 1, so the first period would write off more\n  than the whole asset; the clamp reduces it to `cost − salvage`. Nothing in the documentation\n  forbids it.\n- **Fractional `life`** is accepted; the final partial period is shorter than 1 and its charge is\n  prorated accordingly.\n- **The schedule does not exhaust `cost − salvage`**, per the section above. This is not an edge\n  case; it is the normal outcome.\n- Empty, missing and error arguments follow the shared call model; see\n  [The value universe](../model/01-value-universe.md).\n\n\n\n### Errors\n\n\n**Microsoft's Learn page documents no error values and no error conditions** — only the\n\"all five arguments must be positive numbers\" remark, which is contradicted on the same page.\n\n",
    "sources": "- Microsoft Learn, **WorksheetFunction.Ddb method (Excel)** —\n  <https://learn.microsoft.com/en-us/office/vba/api/excel.worksheetfunction.ddb>. Source of the\n  parameter table with its quoted descriptions (including \"This value can be 0\" for `salvage`),\n  the `factor` default of 2, the `Min(...)` formula quoted above, the \"All five arguments must be\n  positive numbers\" remark recorded here as contradicting that table, and the pointer to `VDB`\n  for the straight-line switch. This page documents no error values.\n- Microsoft Learn, **WorksheetFunction.Db method (Excel)** —\n  <https://learn.microsoft.com/en-us/office/vba/api/excel.worksheetfunction.db>. Cited for the\n  sibling's derived, rounded rate in the comparison above.\n- Microsoft 365 support, **DDB function** —\n  <https://support.microsoft.com/en-us/office/ddb-function-519a7a37-8772-4c96-85c0-ed2c209717a5>.\n  The worksheet-surface page; **not retrieved** for this entry (the host returned HTTP 403), so\n  nothing here is quoted from it.\n- Handbook chapters [01 the value universe](../model/01-value-universe.md),\n  [02 coercion and lifting](../model/02-coercion-and-lifting.md),\n  [06 claim language](../model/06-claim-language.md),\n  [07 implementation options](../model/07-implementation-options.md).\n- `data/functions/FUNC.DDB.json`, `data/presence/FUNC.DDB.json`, `data/battery/FUNC.DDB.json`.\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 | 61,630 |\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.DDB.json).",
    "what-it-does": "\n`DDB(cost, salvage, life, period, [factor])` returns the depreciation charge for **one period**\nunder the double-declining-balance method, or any other declining rate you name.\n\nMicrosoft's Learn page gives the rule in one line:\n\n>     Min( (cost − total depreciation from prior periods) × (factor / life),\n>          (cost − salvage − total depreciation from prior periods) )\n\nWriting `book` for `cost` minus the depreciation already taken, that is:\n\n>     charge = min( book × factor / life,  book − salvage )\n\nThe first term is the declining-balance charge: a constant fraction `factor/life` of the\nremaining book value. With the default `factor` = 2 that fraction is twice the straight-line\nrate, which is where \"double declining\" comes from — the method writes off twice as fast at the\nstart and tapers.\n\nThe second term is a **clamp**: the charge may never take the book value below `salvage`.\n\nTwo properties define the method, and both matter:\n\n1. **The rate is given, not derived.** Unlike [DB](FUNC.DB.md), which solves for the rate that\n   lands exactly on `salvage`, `DDB` applies whatever `factor/life` you specify and lets the\n   clamp deal with the consequences.\n2. **`salvage` enters only through the clamp.** It does not affect the declining-balance term at\n   all, so for early periods `DDB` returns the same number whatever `salvage` is.\n\n\n\n### Arguments\n\n\n`DDB(cost, salvage, life, period, [factor])`\n\n| Argument | Meaning (Microsoft's wording) | Required? |\n|---|---|---|\n| `cost` | \"The initial cost of the asset.\" | Required |\n| `salvage` | \"The value at the end of the depreciation … **This value can be 0.**\" | Required |\n| `life` | \"The number of periods over which the asset is being depreciated.\" | Required |\n| `period` | \"The period for which you want to calculate the depreciation. Period must use the same units as life.\" | Required |\n| `factor` | \"The rate at which the balance declines. If factor is omitted, it is assumed to be 2 (the double-declining balance method).\" | Optional, defaults to 2 |\n\n**`period` is 1-based**, like [DB](FUNC.DB.md) and unlike the French pair\n[AMORLINC](FUNC.AMORLINC.md) / [AMORDEGRC](FUNC.AMORDEGRC.md).\n\n**`period` and `life` must be in the same units.** Monthly depreciation of a five-year asset\nmeans `life` = 60 and `period` in months — and `factor/life` shrinks accordingly, which is the\npoint.\n\nNumeric slots follow the shared model; see\n[Coercion and lifting](../model/02-coercion-and-lifting.md).\n\n\n"
  },
  "signature": {
    "display": "DDB(cost, salvage, life, period, [factor])",
    "parameters": [
      {
        "description": null,
        "name": "cost",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "salvage",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "life",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "period",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "factor",
        "optional": true,
        "repeats": false
      }
    ],
    "trailing_repeats": false
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 5,
        "min": 4
      },
      "category": "Financial 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": "Double-declining-balance (or other factor) depreciation for one period",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns the depreciation of an asset for a specified period by using the double-declining balance method or some other method that you specify",
        "microsoft_url": "https://support.microsoft.com/en-us/office/ddb-function-519a7a37-8772-4c96-85c0-ed2c209717a5"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "DDB"
        },
        {
          "locale": "bg-BG",
          "name": "DDB"
        },
        {
          "locale": "cs-CZ",
          "name": "ODPIS.ZRYCH2"
        },
        {
          "locale": "da-DK",
          "name": "DSA"
        },
        {
          "locale": "de-DE",
          "name": "DDB"
        },
        {
          "locale": "el-GR",
          "name": "DDB"
        },
        {
          "locale": "en-AU",
          "name": "DDB"
        },
        {
          "locale": "en-GB",
          "name": "DDB"
        },
        {
          "locale": "en-US",
          "name": "DDB"
        },
        {
          "locale": "es-ES",
          "name": "DDB"
        },
        {
          "locale": "et-EE",
          "name": "DDB"
        },
        {
          "locale": "fi-FI",
          "name": "DDB"
        },
        {
          "locale": "fr-FR",
          "name": "DDB"
        },
        {
          "locale": "he-IL",
          "name": "DDB"
        },
        {
          "locale": "hr-HR",
          "name": "DDB"
        },
        {
          "locale": "hu-HU",
          "name": "KCSA"
        },
        {
          "locale": "id-ID",
          "name": "DDB"
        },
        {
          "locale": "it-IT",
          "name": "DDB"
        },
        {
          "locale": "ja-JP",
          "name": "DDB"
        },
        {
          "locale": "ko-KR",
          "name": "DDB"
        },
        {
          "locale": "lt-LT",
          "name": "DDB"
        },
        {
          "locale": "lv-LV",
          "name": "DDB"
        },
        {
          "locale": "nb-NO",
          "name": "DDB"
        },
        {
          "locale": "nl-NL",
          "name": "DDB"
        },
        {
          "locale": "pl-PL",
          "name": "DDB"
        },
        {
          "locale": "pt-BR",
          "name": "DDB"
        },
        {
          "locale": "pt-PT",
          "name": "BDD"
        },
        {
          "locale": "ro-RO",
          "name": "DDB"
        },
        {
          "locale": "ru-RU",
          "name": "ДДОБ"
        },
        {
          "locale": "sk-SK",
          "name": "DDB"
        },
        {
          "locale": "sl-SI",
          "name": "DDB"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "DDB"
        },
        {
          "locale": "sv-SE",
          "name": "DEGAVSKR"
        },
        {
          "locale": "th-TH",
          "name": "DDB"
        },
        {
          "locale": "tr-TR",
          "name": "ÇİFTAZALANBAKİYE işlevi"
        },
        {
          "locale": "uk-UA",
          "name": "DDB"
        },
        {
          "locale": "vi-VN",
          "name": "DDB"
        },
        {
          "locale": "zh-CN",
          "name": "DDB"
        },
        {
          "locale": "zh-HK",
          "name": "DDB"
        },
        {
          "locale": "zh-TW",
          "name": "DDB"
        }
      ],
      "signature": {
        "display": "DDB(cost, salvage, life, period, [factor])",
        "parameters": [
          {
            "description": null,
            "name": "cost",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "salvage",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "life",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "period",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "factor",
            "optional": true,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "DDB",
      "version_marker": null,
      "xlcall": {
        "code": "144",
        "symbol": "xlfDdb"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/ddb-function-519a7a37-8772-4c96-85c0-ed2c209717a5"
  },
  "try_it": {
    "formula": "=DDB(1000,100,5,1)"
  },
  "url": "https://handbook.dnacalc.com/functions/DDB.html",
  "variants": [],
  "versions": [
    {
      "behaviour": "61,630 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.DDB.json"
      ]
    }
  ]
}