use fracints_internals::traits::*;
use crate::fi16;
pub fn eval_simple_isqrt_lut(lut: &[fi16], cutoff: fi16, bits: usize, x: fi16) -> fi16 {
if (x < fi16::ZERO) || (x >= cutoff) {
return fi16::ZERO;
}
let x_i = x.as_int() as u16;
let inx0 = x_i >> (16 - 1 - bits);
let rem = x_i.wrapping_sub(inx0 << (16 - 1 - bits));
let rem_inx = fi16::from_int((rem << bits) as i16);
let inx0 = inx0.wrapping_sub(0b1 << (bits - 2));
let y0 = lut[inx0 as usize];
let inx1 = inx0.wrapping_add(1);
if (inx1 as usize) < lut.len() {
let y1 = lut[inx1 as usize];
y1.wrapping_sub(y0).wrapping_mul(rem_inx).wrapping_add(y0)
} else {
y0.wrapping_sub(y0.wrapping_mul(rem_inx))
}
}
pub fn goldschmidt<F: Fracint>(s: F, f: F, n: usize) -> F {
let half = (F::ONE >> 1).wrapping_add(F::ULP);
let mut r;
let mut g = f.wrapping_mul(s).wrapping_add(s);
let mut h = half.wrapping_add(f >> 1);
for i in 0..n {
r = half.wrapping_sub(g.wrapping_mul(h));
g = r.wrapping_mul(g).wrapping_add(g);
if i == (n - 1) {
break;
}
h = r.wrapping_mul(h).wrapping_add(h);
}
g
}