use crate::int::types::compute_limbs::{ComputeLimbs, Limbs};
use crate::int::types::Int;
use crate::support::rounding::RoundingMode;
#[inline]
#[must_use]
pub(crate) fn hypot_pythagoras<const N: usize>(a: Int<N>, b: Int<N>, mode: RoundingMode) -> Option<Int<N>>
where
Limbs<N>: ComputeLimbs,
{
crate::int::policy::hypot::dispatch::<N>(a, b, mode)
}
#[cfg(test)]
mod tests {
use super::hypot_pythagoras;
use crate::int::types::Int;
use crate::support::rounding::RoundingMode;
const ALL_MODES: [RoundingMode; 6] = [
RoundingMode::HalfToEven,
RoundingMode::HalfAwayFromZero,
RoundingMode::HalfTowardZero,
RoundingMode::Trunc,
RoundingMode::Floor,
RoundingMode::Ceiling,
];
#[test]
fn hypot_pythagoras_pythagorean_3_4_5_all_modes() {
let a = Int::<2>::from_i64(3);
let b = Int::<2>::from_i64(4);
let expected = Int::<2>::from_i64(5);
for mode in ALL_MODES {
assert_eq!(hypot_pythagoras::<2>(a, b, mode), Some(expected), "mode {mode:?}");
}
}
#[test]
fn hypot_pythagoras_non_perfect_1_1() {
let a = Int::<2>::from_i64(1);
let b = Int::<2>::from_i64(1);
assert_eq!(hypot_pythagoras::<2>(a, b, RoundingMode::Trunc).unwrap().as_i128(), 1);
assert_eq!(hypot_pythagoras::<2>(a, b, RoundingMode::Ceiling).unwrap().as_i128(), 2);
assert_eq!(hypot_pythagoras::<2>(a, b, RoundingMode::HalfToEven).unwrap().as_i128(), 1);
}
#[test]
fn hypot_pythagoras_zero_zero() {
let z = Int::<2>::from_i64(0);
for mode in ALL_MODES {
assert_eq!(hypot_pythagoras::<2>(z, z, mode), Some(z), "mode {mode:?}");
}
}
#[test]
fn hypot_pythagoras_zero_x_equals_abs_x() {
let z = Int::<2>::from_i64(0);
let x = Int::<2>::from_i64(42);
for mode in ALL_MODES {
assert_eq!(hypot_pythagoras::<2>(z, x, mode), Some(x), "mode {mode:?}");
}
}
}