Function nekolib::math::stern_brocot
source · pub fn stern_brocot(
n: i128,
large: impl FnMut(i128, i128) -> bool,
ok: impl FnMut(i128, i128) -> bool
) -> Result<(i128, i128), ((i128, i128), (i128, i128))>
Expand description
Stern–Brocot tree
$a/b = 0/1=0$ と $c/d = 1/0=\infty$ で初期化し、その mediant $x/y = (a+b)/(c+d)$ を探索する。
$x/y$ が所望の条件 ok
を満たすならそれを Ok
として返す。
条件 large
を満たすなら $c/d\gets x/y$、そうでなければ $a/b\gets x/y$
として探索を進める。
分母が $n$ を超えても ok
を満たさなければ、$((a, b), (c, d))$ を
Err
として返す。
Examples
use nekolib::math::stern_brocot;
let (num, den) =
stern_brocot(10_i128.pow(18), |n, d| n * n > 3 * d * d, |_, _| false)
.err().unwrap().0;
let sqrt3 = num as f64 / den as f64;
assert!((sqrt3 - 3.0_f64.sqrt()).abs() < 1.0e-16);
assert_eq!((num, den), (734231055024833855, 423908497265970753));