{
  "schemaVersion": 1,
  "slug": "half-life-calculator",
  "category": "science",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "6a4e9d3f829ac3819919ef2a2f7d6c7dc57c75e2a7565fde11ae6454c06a4b5e",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/half-life-calculator.json",
    "src/engine.js"
  ],
  "runtimeSource": "/sources/engine.txt",
  "runtimeHash": "5c888d8898afbdee36267bb9977829e1e2ac568f6677c8ee87469c139864645c",
  "scope": "The compute function records implemented equations, constants, lookup tables and custom rules. Inputs record defaults and allowed values; outputs record precision and units. Defaults are examples, not recommendations. General background references are not evidence for this specific algorithm.",
  "publishedFormula": {
    "formula": "N(t) = N_0×0.5^(t/t_½); λ = ln 2/t_½",
    "vars": [
      [
        "N_0",
        "Initial amount"
      ],
      [
        "t",
        "Elapsed time"
      ],
      [
        "t_½",
        "Half-life"
      ],
      [
        "N(t)",
        "Remaining amount"
      ],
      [
        "λ",
        "Decay constant"
      ]
    ],
    "note": "Elapsed time and half-life must use the same unit. The decay constant is per that input unit; 10% remains after 3.3219 half-lives. This is a mathematical model only."
  },
  "externalEvidence": {
    "reviewedAt": "2026-10-04",
    "sources": [
      {
        "name": "OpenStax — Radioactive decay",
        "url": "https://openstax.org/books/chemistry-2e/pages/21-3-radioactive-decay"
      }
    ],
    "basis": "Remaining amount = initial amount × 0.5^(elapsed time / half-life); decay constant = ln(2) / half-life.",
    "limitations": "Assumes a constant half-life and one exponential decay process. Time to 10% is displayed as a number of half-lives, not elapsed time in the input time unit. No decay-chain or variable-rate model is included.",
    "implementationHash": "6a4e9d3f829ac3819919ef2a2f7d6c7dc57c75e2a7565fde11ae6454c06a4b5e"
  },
  "contract": {
    "compute": "const hl=Math.max(1e-9,halfLife); const n=elapsedTime/hl; const remaining=initialAmount*Math.pow(0.5,n); return {remaining,decayed:initialAmount-remaining,percentRemaining:initialAmount>0?remaining/initialAmount*100:0,halfLives:n,decayConstant:Math.LN2/hl,timeTo10:Math.log(0.1)/Math.log(0.5)};",
    "inputs": [
      {
        "name": "initialAmount",
        "type": "number",
        "default": 100,
        "min": 0,
        "max": 1000000,
        "step": 0.001
      },
      {
        "name": "halfLife",
        "type": "number",
        "default": 5.27,
        "min": 0.000001,
        "max": 1000000000,
        "step": 0.000001
      },
      {
        "name": "elapsedTime",
        "type": "number",
        "default": 10,
        "min": 0,
        "max": 1000000000,
        "step": 0.01
      }
    ],
    "outputs": [
      {
        "name": "remaining",
        "precision": 6,
        "unit": "g"
      },
      {
        "name": "decayed",
        "precision": 6,
        "unit": "g"
      },
      {
        "name": "percentRemaining",
        "precision": 4,
        "unit": "%"
      },
      {
        "name": "halfLives",
        "precision": 3,
        "unit": ""
      },
      {
        "name": "decayConstant",
        "precision": 6,
        "unit": "per unit time"
      },
      {
        "name": "timeTo10",
        "precision": 3,
        "unit": "periods"
      }
    ],
    "interpret": null
  }
}
