1#[inline]
3fn acos_approx_f32(v: f32) -> f32 {
4 let nonnegative = v >= 0.0;
7 let x = abs(v);
8 let mut omx = 1.0 - x;
9 if omx < 0.0 {
10 omx = 0.0;
11 }
12 let root = sqrt(omx);
13
14 #[allow(clippy::approx_constant)]
16 let mut result =
17 ((((((-0.001_262_491_1 * x + 0.006_670_09) * x - 0.017_088_126) * x + 0.030_891_88) * x
18 - 0.050_174_303)
19 * x
20 + 0.088_978_99)
21 * x
22 - 0.214_598_8)
23 * x
24 + 1.570_796_3;
25 result *= root;
26
27 if nonnegative {
29 result
30 } else {
31 core::f32::consts::PI - result
32 }
33}
34
35#[cfg(feature = "libm")]
36mod libm_math {
37 #[inline(always)]
38 pub(crate) fn abs(f: f32) -> f32 {
39 libm::fabsf(f)
40 }
41
42 #[inline(always)]
43 pub(crate) fn acos_approx(f: f32) -> f32 {
44 super::acos_approx_f32(f)
45 }
46
47 #[inline(always)]
48 pub(crate) fn asin(f: f32) -> f32 {
49 libm::asinf(f)
50 }
51
52 #[inline(always)]
53 pub(crate) fn atan2(f: f32, other: f32) -> f32 {
54 libm::atan2f(f, other)
55 }
56
57 #[allow(unused)]
58 #[inline(always)]
59 pub(crate) fn sin(f: f32) -> f32 {
60 libm::sinf(f)
61 }
62
63 #[inline(always)]
64 pub(crate) fn sin_cos(f: f32) -> (f32, f32) {
65 libm::sincosf(f)
66 }
67
68 #[inline(always)]
69 pub(crate) fn tan(f: f32) -> f32 {
70 libm::tanf(f)
71 }
72
73 #[inline(always)]
74 pub(crate) fn sqrt(f: f32) -> f32 {
75 libm::sqrtf(f)
76 }
77
78 #[inline(always)]
79 pub(crate) fn copysign(f: f32, sign: f32) -> f32 {
80 libm::copysignf(f, sign)
81 }
82
83 #[inline(always)]
84 pub(crate) fn signum(f: f32) -> f32 {
85 if f.is_nan() {
86 f32::NAN
87 } else {
88 copysign(1.0, f)
89 }
90 }
91
92 #[inline(always)]
93 pub(crate) fn round(f: f32) -> f32 {
94 libm::roundf(f)
95 }
96
97 #[inline(always)]
98 pub(crate) fn trunc(f: f32) -> f32 {
99 libm::truncf(f)
100 }
101
102 #[inline(always)]
103 pub(crate) fn ceil(f: f32) -> f32 {
104 libm::ceilf(f)
105 }
106
107 #[inline(always)]
108 pub(crate) fn floor(f: f32) -> f32 {
109 libm::floorf(f)
110 }
111
112 #[inline(always)]
113 pub(crate) fn exp(f: f32) -> f32 {
114 libm::expf(f)
115 }
116
117 #[inline(always)]
118 pub(crate) fn powf(f: f32, n: f32) -> f32 {
119 libm::powf(f, n)
120 }
121
122 #[inline(always)]
123 pub(crate) fn mul_add(a: f32, b: f32, c: f32) -> f32 {
124 libm::fmaf(a, b, c)
125 }
126
127 #[inline]
128 pub fn div_euclid(a: f32, b: f32) -> f32 {
129 let q = libm::truncf(a / b);
131 if a % b < 0.0 {
132 return if b > 0.0 { q - 1.0 } else { q + 1.0 };
133 }
134 q
135 }
136
137 #[inline]
138 pub fn rem_euclid(a: f32, b: f32) -> f32 {
139 let r = a % b;
140 if r < 0.0 {
141 r + abs(b)
142 } else {
143 r
144 }
145 }
146}
147
148#[cfg(not(feature = "libm"))]
149mod std_math {
150 #[inline(always)]
151 pub(crate) fn abs(f: f32) -> f32 {
152 f32::abs(f)
153 }
154
155 #[inline(always)]
156 pub(crate) fn acos_approx(f: f32) -> f32 {
157 super::acos_approx_f32(f)
158 }
159
160 #[inline(always)]
161 pub(crate) fn asin(f: f32) -> f32 {
162 f32::asin(f)
163 }
164
165 #[inline(always)]
166 pub(crate) fn atan2(f: f32, other: f32) -> f32 {
167 f32::atan2(f, other)
168 }
169
170 #[allow(unused)]
171 #[inline(always)]
172 pub(crate) fn sin(f: f32) -> f32 {
173 f32::sin(f)
174 }
175
176 #[inline(always)]
177 pub(crate) fn sin_cos(f: f32) -> (f32, f32) {
178 f32::sin_cos(f)
179 }
180
181 #[inline(always)]
182 pub(crate) fn tan(f: f32) -> f32 {
183 f32::tan(f)
184 }
185
186 #[inline(always)]
187 pub(crate) fn sqrt(f: f32) -> f32 {
188 f32::sqrt(f)
189 }
190
191 #[inline(always)]
192 pub(crate) fn copysign(f: f32, sign: f32) -> f32 {
193 f32::copysign(f, sign)
194 }
195
196 #[inline(always)]
197 pub(crate) fn signum(f: f32) -> f32 {
198 f32::signum(f)
199 }
200
201 #[inline(always)]
202 pub(crate) fn round(f: f32) -> f32 {
203 f32::round(f)
204 }
205
206 #[inline(always)]
207 pub(crate) fn trunc(f: f32) -> f32 {
208 f32::trunc(f)
209 }
210
211 #[inline(always)]
212 pub(crate) fn ceil(f: f32) -> f32 {
213 f32::ceil(f)
214 }
215
216 #[inline(always)]
217 pub(crate) fn floor(f: f32) -> f32 {
218 f32::floor(f)
219 }
220
221 #[inline(always)]
222 pub(crate) fn exp(f: f32) -> f32 {
223 f32::exp(f)
224 }
225
226 #[inline(always)]
227 pub(crate) fn powf(f: f32, n: f32) -> f32 {
228 f32::powf(f, n)
229 }
230
231 #[inline(always)]
232 pub(crate) fn mul_add(a: f32, b: f32, c: f32) -> f32 {
233 f32::mul_add(a, b, c)
234 }
235
236 #[inline]
237 pub fn div_euclid(a: f32, b: f32) -> f32 {
238 f32::div_euclid(a, b)
239 }
240
241 #[inline]
242 pub fn rem_euclid(a: f32, b: f32) -> f32 {
243 f32::rem_euclid(a, b)
244 }
245}
246
247#[cfg(feature = "libm")]
248pub(crate) use libm_math::*;
249
250#[cfg(not(feature = "libm"))]
251pub(crate) use std_math::*;