const_soft_float/soft_f32/
sin.rs1use core::f64::consts::FRAC_PI_2;
18
19use crate::soft_f64::SoftF64;
20
21use super::{
22 helpers::{k_cosf, k_sinf, rem_pio2f},
23 SoftF32,
24};
25
26const S1_PIO2: SoftF64 = SoftF64(1.).mul(SoftF64(FRAC_PI_2)); const S2_PIO2: SoftF64 = SoftF64(2.).mul(SoftF64(FRAC_PI_2)); const S3_PIO2: SoftF64 = SoftF64(3.).mul(SoftF64(FRAC_PI_2)); const S4_PIO2: SoftF64 = SoftF64(4.).mul(SoftF64(FRAC_PI_2)); pub const fn sinf(x: SoftF32) -> SoftF32 {
33 let x64 = SoftF64(x.0 as f64);
34
35 let x1p120 = SoftF32::from_bits(0x7b800000); let mut ix = x.to_bits();
38 let sign = (ix >> 31) != 0;
39 ix &= 0x7fffffff;
40
41 if ix <= 0x3f490fda {
42 if ix < 0x39800000 {
44 if ix < 0x00800000 {
47 let _ = x.div(x1p120);
48 } else {
49 let _ = x.add(x1p120);
50 };
51 return x;
52 }
53 return k_sinf(x64);
54 }
55 if ix <= 0x407b53d1 {
56 if ix <= 0x4016cbe3 {
58 if sign {
60 return k_cosf(x64.add(S1_PIO2)).neg();
61 } else {
62 return k_cosf(x64.sub(S1_PIO2));
63 }
64 }
65 return k_sinf(if sign {
66 x64.add(S2_PIO2).neg()
67 } else {
68 x64.sub(S2_PIO2).neg()
69 });
70 }
71 if ix <= 0x40e231d5 {
72 if ix <= 0x40afeddf {
74 if sign {
76 return k_cosf(x64.add(S3_PIO2));
77 } else {
78 return k_cosf(x64.sub(S3_PIO2)).neg();
79 }
80 }
81 return k_sinf(if sign {
82 x64.add(S4_PIO2)
83 } else {
84 x64.sub(S4_PIO2)
85 });
86 }
87
88 if ix >= 0x7f800000 {
90 return x.sub(x);
91 }
92
93 let (n, y) = rem_pio2f(x);
95 match n & 3 {
96 0 => k_sinf(y),
97 1 => k_cosf(y),
98 2 => k_sinf(y.neg()),
99 _ => k_cosf(y).neg(),
100 }
101}
102
103#[cfg(test)]
104mod test {
105 use core::f32::consts::{FRAC_2_PI, FRAC_PI_2, FRAC_PI_3, PI};
106
107 use super::*;
108
109 #[test]
110 fn test_basic() {
111 for val in [0.0, FRAC_PI_3, FRAC_PI_2, PI, FRAC_2_PI] {
112 assert_eq!(SoftF32(val).sin().to_f32(), val.sin())
113 }
114 }
115}