use crate::int::types::traits::BigInt;
use crate::int::types::Int;
use crate::support::rounding::RoundingMode;
const SCALE: u32 = 20;
#[inline]
#[must_use]
pub(crate) fn cbrt_newton_with_table_seed(raw: Int<3>, mode: RoundingMode) -> Int<3> {
if raw == Int::<3>::ZERO {
return Int::<3>::ZERO;
}
let zero = Int::<6>::ZERO;
let one = Int::<6>::ONE;
let widened: Int<6> = raw.resize_to::<Int<6>>();
let negative = widened < zero;
let mag = if negative { -widened } else { widened };
let n: Int<6> = mag * const { crate::consts::pow10::dispatch_int::<6>(2 * SCALE) };
let q: Int<6> = n.icbrt();
let eight_n = n << 3u32;
let t = q + q + one;
let cube = t * t * t;
let halfway_geq = eight_n >= cube;
let halfway_gt = eight_n > cube;
let tie = halfway_geq && !halfway_gt;
let two_q = q + q;
let eight_q_cubed = if q == zero { zero } else { two_q * two_q * two_q };
let residual_nonzero = eight_n > eight_q_cubed;
let q_is_odd = (q % (one + one)) != zero;
let bump = match mode {
RoundingMode::HalfToEven => halfway_gt || (tie && q_is_odd),
RoundingMode::HalfAwayFromZero => halfway_geq,
RoundingMode::HalfTowardZero => halfway_gt,
RoundingMode::Trunc => false,
RoundingMode::Floor => negative && residual_nonzero,
RoundingMode::Ceiling => !negative && residual_nonzero,
};
let q = if bump { q + one } else { q };
let signed = if negative { -q } else { q };
signed.resize_to::<Int<3>>()
}