use crate::algos::exp::exp_generic as eg;
use crate::algos::exp::exp_tang::tang_exp_fixed_g;
use crate::algos::support::wide_trig_core::WideTrigCore;
use crate::int::types::compute_limbs::ComputeLimbs;
use crate::int::types::traits::BigInt;
use crate::support::rounding::RoundingMode;
#[inline]
fn ex_enx_agm<C: WideTrigCore, const M: u32, const IE: bool>(
v: C::Wagm,
w: u32,
) -> (C::Wagm, C::Wagm)
where
<C::Wagm as BigInt>::Scratch: ComputeLimbs,
{
let ex = tang_exp_fixed_g::<C::Wagm, M, IE>(v, w, |ww| {
crate::consts::ln2_by_working_scale::<C::Wagm>(
ww,
crate::support::rounding::DEFAULT_ROUNDING_MODE,
)
});
let enx = eg::div::<C::Wagm>(eg::one::<C::Wagm>(w), ex, w);
(ex, enx)
}
#[inline]
#[must_use]
pub(crate) fn sinh_exp_identity_with_tang<
C: WideTrigCore,
const SCALE: u32,
const GUARD: u32,
const M: u32,
const IE: bool,
>(
raw: C::Storage,
mode: RoundingMode,
) -> C::Storage
where
<C::Wagm as BigInt>::Scratch: ComputeLimbs,
<C::Wexp as BigInt>::Scratch: ComputeLimbs,
{
let w = SCALE + GUARD;
let v = C::to_work_scaled_agm(raw, GUARD);
let (ex, enx) = ex_enx_agm::<C, M, IE>(v, w);
let r = (ex - enx) / eg::lit::<C::Wagm>(2);
match crate::algos::support::wide_trig_core::round_to_storage_clear_of_tie_g::<
C::Storage,
C::Wagm,
>(r, w, SCALE, mode, C::storage_max(), C::storage_min())
{
Some(st) => st,
None => crate::algos::trig::hyper_schoolbook::sinh_schoolbook::<C, SCALE>(raw, mode),
}
}
#[inline]
#[must_use]
pub(crate) fn cosh_exp_identity_with_tang<
C: WideTrigCore,
const SCALE: u32,
const GUARD: u32,
const M: u32,
const IE: bool,
>(
raw: C::Storage,
mode: RoundingMode,
) -> C::Storage
where
<C::Wagm as BigInt>::Scratch: ComputeLimbs,
<C::Wexp as BigInt>::Scratch: ComputeLimbs,
{
crate::algos::support::wide_trig_core::round_to_storage_directed_g::<C::Storage, C::Wagm>(
GUARD,
SCALE,
mode,
C::storage_max(),
C::storage_min(),
|guard| {
let w = SCALE + guard;
let v = C::to_work_scaled_agm(raw, guard);
let (ex, enx) = ex_enx_agm::<C, M, IE>(v, w);
(ex + enx) / eg::lit::<C::Wagm>(2)
},
)
}
#[inline]
#[must_use]
pub(crate) fn tanh_exp_identity_with_tang<
C: WideTrigCore,
const SCALE: u32,
const GUARD: u32,
const M: u32,
const IE: bool,
>(
raw: C::Storage,
mode: RoundingMode,
) -> C::Storage
where
<C::Wagm as BigInt>::Scratch: ComputeLimbs,
<C::Wexp as BigInt>::Scratch: ComputeLimbs,
{
let zero = C::storage_zero();
if raw != zero {
let thresh_exp = SCALE - SCALE.div_ceil(3);
let thresh = <C::Storage as BigInt>::TEN.pow(thresh_exp);
let abs_raw = if raw < zero { -raw } else { raw };
if abs_raw <= thresh {
return crate::support::rounding::tiny_odd_compressing_directed(
raw,
zero,
<C::Storage as BigInt>::ONE,
mode,
);
}
}
let w = SCALE + GUARD;
let v = C::to_work_scaled_agm(raw, GUARD);
let (ex, enx) = ex_enx_agm::<C, M, IE>(v, w);
let r = eg::div::<C::Wagm>(ex - enx, ex + enx, w);
match crate::algos::support::wide_trig_core::round_to_storage_clear_of_tie_g::<
C::Storage,
C::Wagm,
>(r, w, SCALE, mode, C::storage_max(), C::storage_min())
{
Some(st) => st,
None => crate::algos::trig::hyper_schoolbook::tanh_schoolbook::<C, SCALE>(raw, mode),
}
}