///|
/// Compute sine of double-precision floating-point number `x`.
///
/// # Examples
///
/// ```moonbit nocheck
/// assert_eq(sinf(-1.0), -0.8414709848078965)
/// assert_eq(sinf(0.0), 0)
/// assert_eq(sinf(1.5707963267948966), 1.0)
/// assert_eq(sinf(3.141592653589793), -8.742277657347586e-8)
/// assert_eq(sinf(10000), -0.30561438888825215)
/// ```
///
/// # Special Cases
///
/// 1. sinf(+-inf) = NaN
/// 2. sinf(NaN) = NaN
///
/// # Accuracy
///
/// 0 ulp.
pub fn sinf(x : Float) -> Float {
if x.is_nan() || x.is_inf() {
return @float.not_a_number
}
if x == 0.0 {
return x
}
let (x, q) = trig_reduce(x, SIN_SWITCHOVER)
sin_cos_core(x, q)
}
///|
test "sinf" {
fn assert_sinf_ulp(input, expect) raise {
assert_float_ulp(expect, sinf(input), SIN_F_MAX_ULP)
}
assert_sinf_ulp(-1, -0.8414709568023682)
assert_sinf_ulp(1, 0.8414709568023682)
assert_sinf_ulp(8, 0.9893582463264465)
assert_sinf_ulp(-8, -0.9893582463264465)
assert_sinf_ulp(0, 0)
assert_sinf_ulp(27, 0.9563759565353394)
assert_sinf_ulp(-27, -0.9563759565353394)
assert_sinf_ulp(0.125, 0.1246747300028801)
assert_sinf_ulp(-0.125, -0.1246747300028801)
assert_sinf_ulp(0.5, 0.4794255495071411)
assert_sinf_ulp(-0.5, -0.4794255495071411)
assert_sinf_ulp(1.5, 0.9974949955940247)
assert_sinf_ulp(-1.5, -0.9974949955940247)
assert_sinf_ulp(2, 0.9092974066734314)
assert_sinf_ulp(-2, -0.9092974066734314)
assert_sinf_ulp(3, 0.14112000167369843)
assert_sinf_ulp(-3, -0.14112000167369843)
assert_sinf_ulp(64, 0.9200260639190674)
assert_sinf_ulp(-64, -0.9200260639190674)
assert_sinf_ulp(1000, 0.8268795013427734)
assert_sinf_ulp(-1000, -0.8268795013427734)
assert_sinf_ulp(512, 0.07951848953962326)
assert_sinf_ulp(729, 0.14993681013584137)
assert_sinf_ulp(3511808, -0.5998656749725342)
assert_sinf_ulp(15.25, 0.4421221613883972)
assert_sinf_ulp(6859, -0.7853350639343262)
assert_sinf_ulp(68.25, -0.7611201405525208)
assert_sinf_ulp(701.625, -0.8673427104949951)
assert_sinf_ulp(@float.not_a_number, @float.not_a_number)
assert_sinf_ulp(@float.infinity, @float.not_a_number)
assert_sinf_ulp(@float.neg_infinity, @float.not_a_number)
}