{
  "category": "Financial functions",
  "display_name": "IPMT",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.IPMT",
  "implementation_state": {
    "answer_bank": {
      "excel_builds": [
        "20131",
        "20527",
        "?"
      ],
      "larger_numeric": 0,
      "last_bit": 7,
      "matched": 50,
      "other_mismatch": 0,
      "refused": 0,
      "rows": 57,
      "unread": 0,
      "worst_ulp": 2
    },
    "detail": "Of 261 recorded answers (57 in the answer bank and 204 workbook cells), 74 do not match: 11 differ by more than 16 ULP, 61 differ by at most 16 ULP, 2 differ in kind or value.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "differs",
    "state_label": "Known larger differences",
    "summary": "Known larger differences on 74 of 261 recorded answers",
    "workbook_corpus": {
      "cells": 204,
      "larger_numeric": 11,
      "last_bit": 54,
      "matched": 137,
      "other_mismatch": 2,
      "worst_ulp": 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/financial.rs#L190-L193"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/financial::tv_out",
        "catalogue/financial::timing",
        "ported/excel_numeric::backend::sqrt",
        "ported/excel_numeric::binary_with",
        "ported/excel_numeric::asuint64",
        "ported/excel_numeric::asdouble",
        "ported/excel_numeric::top12",
        "ported/excel_numeric::top16",
        "ported/excel_numeric::c2",
        "ported/excel_numeric::c3",
        "ported/excel_numeric::c4",
        "ported/excel_numeric::c5",
        "ported/excel_numeric::specialcase",
        "ported/excel_numeric::excel_expm1_spilled",
        "ported/excel_numeric::expm1_internal_graph",
        "ported/excel_numeric::exp_portable",
        "ported/excel_numeric::excel_pow_positive",
        "ported/excel_numeric::excel_pow_chain",
        "ported/excel_numeric::excel_x87_add",
        "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::log_general_hi_lo",
        "ported/excel_numeric::excel_expm1",
        "ported/excel_numeric::excel_log1p",
        "ported/excel_numeric::excel_log1p_atanh",
        "ported/excel_numeric/x87::mul",
        "ported/excel_numeric/x87::add",
        "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/financial_time_value_family::PaymentTiming::factor",
        "ported/financial_time_value_family::validate_finite",
        "ported/financial_time_value_family::growth",
        "ported/financial_time_value_family::annuity_term",
        "ported/financial_time_value_family::balance_equation",
        "ported/financial_time_value_family::pmt",
        "ported/financial_time_value_family::values_bracket_root",
        "ported/financial_time_value_family::bisect_rate_bracket",
        "ported/financial_time_value_family::search_rate_bracket_from_zero",
        "ported/financial_time_value_family::rate",
        "ported/financial_time_value_family::polish_root",
        "ported/financial_time_value_family::rate_root",
        "ported/financial_time_value_family::end_payment_quotient",
        "ported/financial_time_value_family::end_payment_parts",
        "ported/financial_time_value_family::ipmt",
        "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#L190-L193",
      "state": "differs",
      "suite": null,
      "summary": "Known larger differences on 74 of 261 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.IPMT.json",
  "name": "IPMT",
  "notes": [
    {
      "basis": "fv 0, type 0: IPMT 95 of 95 and PPMT 74 of 74 recorded rows, plus 64 of 64 fresh PPMT(r,1,1,pv) and PPMT(r,1,2,pv) readings. Nonzero fv, type 0: PPMT 25 of 27, IPMT 18 of 27. Over every recorded row in the evidence repository IPMT matches 48 of 57 and PPMT 26 of 33. Replaying the formulas in exact rational arithmetic, with exp and ln correctly rounded, gives all 12 PPMT and all 12 IPMT answers of the loan below.",
      "documentation": null,
      "evidence": [
        {
          "commit": "b5d84a80a5a4640eca9ce04f232c0bc115503f34",
          "locator": "section UPDATE",
          "note": "research write-up",
          "path": "content/notes/evidence/2026-11-04/annuity-EVIDENCE.txt",
          "repository": "ExcelFunctionsHandbook"
        },
        {
          "commit": "6c6cbd31c960fe1ac07d5cce9cb33ca9d7d86cf5",
          "locator": "end_payment_parts",
          "note": "the formulas in the product; the commit message carries the row counts",
          "path": "crates/calc-func/src/ported/financial_time_value_family.rs",
          "repository": "DnaCalc"
        },
        {
          "commit": "6c6cbd31c960fe1ac07d5cce9cb33ca9d7d86cf5",
          "locator": "ipmt_and_ppmt_use_the_quotient_of_pmt",
          "note": "eight catalogue readings; failed before the change",
          "path": "crates/calc-func/tests/f3_financial.rs",
          "repository": "DnaCalc"
        }
      ],
      "functions": [
        "FUNC.IPMT",
        "FUNC.PPMT"
      ],
      "inferred": null,
      "kind": "bit-matching-detail",
      "note_id": "FN-IPMT-001",
      "open": [
        "Nonzero fv: PMT's open numerator of q carries through.",
        "type 1: PMT's open factor K carries through."
      ],
      "recorded_on": "2026-11-04",
      "repros": [
        {
          "call": "=IPMT(0.05/12,12,360,200000)",
          "correct": {
            "bits": "0xc089b0b1b69cc35e",
            "display": "-822.0867740866777",
            "how": "mpmath at 800 bits with rate the binary64 0x3f71111111111111 that 0.05/12 evaluates to; correctly rounded.",
            "kind": "number"
          },
          "excel": {
            "bits": "0xc089b0b1b69cc35f",
            "display": "-822.0867740866778",
            "kind": "number"
          },
          "input_route": "formula-literal",
          "inputs": [],
          "recorded_in": "Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA",
          "source": {
            "commit": "c9f9d354165d2c20b9455c32582ea50baac7ba73",
            "locator": "sheet dcj9k_annuity, row 750, column 4",
            "note": null,
            "path": "crates/calc-func/tests/captures/catalogue/sections/dcj9k_annuity.capture.json",
            "repository": "DnaCalc"
          }
        },
        {
          "call": "=PPMT(0.05/12,12,360,200000)",
          "correct": {
            "bits": "0xc06f71ce9e3ca452",
            "display": "-251.5564719376003",
            "how": "mpmath at 800 bits with rate the binary64 0x3f71111111111111 that 0.05/12 evaluates to; correctly rounded.",
            "kind": "number"
          },
          "excel": {
            "bits": "0xc06f71ce9e3ca456",
            "display": "-251.5564719376004",
            "kind": "number"
          },
          "input_route": "formula-literal",
          "inputs": [],
          "recorded_in": "Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA",
          "source": {
            "commit": "c9f9d354165d2c20b9455c32582ea50baac7ba73",
            "locator": "sheet dcj9k_annuity, row 749, column 4",
            "note": null,
            "path": "crates/calc-func/tests/captures/catalogue/sections/dcj9k_annuity.capture.json",
            "repository": "DnaCalc"
          }
        }
      ],
      "schema": "efh.function-note/v1",
      "statement": "With RN(v) meaning v rounded to 64 bits on the x87 unit and then stored to binary64, take L and q from PMT (FN-PMT-001; with nonzero fv, q = RN(N/em) with an fv numerator that is open). For period k of nper with end-of-period payments, m = nper-k+1, t = -(m*L), em_m is the expm1 of t by the route in FN-PMT-001, and u = exp(t) stored. Then IPMT = -RN(RN(RN(q*em_m) - RN(fv*u))*rate) and PPMT = RN(RN(RN(q - fv)*u)*rate). Interest takes the Kahan expm1, and principal takes the exponential it starts from: 1+em_m fits 36 of 74 principal rows where u fits all 74. So neither answer is the payment less the other (FN-PPMT-001).",
      "status": "measured",
      "title": "IPMT and PPMT reuse PMT's quotient, one through expm1 and the other through exp"
    }
  ],
  "schema": "efh.function-reference/v1",
  "section_order": [
    "what-it-does",
    "try-it",
    "quirks",
    "how-to-implement",
    "version-differences",
    "alternatives"
  ],
  "sections": {
    "alternatives": "\n[PPMT](FUNC.PPMT.md) returns principal and [PMT](FUNC.PMT.md) the full payment. [CUMIPMT](FUNC.CUMIPMT.md) totals interest over a period interval. [ISPMT](FUNC.ISPMT.md) uses a different level-principal model and a different period convention.\n\n\n\n\n",
    "how-to-implement": "\nUse [D and R](../model/09-staged-arithmetic.md) for ordinary binary64 storage and a stored 64-bit-significand operation. The current route keeps argument validation, timing boundaries and period arithmetic separate.\n\n1. Validate finite numeric arguments and require `1<=per<=nper`. For beginning timing at per=1, return zero before PMT’s rate-domain and reciprocal-pole checks. At exactly zero rate, other valid periods also return zero.\n2. For remaining calls reject a nonpositive growth base and obtain PMT under its own guards. A tiny nonzero rate retains the computation; do not use an epsilon band.\n3. For **end timing, fv=0 and a valid rate in the series range**, obtain L and the total-period corrected exponential difference `em_n` from the [PMT recipe](FUNC.PMT.md#how-to-implement). Store `q=R(pv/em_n)`; do not recover q by dividing PMT’s already rounded answer by r.\n4. Store `m=D(D(nper-per)+1)`, then `t=-D(m*L)`. Obtain the corrected difference `em_m` by the same spilled Kahan rule used for PMT.\n5. Return `-R(R(q*em_m)*r)`. Principal instead uses the separately stored EXP(t) result; `1+em_m` is not a substitute for that exponential.\n\nWorked second period of a two-period loan at r=0.25, pv=1000: the stated reconstruction has L `0.22314355131420974`, total em_n `-0.36000000000000004` and q `-2777.7777777777774`. One period remains, with em_m `-0.19999999999999998`; the stored products give interest `-138.88888888888886`. This trace evaluates the reconstruction, rather than adding an Excel capture.\n\nFor nonzero fv, the current end helper still forms `v_n=D(1+em_n)`, `N=D(pv+D(fv*v_n))` and `q=R(N/em_n)`. Its interest expression is `-R(R(R(q*em_m)-R(fv*EXP(t)))*r)`. This helper does **not** yet use the later nonzero-fv fold recovered for PMT itself. The note retains only 18 of 27 matching nonzero-fv interest controls; that numerator remains open here.\n\nThe helper declines rates outside its series range, opposite nonzero balances and zero/nonfinite em and nonfinite quotients. Beginning timing and other declined cases retain a separate backward-balance candidate with internal log1p/exponential leaves. They are not established by the zero-fv end-timing recipe. The source, first-period guard and unresolved fallback scope supersede the older page’s blanket recurrence description. The interactive calculator remains pinned separately.\n\n\n",
    "quirks": "\nThe documented period range is one through nper. The current helper returns `#NUM!` outside that range and distinguishes exactly zero rate from a tiny nonzero rate. Type is truncated by the wrapper before its zero/nonzero timing choice.\n\nThe newer source checks a valid beginning first period before its PMT rate guard, so it can return zero even at a rate PMT itself rejects. PPMT calls PMT first and can therefore have a different error path on that same otherwise invalid annuity.\n\nMathematically interest plus principal is the payment. Recorded Excel results can differ in their last bits from either subtraction identity: the notes retain a twelve-period example. Money amounts are not automatically rounded to cents by these functions.\n\n\n",
    "sources": "\n- [Microsoft: IPMT function](https://support.microsoft.com/en-us/excel/functions/ipmt-function), opened 6 November 2026; syntax, documented argument rules and errors.\n- [R31 financial implementation](https://github.com/DnaCalc/DnaCalc/blob/481f4ab85d3bf5a95b6daf959bb75ccb2f8b40f8/crates/calc-func/src/ported/financial_time_value_family.rs); `end_payment_quotient`, `end_payment_parts`, `ipmt` and `ppmt`, including distinct guard and fallback paths.\n- [Recorded stage controls](https://github.com/DnaCalc/DnaCalc/blob/481f4ab85d3bf5a95b6daf959bb75ccb2f8b40f8/crates/calc-func/tests/f3_financial.rs); payment-part and beginning-period controls. The notes below retain captured examples and their environments.\n\n",
    "try-it": "\n`=IPMT(0.25,2,2,1000)` is about `-138.8888889`. On this two-payment loan, the interest in the second period is charged on the balance remaining after the first payment. `=IPMT(0.25,1,2,1000,0,1)` returns zero because a beginning payment at the initial instant has no elapsed-period interest.\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 | 357 |\n| 20131 | Windows, bitness not recorded, AMD Ryzen 7 4800H with Radeon Graphics | 31 |\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.IPMT.json).",
    "what-it-does": "\n`IPMT(rate,per,nper,pv,[fv],[type])` returns the interest part of a constant annuity payment in one chosen period. The period comes before the total count and starts at one. Future value and timing default to zero; type one means payment at the beginning.\n\nUse a rate per payment period. A positive loan principal normally produces negative interest payments under Excel’s cash-flow sign convention.\n\n\n"
  },
  "signature": {
    "display": "IPMT(rate, per, nper, pv, [fv], [type])",
    "parameters": [
      {
        "description": null,
        "name": "rate",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "per",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "nper",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "pv",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "fv",
        "optional": true,
        "repeats": false
      },
      {
        "description": null,
        "name": "type",
        "optional": true,
        "repeats": false
      }
    ],
    "trailing_repeats": false
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 6,
        "min": 4
      },
      "category": "Financial functions",
      "classification": {
        "arg_preparation_profile": "RefsVisibleInAdapter",
        "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": "Interest part of one payment on a loan or investment",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns the interest payment for an investment for a given period",
        "microsoft_url": "https://support.microsoft.com/en-us/office/ipmt-function-5cce0ad6-8402-4a41-8d29-61a0b054cb6f"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "IPMT"
        },
        {
          "locale": "bg-BG",
          "name": "IPMT"
        },
        {
          "locale": "cs-CZ",
          "name": "PLATBA.ÚROK"
        },
        {
          "locale": "da-DK",
          "name": "R.YDELSE"
        },
        {
          "locale": "de-DE",
          "name": "ZINSZ"
        },
        {
          "locale": "el-GR",
          "name": "IPMT"
        },
        {
          "locale": "en-AU",
          "name": "IPMT"
        },
        {
          "locale": "en-GB",
          "name": "IPMT"
        },
        {
          "locale": "en-US",
          "name": "IPMT"
        },
        {
          "locale": "es-ES",
          "name": "PAGOINT"
        },
        {
          "locale": "et-EE",
          "name": "IPMT"
        },
        {
          "locale": "fi-FI",
          "name": "IPMT"
        },
        {
          "locale": "fr-FR",
          "name": "INTPER"
        },
        {
          "locale": "he-IL",
          "name": "IPMT"
        },
        {
          "locale": "hr-HR",
          "name": "IPMT"
        },
        {
          "locale": "hu-HU",
          "name": "RRÉSZLET"
        },
        {
          "locale": "id-ID",
          "name": "IPMT"
        },
        {
          "locale": "it-IT",
          "name": "INTERESSI"
        },
        {
          "locale": "ja-JP",
          "name": "IPMT"
        },
        {
          "locale": "ko-KR",
          "name": "IPMT"
        },
        {
          "locale": "lt-LT",
          "name": "IPMT"
        },
        {
          "locale": "lv-LV",
          "name": "IPMT"
        },
        {
          "locale": "nb-NO",
          "name": "RANNUITET"
        },
        {
          "locale": "nl-NL",
          "name": "IBET"
        },
        {
          "locale": "pl-PL",
          "name": "IPMT"
        },
        {
          "locale": "pt-BR",
          "name": "IPGTO"
        },
        {
          "locale": "pt-PT",
          "name": "IPGTO"
        },
        {
          "locale": "ro-RO",
          "name": "IPMT"
        },
        {
          "locale": "ru-RU",
          "name": "ПРПЛТ"
        },
        {
          "locale": "sk-SK",
          "name": "IPMT"
        },
        {
          "locale": "sl-SI",
          "name": "IPMT"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "IPMT"
        },
        {
          "locale": "sv-SE",
          "name": "RBETALNING"
        },
        {
          "locale": "th-TH",
          "name": "IPMT"
        },
        {
          "locale": "tr-TR",
          "name": "FAİZTUTARI"
        },
        {
          "locale": "uk-UA",
          "name": "IPMT"
        },
        {
          "locale": "vi-VN",
          "name": "IPMT"
        },
        {
          "locale": "zh-CN",
          "name": "IPMT"
        },
        {
          "locale": "zh-HK",
          "name": "IPMT"
        },
        {
          "locale": "zh-TW",
          "name": "IPMT"
        }
      ],
      "signature": {
        "display": "IPMT(rate, per, nper, pv, [fv], [type])",
        "parameters": [
          {
            "description": null,
            "name": "rate",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "per",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "nper",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "pv",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "fv",
            "optional": true,
            "repeats": false
          },
          {
            "description": null,
            "name": "type",
            "optional": true,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "IPMT",
      "version_marker": null,
      "xlcall": {
        "code": "167",
        "symbol": "xlfIpmt"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/ipmt-function-5cce0ad6-8402-4a41-8d29-61a0b054cb6f"
  },
  "try_it": {
    "formula": "=IPMT(0.25,2,2,1000)"
  },
  "url": "https://handbook.dnacalc.com/functions/IPMT.html",
  "variants": [],
  "versions": [
    {
      "behaviour": "=IPMT(0.05/12,12,360,200000) returned -822.0867740866778 (0xc089b0b1b69cc35f). Inputs were supplied through formula literals. These are controls from this environment, not a same-input comparison with another build.",
      "excel_build": "16.0.20527.20088",
      "observations": [
        {
          "call": "=IPMT(0.05/12,12,360,200000)",
          "excel": {
            "bits": "0xc089b0b1b69cc35f",
            "display": "-822.0867740866778",
            "kind": "number"
          },
          "input_route": "formula-literal",
          "inputs": [],
          "recorded_in": "Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA"
        }
      ],
      "platform": "Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA",
      "sources": [
        "https://github.com/DnaCalc/ExcelFunctionsHandbook/blob/3345a87/content/notes/FN-IPMT-001.json"
      ]
    },
    {
      "behaviour": "357 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.IPMT.json"
      ]
    },
    {
      "behaviour": "31 captured inputs are indexed for this environment. Capture dates: 2026-07-23 to 2026-07-23. This is a reading count, not a comparison with another build.",
      "excel_build": "16.0 build 20131",
      "platform": "Windows, bitness not recorded, AMD Ryzen 7 4800H with Radeon Graphics",
      "sources": [
        "https://github.com/DnaCalc/ExcelFunctionsHandbook/blob/5dc75391aa5125ccc5abdb095da85950980d6fd8/content/evidence/environments/FUNC.IPMT.json"
      ]
    }
  ]
}