1pub trait FloatMath: Sized {
5 fn abs(self) -> Self;
6 fn sin(self) -> Self;
7 fn cos(self) -> Self;
8 fn sqrt(self) -> Self;
9 fn ln(self) -> Self;
10 fn exp(self) -> Self;
11 fn atan2(self, x: Self) -> Self;
12 fn powf(self, n: Self) -> Self;
13 fn tanh(self) -> Self;
14}
15
16impl FloatMath for f32 {
17 #[inline(always)]
18 fn abs(self) -> f32 {
19 #[cfg(feature = "std")]
20 {
21 self.abs()
22 }
23 #[cfg(all(not(feature = "std"), feature = "libm"))]
24 {
25 libm::fabsf(self)
26 }
27 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
28 {
29 f32::from_bits(self.to_bits() & 0x7FFF_FFFF)
30 }
31 }
32
33 #[inline(always)]
34 fn sin(self) -> f32 {
35 #[cfg(feature = "std")]
36 {
37 self.sin()
38 }
39 #[cfg(all(not(feature = "std"), feature = "libm"))]
40 {
41 libm::sinf(self)
42 }
43 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
44 {
45 core::compile_error!("Either feature 'std' or feature 'libm' must be enabled for floating-point trig functions.");
46 }
47 }
48
49 #[inline(always)]
50 fn cos(self) -> f32 {
51 #[cfg(feature = "std")]
52 {
53 self.cos()
54 }
55 #[cfg(all(not(feature = "std"), feature = "libm"))]
56 {
57 libm::cosf(self)
58 }
59 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
60 {
61 core::compile_error!("Either feature 'std' or feature 'libm' must be enabled for floating-point trig functions.");
62 }
63 }
64
65 #[inline(always)]
66 fn sqrt(self) -> f32 {
67 #[cfg(feature = "std")]
68 {
69 self.sqrt()
70 }
71 #[cfg(all(not(feature = "std"), feature = "libm"))]
72 {
73 libm::sqrtf(self)
74 }
75 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
76 {
77 core::compile_error!(
78 "Either feature 'std' or feature 'libm' must be enabled for floating-point sqrt."
79 );
80 }
81 }
82
83 #[inline(always)]
84 fn ln(self) -> f32 {
85 #[cfg(feature = "std")]
86 {
87 self.ln()
88 }
89 #[cfg(all(not(feature = "std"), feature = "libm"))]
90 {
91 libm::logf(self)
92 }
93 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
94 {
95 core::compile_error!(
96 "Either feature 'std' or feature 'libm' must be enabled for floating-point log."
97 );
98 }
99 }
100
101 #[inline(always)]
102 fn exp(self) -> f32 {
103 #[cfg(feature = "std")]
104 {
105 self.exp()
106 }
107 #[cfg(all(not(feature = "std"), feature = "libm"))]
108 {
109 libm::expf(self)
110 }
111 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
112 {
113 core::compile_error!(
114 "Either feature 'std' or feature 'libm' must be enabled for floating-point exp."
115 );
116 }
117 }
118
119 #[inline(always)]
120 fn atan2(self, x: f32) -> f32 {
121 #[cfg(feature = "std")]
122 {
123 self.atan2(x)
124 }
125 #[cfg(all(not(feature = "std"), feature = "libm"))]
126 {
127 libm::atan2f(self, x)
128 }
129 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
130 {
131 core::compile_error!(
132 "Either feature 'std' or feature 'libm' must be enabled for floating-point atan2."
133 );
134 }
135 }
136
137 #[inline(always)]
138 fn powf(self, n: f32) -> f32 {
139 #[cfg(feature = "std")]
140 {
141 self.powf(n)
142 }
143 #[cfg(all(not(feature = "std"), feature = "libm"))]
144 {
145 libm::powf(self, n)
146 }
147 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
148 {
149 core::compile_error!(
150 "Either feature 'std' or feature 'libm' must be enabled for floating-point powf."
151 );
152 }
153 }
154
155 #[inline(always)]
156 fn tanh(self) -> f32 {
157 #[cfg(feature = "std")]
158 {
159 self.tanh()
160 }
161 #[cfg(all(not(feature = "std"), feature = "libm"))]
162 {
163 libm::tanhf(self)
164 }
165 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
166 {
167 core::compile_error!(
168 "Either feature 'std' or feature 'libm' must be enabled for floating-point tanh."
169 );
170 }
171 }
172}
173
174impl FloatMath for f64 {
175 #[inline(always)]
176 fn abs(self) -> f64 {
177 #[cfg(feature = "std")]
178 {
179 self.abs()
180 }
181 #[cfg(all(not(feature = "std"), feature = "libm"))]
182 {
183 libm::fabs(self)
184 }
185 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
186 {
187 f64::from_bits(self.to_bits() & 0x7FFF_FFFF_FFFF_FFFF)
188 }
189 }
190
191 #[inline(always)]
192 fn sin(self) -> f64 {
193 #[cfg(feature = "std")]
194 {
195 self.sin()
196 }
197 #[cfg(all(not(feature = "std"), feature = "libm"))]
198 {
199 libm::sin(self)
200 }
201 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
202 {
203 core::compile_error!("Either feature 'std' or feature 'libm' must be enabled for floating-point trig functions.");
204 }
205 }
206
207 #[inline(always)]
208 fn cos(self) -> f64 {
209 #[cfg(feature = "std")]
210 {
211 self.cos()
212 }
213 #[cfg(all(not(feature = "std"), feature = "libm"))]
214 {
215 libm::cos(self)
216 }
217 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
218 {
219 core::compile_error!("Either feature 'std' or feature 'libm' must be enabled for floating-point trig functions.");
220 }
221 }
222
223 #[inline(always)]
224 fn sqrt(self) -> f64 {
225 #[cfg(feature = "std")]
226 {
227 self.sqrt()
228 }
229 #[cfg(all(not(feature = "std"), feature = "libm"))]
230 {
231 libm::sqrt(self)
232 }
233 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
234 {
235 core::compile_error!(
236 "Either feature 'std' or feature 'libm' must be enabled for floating-point sqrt."
237 );
238 }
239 }
240
241 #[inline(always)]
242 fn ln(self) -> f64 {
243 #[cfg(feature = "std")]
244 {
245 self.ln()
246 }
247 #[cfg(all(not(feature = "std"), feature = "libm"))]
248 {
249 libm::log(self)
250 }
251 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
252 {
253 core::compile_error!(
254 "Either feature 'std' or feature 'libm' must be enabled for floating-point log."
255 );
256 }
257 }
258
259 #[inline(always)]
260 fn exp(self) -> f64 {
261 #[cfg(feature = "std")]
262 {
263 self.exp()
264 }
265 #[cfg(all(not(feature = "std"), feature = "libm"))]
266 {
267 libm::exp(self)
268 }
269 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
270 {
271 core::compile_error!(
272 "Either feature 'std' or feature 'libm' must be enabled for floating-point exp."
273 );
274 }
275 }
276
277 #[inline(always)]
278 fn atan2(self, x: f64) -> f64 {
279 #[cfg(feature = "std")]
280 {
281 self.atan2(x)
282 }
283 #[cfg(all(not(feature = "std"), feature = "libm"))]
284 {
285 libm::atan2(self, x)
286 }
287 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
288 {
289 core::compile_error!(
290 "Either feature 'std' or feature 'libm' must be enabled for floating-point atan2."
291 );
292 }
293 }
294
295 #[inline(always)]
296 fn powf(self, n: f64) -> f64 {
297 #[cfg(feature = "std")]
298 {
299 self.powf(n)
300 }
301 #[cfg(all(not(feature = "std"), feature = "libm"))]
302 {
303 libm::pow(self, n)
304 }
305 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
306 {
307 core::compile_error!(
308 "Either feature 'std' or feature 'libm' must be enabled for floating-point powf."
309 );
310 }
311 }
312
313 #[inline(always)]
314 fn tanh(self) -> f64 {
315 #[cfg(feature = "std")]
316 {
317 self.tanh()
318 }
319 #[cfg(all(not(feature = "std"), feature = "libm"))]
320 {
321 libm::tanh(self)
322 }
323 #[cfg(all(not(feature = "std"), not(feature = "libm")))]
324 {
325 core::compile_error!(
326 "Either feature 'std' or feature 'libm' must be enabled for floating-point tanh."
327 );
328 }
329 }
330}