use super::asin_acos::{acos_inner, asin_inner};
use super::{AsinAcos, RadToDeg};
use crate::traits::Int as _;
pub(crate) fn asind<F: AsinAcos + RadToDeg>(x: F) -> F {
let e = x.raw_exp();
if e == F::EXP_OFFSET && x.raw_mant() == F::Raw::ZERO {
F::cast_from(90u32).copysign(x)
} else if e >= F::EXP_OFFSET {
F::NAN
} else if e <= F::RawExp::from(F::MANT_BITS) {
x * F::rad_to_deg()
} else {
let y = asin_inner(x).to_semi();
(y * F::rad_to_deg_ex()).to_single()
}
}
pub(crate) fn acosd<F: AsinAcos + RadToDeg>(x: F) -> F {
let e = x.raw_exp();
if e == F::EXP_OFFSET && x.raw_mant() == F::Raw::ZERO {
if x.sign() {
F::cast_from(180u32)
} else {
F::ZERO
}
} else if e >= F::EXP_OFFSET {
F::NAN
} else if e == F::RawExp::ZERO {
F::cast_from(90u32)
} else {
let y = acos_inner(x).to_semi();
(y * F::rad_to_deg_ex()).to_single()
}
}
#[cfg(test)]
mod tests {
use crate::traits::Float;
use crate::FloatMath;
fn test_asind<F: Float + FloatMath>() {
use crate::asind;
let f = F::parse;
assert_is_nan!(asind(F::NAN));
assert_is_nan!(asind(f("1.5")));
assert_is_nan!(asind(f("-1.5")));
assert_is_nan!(asind(F::INFINITY));
assert_is_nan!(asind(F::neg_infinity()));
assert_total_eq!(asind(F::ZERO), F::ZERO);
assert_total_eq!(asind(-F::ZERO), -F::ZERO);
assert_total_eq!(asind(F::one()), f("90"));
assert_total_eq!(asind(-F::one()), f("-90"));
}
fn test_acosd<F: Float + FloatMath>() {
use crate::acosd;
let f = F::parse;
assert_is_nan!(acosd(F::NAN));
assert_is_nan!(acosd(f("1.5")));
assert_is_nan!(acosd(f("-1.5")));
assert_is_nan!(acosd(F::INFINITY));
assert_is_nan!(acosd(F::neg_infinity()));
assert_total_eq!(acosd(F::ZERO), f("90"));
assert_total_eq!(acosd(-F::ZERO), f("90"));
assert_total_eq!(acosd(F::one()), F::ZERO);
assert_total_eq!(acosd(-F::one()), f("180"));
}
#[test]
fn test_f32() {
test_asind::<f32>();
test_acosd::<f32>();
}
#[cfg(feature = "soft-float")]
#[test]
fn test_soft_f32() {
test_asind::<crate::SoftF32>();
test_acosd::<crate::SoftF32>();
}
#[test]
fn test_f64() {
test_asind::<f64>();
test_acosd::<f64>();
}
#[cfg(feature = "soft-float")]
#[test]
fn test_soft_f64() {
test_asind::<crate::SoftF64>();
test_acosd::<crate::SoftF64>();
}
}