How Worth the Test does its math
Open this calculator with the numbers it starts on — 1,000 people, a disease that affects 1% of them, and a test that is 90% sensitive and 90% specific — and it reports that a positive result carries only about an 8% chance of real disease. That figure surprises almost everyone, so this page shows exactly how the tool gets there. Every output on the site comes from the formulas below; nothing is a black box, and every number in this guide can be reproduced by typing the same inputs into the calculator.
From a population to a 2×2 table
The model starts with a whole population and splits it by prevalence — the share who actually have the condition, which is also the pre-test probability for a person drawn at random. With N people and prevalence p, the diseased group is N·p and the healthy group is N·(1 − p). For the starting scenario that is 10 people with the disease and 990 without.
Everyone is then screened, and each person lands in one of four cells of a 2×2 table — the tool's confusion matrix view — set by whether they are truly sick and how the test calls them:
- True positives (TP) = diseased × sensitivity — the sick people the test catches. Here 10 × 0.90 = 9.
- False negatives (FN) = diseased × (1 − sensitivity) — sick people the test misses. Here 10 × 0.10 = 1.
- False positives (FP) = healthy × (1 − specificity) — healthy people wrongly flagged. Here 990 × 0.10 = 99.
- True negatives (TN) = healthy × specificity — healthy people correctly cleared. Here 990 × 0.90 = 891.
Those four counts always sum back to N (9 + 1 + 99 + 891 = 1,000), and the two rows sum to the diseased and healthy groups you started with. Sensitivity and specificity are fixed properties of the test; the split into these four cells is where prevalence quietly takes over.
Reading the table: predictive values
Sensitivity answers "if you are sick, will the test catch it?" A patient holding a positive result wants the reverse: "given this positive, am I actually sick?" That is the positive predictive value, and you read it straight off the table as the share of all positives that are true:
PPV = TP / (TP + FP) = 9 / (9 + 99) = 9 / 108 ≈ 8.3%.
Written in terms of the inputs, that is Bayes' theorem: PPV = (sens·p) / (sens·p + (1 − spec)·(1 − p)). The mirror-image quantity for a negative result is the negative predictive value, the share of negatives that are truly disease-free: NPV = TN / (TN + FN) = 891 / 892 ≈ 99.9%. A negative on this test is strongly reassuring; a positive, at this prevalence, is usually a false alarm — the base-rate fallacy expressed in one calculation.
Try it
Open the default scenario and read the 2×2 table: 9 true positives against 99 false positives, for a PPV of about 8%.
Open this scenario in the calculator →Likelihood ratios and the odds form of Bayes
Predictive values are useful, but they move with prevalence, so they have to be recomputed for every population. Likelihood ratios strip prevalence out and describe the test alone:
LR+ = sens / (1 − spec) = 0.90 / 0.10 = 9 · LR− = (1 − sens) / spec = 0.10 / 0.90 ≈ 0.11.
An LR+ of 9 means a positive result is nine times as likely to come from a sick person as from a healthy one. To turn that into a probability you apply Bayes' rule in odds form: convert the pre-test probability to odds, multiply by the likelihood ratio, convert back.
- Pre-test odds = p / (1 − p) = 0.01 / 0.99 ≈ 0.0101.
- Post-test odds = 0.0101 × 9 ≈ 0.0909.
- Post-test probability = 0.0909 / (1 + 0.0909) ≈ 0.083.
That 8.3% is the very same PPV the 2×2 table gave. The count path and the odds path are two routes to one number — the equality the tool draws as a live Fagan nomogram, where a straight line from your pre-test probability through the likelihood ratio lands on the post-test probability. Likelihood ratios also chain, so working from pre-test to post-test probability across several tests is just repeated multiplication of the odds.
From detection to treatment: who is helped, who is harmed
A test result is not an outcome. The calculator's second half follows the people who test positive into treatment and asks what it actually does for them. The people treated are the positives, optionally scaled by an uptake fraction for those who decline or never follow up:
treated = (TP + FP) × uptake.
Benefit can only reach people who truly have the disease, so it is governed by the number needed to treat: helped = treated true-positives / NNT. Harm can befall anyone who undergoes the treatment or work-up, so it is spread across everyone treated: harmed = treated / NNH. Scaling the starting scenario up to 10,000 people so the tallies stay whole, with NNT = 10 and NNH = 20: 1,080 people are treated, 90 / 10 = 9 are helped, 1,080 / 20 = 54 are harmed, and the remaining 1,017 see no change either way.
Two honesty guards sit on top of that. First, helped and harmed are modeled as disjoint groups — a teaching simplification that lets the outcome bar partition cleanly into helped, harmed, and no-change, not a claim that one person can never experience both. Second, because the two counts use different denominators, in extreme settings they can add up to more than the number actually treated; when they do, the model applies a joint cap, scaling both down by the same factor so they never exceed the treated total. (Push both NNT and NNH to 1 in the default scenario and the raw 9 helped plus 108 harmed would total 117 against 108 treated, so each is rescaled by 108/117 while their ratio is preserved.) Folding the whole chain together gives the number needed to screen — NNS = N / helped — which here is 10,000 / 9 ≈ 1,111 people screened for each person helped.
Honest numbers: absolute versus relative
The same benefit can be dressed up or down depending on which number you quote. A treatment with an NNT of 20 delivers an absolute risk reduction of 1/20 = 5% — five fewer bad outcomes per hundred treated. If the untreated risk were 10%, that identical five-point drop is a relative risk reduction of 5/10 = 50%, which sounds far more impressive while describing the very same effect. Relative figures alone routinely mislead, so the tool holds every claim to two rules: always present the absolute risk reduction, the NNT, and the baseline risk together, and pair every benefit count with the matching harm count on the same footing. Whether a given trade of helped against harmed is worth making is a value judgment this site deliberately leaves to you and your clinician; the harms and biases of screening are their own subject.
Repeat testing: why false positives pile up
Screening is rarely a one-time event, and each round is a fresh chance at a false alarm. If rounds were statistically independent, the probability of at least one false positive after n rounds is:
P(≥1 false positive) = 1 − specificity^n.
For the 90%-specific default test over ten rounds that is 1 − 0.90^10 ≈ 65.1% — a healthy person is more likely than not to be flagged at least once. The tool draws this as a rising curve in its repeat-testing view.
Real repeat testing is not independent, so this formula is an upper bound, not a prediction. Re-testing the same person tends to re-flag the same harmless quirk, which correlates the errors and pushes the true rate below the curve; scanning many organs in a single round adds independent chances and can push it above. Two long-running trials anchor the reality: in a mammography cohort, Elmore and colleagues found a 49.1% cumulative chance of at least one false positive after ten screening rounds; in the PLCO trial's multimodal rounds, Croswell and colleagues found 60.4% for men and 48.8% for women after fourteen tests.
Try it
Load a mammography-like test (≈87% sensitive, ≈89% specific) and scroll to repeat testing: the independence curve climbs to about 69% by the tenth round, while Elmore's real cohort saw 49.1% — the gap is the correlation the formula ignores.
Open the mammography scenario →Guardrails and honest rounding
A live calculator has to stay well-behaved at the edges. Probabilities are clamped to the [0, 1] range; NNT and NNH are floored at 1; and every division is guarded, so an empty group shows an em dash rather than a meaningless "NaN". Perfect specificity is a special case worth naming: when specificity is exactly 1 there are no false positives, the 1 − spec denominator vanishes, and LR+ becomes infinite — a positive then "rules in" the disease outright, which the tool labels rather than crashing on.
The icon array and every displayed count are whole people, but the raw arithmetic produces fractions. Rounding each cell on its own would let the parts drift away from the whole — three groups of 33.3 rounding to 99, not 100. The tool instead uses the largest-remainder method: it rounds every cell down, then hands the leftover units to the cells with the largest fractional parts until the counts sum exactly to their parent total. Whatever the inputs, the four cells of the 2×2 add back to N and the outcome groups add back to the number treated.
How we know the math is right
All of this lives in a small set of pure functions — no interface, no styling, just inputs and outputs — in the project's src/lib/stats/ module, which carries its own written specification. Keeping the math separate from the display makes it testable, and it is tested: at the time of writing, the engine is covered by 39 automated checks across three files. Some are worked examples pinned to exact expected values, including the 8.3% PPV and the 65.1% serial figure used above. Others are property-based "fuzz" tests that generate thousands of random scenarios — 6,000 full population cascades in one block alone — and assert that the invariants never break: people are conserved at every stage, the integer counts always reconcile to their totals, no probability escapes the [0, 1] range, and the odds path and the 2×2 path agree to within rounding. That last check is what lets this page promise the two routes to PPV give the same answer — it is verified automatically, not merely asserted here. If you want to inspect the machinery, the calculator's own worked example and references open the same numbers in the live tool.
References
- Fagan TJ. Nomogram for Bayes's theorem. N Engl J Med, 1975;293(5):257.
- Elmore JG, Barton MB, Moceri VM, et al. Ten-year risk of false positive screening mammograms and clinical breast examinations. N Engl J Med, 1998;338(16):1089–1096.
- Croswell JM, Kramer BS, Kreimer AR, et al. Cumulative incidence of false-positive results in repeated, multimodal cancer screening. Ann Fam Med, 2009;7(3):212–222.
- Lehman CD, Arao RF, Sprague BL, et al. National performance benchmarks for modern screening digital mammography (BCSC). Radiology, 2017;283(1):49–58.
- Gigerenzer G, Edwards A. Simple tools for understanding risks: from innumeracy to insight. BMJ, 2003;327(7417):741–744.
- Gøtzsche PC, Jørgensen KJ. Screening for breast cancer with mammography. Cochrane Database of Systematic Reviews, 2013.