Let Language Models Read. Let Code Calculate.
In this essay
Ask a language model to explain a financial statement and it may produce a convincing summary. Ask it to calculate the change in operating margin and the same fluent interface can conceal several distinct tasks: locating numbers, interpreting their units, selecting comparable periods, and applying arithmetic.
Treating those tasks as one act of text generation makes failures difficult to diagnose. Separating them creates a workflow in which each step can be tested.
A correct number can answer the wrong question
Use a fictional company with the following simplified figures, all in millions of dollars:
| Metric | Year 1 | Year 2 |
|---|---|---|
| Revenue | 800 | 1,000 |
| Operating income | 80 | 150 |
Revenue growth is (1,000 − 800) / 800, or 25%. Operating margin rises from 10% to 15%. That is a five percentage point increase, equivalent to 500 basis points. The relative increase in the margin is 50%.
“Margin improved by 5%” is therefore ambiguous. It might mean a five percentage point movement or a 5% relative increase. Those would be different results. A calculator cannot resolve the ambiguity unless the intended definition is supplied first.
The FinQA research paper treats financial question answering as a numerical reasoning problem over reports, with annotated reasoning programs. Its historical benchmark findings are not a current ranking of models; the useful design lesson is to preserve how an answer was calculated.
Give extraction a contract
Before calculating, create a structured record for each input. Include the entity, statement, metric, period, unit, accounting basis, and source location. Do not turn a blank or unavailable field into zero merely because zero is easier to process.
1 | metric: operating_income |
For a real filing, the source field should identify a document and a specific table or section. Keep reported and adjusted figures in separate fields. Comparing one year’s adjusted measure with another year’s reported measure can create a mathematically tidy but analytically invalid growth rate.
Period checks also matter. A year-to-date cash flow is not automatically a single-quarter cash flow. Subtracting a comparable prior year-to-date figure may be appropriate in some cases, but the periods, restatements, and definitions must be reconciled first.
Keep the calculation small and inspectable
The arithmetic for the example does not need a language model:
1 | from decimal import Decimal |
The output is 0.25, 0.1, 0.15, followed by 5.00 percentage points and 500.00 basis points. Decimal arithmetic makes these simple decimal operations exact; it does not make the original accounting data intrinsically certain.
For negative starting values, a conventional growth percentage can be misleading. A move from a loss to a profit often deserves an absolute change and a clear explanation rather than a dramatic percentage derived from a negative denominator.
Return the result with its lineage
A strong final answer includes the metric definition, inputs, operation, and source locations alongside the prose. For the example: “Operating margin increased from 10% to 15%, a five percentage point improvement, using reported operating income divided by revenue.”
That sentence is useful because a reader can reproduce it. A bare “profitability improved significantly” is harder to audit and loses information about the size and basis of the change.
The language model still has a role: proposing where to look, extracting candidate fields, explaining the calculation, and identifying unanswered questions. The calculator has a narrower role: reliably performing an explicitly defined operation on validated inputs.
Evaluate the whole chain
Test extraction accuracy separately from arithmetic correctness and final-answer support. Include cases with different units, missing values, negative denominators, restated comparatives, and both reported and adjusted measures.
A system that passes arithmetic tests but regularly selects the wrong reporting period is not ready for financial analysis. Conversely, a reliable extractor does not justify letting free-form generated text invent the calculation that follows.
The aim is not to declare code infallible or language models incapable of arithmetic. It is to put each failure somewhere visible. A financial answer becomes more useful when the reader can see exactly which numbers entered it and which operations connect them.