(n: number)
| 51 | * exact path caps |argument| at 100, i.e. at most B₁₀₁). |
| 52 | */ |
| 53 | export function bernoulliRational(n: number): [bigint, bigint] { |
| 54 | if (!Number.isInteger(n) || n < 0) |
| 55 | throw new RangeError(`bernoulliRational: invalid index ${n}`); |
| 56 | |
| 57 | for (let m = BERNOULLI.length; m <= n; m++) { |
| 58 | // Odd m > 1: B_m = 0 |
| 59 | if (m % 2 === 1) { |
| 60 | BERNOULLI.push([0n, 1n]); |
| 61 | continue; |
| 62 | } |
| 63 | |
| 64 | // B_m = -1/(m+1) * sum_{k=0}^{m-1} C(m+1, k) * B_k |
| 65 | const mp1 = BigInt(m + 1); |
| 66 | let sumNum = 0n; |
| 67 | let sumDen = 1n; |
| 68 | let binom = 1n; // C(m+1, 0) = 1 |
| 69 | for (let k = 0; k < m; k++) { |
| 70 | if (k > 0) binom = (binom * (mp1 - BigInt(k) + 1n)) / BigInt(k); |
| 71 | const [bkNum, bkDen] = BERNOULLI[k]; |
| 72 | if (bkNum === 0n) continue; |
| 73 | sumNum = sumNum * bkDen + binom * bkNum * sumDen; |
| 74 | sumDen = sumDen * bkDen; |
| 75 | } |
| 76 | BERNOULLI.push(reduce(-sumNum, mp1 * sumDen)); |
| 77 | } |
| 78 | |
| 79 | return BERNOULLI[n]; |
| 80 | } |
| 81 | |
| 82 | /** |
| 83 | * The exact rational c such that ζ(2k) = c·π^{2k}, for integer k ≥ 1. |
no test coverage detected