"use strict"; function round2(x) { return Math.round(x * 100) / 100; } module.exports = { slug: "percent-of-and-percent-change", title: "Percent of a value, or percent change between two values", deck_category: "other", description: "Computes either a percentage of a base value, or the percent change from an old value to a new value.", inputs: [ { name: "operation", type: "string", required: true, description: "Which calculation to perform.", enum: ["percent_of", "percent_change"] }, { name: "base", type: "number", required: true, description: "For percent_of: the value to take a percentage of. For percent_change: the old (starting) value." }, { name: "percent", type: "number", unit: "%", required: false, description: "Required for percent_of: the percentage to apply to base." }, { name: "new_value", type: "number", required: false, description: "Required for percent_change: the new (ending) value." } ], outputs: [ { name: "result", description: "For percent_of: the computed amount. For percent_change: the percent change (positive is an increase, negative a decrease)." } ], steps: [ "If operation is percent_of: result = base * percent / 100.", "If operation is percent_change: result = ((new_value - base) / base) * 100, expressed in percent.", "Round to 2 decimals." ], constants: [], sources: [ { kind: "edition_page", value: "Standard arithmetic reference (percentage and percent-change definitions).", title: "Percentage and percent-change formulas", publisher: "Standard arithmetic reference", retrieved_utc: "2026-09-30T19:56:00Z", note: "result=base*percent/100; percent change=(new-old)/old*100." } ], disclaimer: null, questionText(inputs) { if (inputs.operation === "percent_of") return `What is ${inputs.percent}% of ${inputs.base}?`; return `What is the percent change from ${inputs.base} to ${inputs.new_value}?`; }, run(inputs) { const { operation, base, percent, new_value } = inputs || {}; if (operation !== "percent_of" && operation !== "percent_change") throw new Error("operation must be percent_of or percent_change"); if (typeof base !== "number") throw new Error("base must be a number"); if (operation === "percent_of") { if (typeof percent !== "number") throw new Error("percent is required for percent_of"); const result = round2((base * percent) / 100); return { answer: `${result.toFixed(2)}`, values: { result } }; } if (typeof new_value !== "number") throw new Error("new_value is required for percent_change"); if (base === 0) throw new Error("base must be non-zero for percent_change"); const result = round2(((new_value - base) / base) * 100); return { answer: `${result.toFixed(2)}%`, values: { result } }; }, examples: [ { name: "worked example", inputs: { operation: "percent_of", base: 250, percent: 12 }, expected: { answer: "30.00" }, check: "By decomposition: 10% of 250 is 25, 2% of 250 is 5, sum is 30, matching 250*12/100=30." }, { name: "test vector: percent change", inputs: { operation: "percent_change", base: 80, new_value: 100 }, expected: { answer: "25.00%" }, check: "By hand: 100 is 20 more than 80; 20/80=0.25=25%, matching ((100-80)/80)*100=25.00." } ] };