/** * One-sided binomial tail: the probability of getting at least k correct out * of n trials by guessing (p = 1/2 per trial). Computed in log space so it * stays finite for large n. */ export function binomialTailP(k: number, n: number): number { if (n <= 0) return 1 if (k <= 0) return 1 let logTerm = -n * Math.LN2 // log C(n,0) 0.5^n let cum = 0 for (let i = 0; i <= n; i++) { if (i >= k) cum += Math.exp(logTerm) if (i < n) logTerm += Math.log(n - i) - Math.log(i + 1) } return Math.min(1, cum) } export function formatP(p: number): string { if (p >= 0.01) return p.toFixed(2) if (p >= 1e-4) return p.toFixed(4) return p.toExponential(1) }