(r: Rational)
| 235 | export function reducedRational(r: [bigint, bigint]): [bigint, bigint]; |
| 236 | export function reducedRational(r: Rational): Rational; |
| 237 | export function reducedRational(r: Rational): Rational { |
| 238 | if (isMachineRational(r)) { |
| 239 | // Normalize negative denominator first (before early return) |
| 240 | if (r[1] < 0) r = [-r[0], -r[1]]; |
| 241 | if (r[0] === 1 || r[1] === 1) return r; |
| 242 | if (!Number.isFinite(r[1])) return [0, 1]; |
| 243 | const g = gcd(r[0], r[1]); |
| 244 | // If the gcd is 0, return the rational unchanged |
| 245 | return g <= 1 ? r : [r[0] / g, r[1] / g]; |
| 246 | } |
| 247 | |
| 248 | if (r[1] < 0) r = [-r[0], -r[1]]; |
| 249 | |
| 250 | const g = bigGcd(r[0], r[1]); |
| 251 | |
| 252 | // If the gcd is 0, return the rational unchanged |
| 253 | const [n, d] = g <= 1 ? r : [r[0] / g, r[1] / g]; |
| 254 | |
| 255 | if ( |
| 256 | n <= Number.MAX_SAFE_INTEGER && |
| 257 | n >= Number.MIN_SAFE_INTEGER && |
| 258 | d <= Number.MAX_SAFE_INTEGER |
| 259 | ) |
| 260 | return [Number(n), Number(d)]; |
| 261 | return [n, d]; |
| 262 | } |
| 263 | |
| 264 | /** |
| 265 | * Return `value / denom` as an exact reduced machine rational, or `null` if |
no test coverage detected