1//! Sine approximation, implemented in terms of `cos(x)`.
2
3use super::F32;
4use core::f32::consts::PI;
5
6impl F32 {
7 /// Approximates `sin(x)` in radians with a maximum error of `0.002`.
8 pub fn sin(self) -> Self {
9 (self - PI / 2.0).cos()
10 }
11}
12
13#[cfg(test)]
14mod tests {
15 use super::F32;
16 use crate::float::cos::tests::MAX_ERROR;
17
18 /// Sine test vectors - `(input, output)`
19 const TEST_VECTORS: &[(f32, f32)] = &[
20 (0.000, 0.000),
21 (0.140, 0.139),
22 (0.279, 0.276),
23 (0.419, 0.407),
24 (0.559, 0.530),
25 (0.698, 0.643),
26 (0.838, 0.743),
27 (0.977, 0.829),
28 (1.117, 0.899),
29 (1.257, 0.951),
30 (1.396, 0.985),
31 (1.536, 0.999),
32 (1.676, 0.995),
33 (1.815, 0.970),
34 (1.955, 0.927),
35 (2.094, 0.866),
36 (2.234, 0.788),
37 (2.374, 0.695),
38 (2.513, 0.588),
39 (2.653, 0.469),
40 (2.793, 0.342),
41 (2.932, 0.208),
42 (3.072, 0.070),
43 (3.211, -0.070),
44 (3.351, -0.208),
45 (3.491, -0.342),
46 (3.630, -0.469),
47 (3.770, -0.588),
48 (3.910, -0.695),
49 (4.049, -0.788),
50 (4.189, -0.866),
51 (4.328, -0.927),
52 (4.468, -0.970),
53 (4.608, -0.995),
54 (4.747, -0.999),
55 (4.887, -0.985),
56 (5.027, -0.951),
57 (5.166, -0.899),
58 (5.306, -0.829),
59 (5.445, -0.743),
60 (5.585, -0.643),
61 (5.725, -0.530),
62 (5.864, -0.407),
63 (6.004, -0.276),
64 (6.144, -0.139),
65 (6.283, 0.000),
66 ];
67
68 #[test]
69 fn sanity_check() {
70 for &(x, expected) in TEST_VECTORS {
71 let sin_x = F32(x).sin();
72 let delta = (sin_x - expected).abs();
73
74 assert!(
75 delta <= MAX_ERROR,
76 "delta {} too large: {} vs {}",
77 delta,
78 sin_x,
79 expected
80 );
81 }
82 }
83}
84