use astro_float::BigFloat;
use crate::{context::Context, CalcError, CalcResult, Number, PREC, RM};
pub fn sqrt(args: &[Number], _ctx: &Context) -> CalcResult {
Ok(args[0].sqrt(PREC, RM))
}
pub fn ln(args: &[Number], _ctx: &Context) -> CalcResult {
let mut consts = astro_float::Consts::new().map_err(|_| CalcError::Unknown)?;
Ok(args[0].ln(PREC, RM, &mut consts))
}
pub fn log(args: &[Number], _ctx: &Context) -> CalcResult {
let mut consts = astro_float::Consts::new().map_err(|_| CalcError::Unknown)?;
Ok(args[0].log10(PREC, RM, &mut consts))
}
pub fn sin(args: &[Number], _ctx: &Context) -> CalcResult {
let mut consts = astro_float::Consts::new().map_err(|_| CalcError::Unknown)?;
let res = if args[0].rem(&consts.pi(PREC, RM)).abs() == BigFloat::from_f32(0.0, PREC) {
BigFloat::from_f32(0.0, PREC)
} else {
args[0].sin(PREC, RM, &mut consts)
};
Ok(res)
}
pub fn cos(args: &[Number], _ctx: &Context) -> CalcResult {
let mut consts = astro_float::Consts::new().map_err(|_| CalcError::Unknown)?;
let res = if args[0]
.rem(&consts.pi(PREC, RM))
.div(&consts.pi(PREC, RM), PREC, RM)
.abs()
== BigFloat::from_f32(0.5, PREC)
{
BigFloat::from_f32(0.0, PREC)
} else {
args[0].cos(PREC, RM, &mut consts)
};
Ok(res)
}
pub fn tan(args: &[Number], _ctx: &Context) -> CalcResult {
let mut consts = astro_float::Consts::new().map_err(|_| CalcError::Unknown)?;
Ok(args[0].tan(PREC, RM, &mut consts))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_trig() {
let mut consts = astro_float::Consts::new().unwrap();
let ctx = Context::new();
let pi = consts.pi(PREC, RM);
let two = BigFloat::from_f32(2.0, PREC);
let two_pi = pi.mul(&two, PREC, RM);
let pi_by_2 = pi.div(&two, PREC, RM);
println!("{}", sin(&[consts.pi(PREC, RM)], &ctx).unwrap());
println!("{}", sin(&[two_pi], &ctx).unwrap());
println!("{}", cos(&[pi_by_2], &ctx).unwrap());
}
}