/rust/registry/src/index.crates.io-1949cf8c6b5b557f/wide-1.7.1/src/simd_float.rs
Line | Count | Source |
1 | | /// Emits functionality shared by all SIMD float types. |
2 | | /// |
3 | | /// Functions that need a separate implementation for each type (for |
4 | | /// performance) use `$fn_{name}:item` syntax, and functions that have one |
5 | | /// shared implementation for all floats are written out normally inside this |
6 | | /// macro. |
7 | | /// |
8 | | /// This macro also invokes `impl_simd`. |
9 | | macro_rules! impl_simd_float { |
10 | | ( |
11 | | // SAFETY: The contents of this macro assume that: |
12 | | // |
13 | | // - `T` implements `Pod` |
14 | | // - `Pod` can be implemented for `Simd` |
15 | | // - `size_of::<Simd>()` is `size_of::<T>() * N` |
16 | | // - `align_of::<Simd>()` is `size_of::<Simd>()` |
17 | | // - `Pod` can be implemented for the optional native SIMD types |
18 | | unsafe { |
19 | | T = $T:ident, |
20 | | N = $N:literal, |
21 | | Simd = $Simd:ident, |
22 | | IntSimd = $IntSimd:ident, |
23 | | UintT = $UintT:ident, |
24 | | UintSimd = $UintSimd:ident, |
25 | | optional_type_x86_inner { $(X86Inner = $X86Inner:ident)? }, |
26 | | optional_type_arm_inner { $(ArmInner = $ArmInner:ident)? }, |
27 | | optional_type_wasm_inner { $(WasmInner = $WasmInner:ident)? }, |
28 | | } |
29 | | old_powf_simd_fn_name = $old_powf_simd_fn_name:ident, |
30 | | |
31 | | // General SIMD functions |
32 | | $fn_neg:item |
33 | | $fn_not:item |
34 | | $fn_add:item |
35 | | $fn_sub:item |
36 | | $fn_mul:item |
37 | | $fn_div:item |
38 | | $fn_rem:item |
39 | | $fn_bitand:item |
40 | | $fn_bitor:item |
41 | | $fn_bitxor:item |
42 | | $fn_simd_eq:item |
43 | | $fn_simd_ne:item |
44 | | $fn_simd_lt:item |
45 | | $fn_simd_gt:item |
46 | | $fn_simd_le:item |
47 | | $fn_simd_ge:item |
48 | | $fn_reduce_add:item |
49 | | $fn_reduce_mul:item |
50 | | $fn_bitselect:item |
51 | | $fn_select:item |
52 | | $fn_to_bitmask:item |
53 | | $fn_any:item |
54 | | $fn_all:item |
55 | | $fn_transpose:item |
56 | | |
57 | | // Float-specific functions |
58 | | $fn_is_nan:item |
59 | | $fn_is_inf:item |
60 | | $fn_is_finite:item |
61 | | $fn_is_sign_positive:item |
62 | | $fn_is_sign_negative:item |
63 | | $fn_recip:item |
64 | | $fn_recip_sqrt:item |
65 | | $fn_max:item |
66 | | $fn_fast_max:item |
67 | | $fn_min:item |
68 | | $fn_fast_min:item |
69 | | $fn_clamp:item |
70 | | $fn_fast_clamp:item |
71 | | $fn_abs:item |
72 | | $fn_floor:item |
73 | | $fn_ceil:item |
74 | | $fn_round:item |
75 | | $fn_round_int:item |
76 | | $fn_fast_round_int:item |
77 | | $fn_round_ties_even:item |
78 | | $fn_trunc:item |
79 | | $fn_trunc_int:item |
80 | | $fn_fast_trunc_int:item |
81 | | $fn_mul_add:item |
82 | | $fn_mul_sub:item |
83 | | $fn_mul_neg_add:item |
84 | | $fn_mul_neg_sub:item |
85 | | $fn_powf_simd:item |
86 | | $fn_sqrt:item |
87 | | $fn_exp:item |
88 | | $fn_exp2:item |
89 | | $fn_ln:item |
90 | | $fn_cbrt:item |
91 | | $fn_asin:item |
92 | | $fn_acos:item |
93 | | $fn_atan:item |
94 | | $fn_atan2:item |
95 | | $fn_sin_cos:item |
96 | | $fn_asin_acos:item |
97 | | $fn_exp_m1:item |
98 | | $fn_ln_1p:item |
99 | | $fn_sinh:item |
100 | | $fn_cosh:item |
101 | | $fn_tanh:item |
102 | | ) => { |
103 | | impl_simd!( |
104 | | unsafe { |
105 | | T = $T, |
106 | | N = $N, |
107 | | Simd = $Simd, |
108 | | UintSimd = $UintSimd, |
109 | | optional_type_x86_inner { $(X86Inner = $X86Inner)? }, |
110 | | optional_type_arm_inner { $(ArmInner = $ArmInner)? }, |
111 | | optional_type_wasm_inner { $(WasmInner = $WasmInner)? }, |
112 | | } |
113 | | |
114 | | $fn_simd_eq |
115 | | |
116 | | $fn_simd_ne |
117 | | |
118 | | $fn_simd_lt |
119 | | |
120 | | $fn_simd_gt |
121 | | |
122 | | $fn_simd_le |
123 | | |
124 | | $fn_simd_ge |
125 | | |
126 | | /// |
127 | | /// # Unspecified precision |
128 | | /// |
129 | | /// The order of addition is non-deterministic. This means it varies by |
130 | | /// platform, version, and can even differ within the same execution from |
131 | | /// one invocation to the next. |
132 | | $fn_reduce_add |
133 | | |
134 | | /// |
135 | | /// # Unspecified precision |
136 | | /// |
137 | | /// The order of multiplication is non-deterministic. This means it varies |
138 | | /// by platform, version, and can even differ within the same execution |
139 | | /// from one invocation to the next. |
140 | | $fn_reduce_mul |
141 | | |
142 | | $fn_bitselect |
143 | | |
144 | | $fn_select |
145 | | |
146 | | $fn_to_bitmask |
147 | | |
148 | | $fn_any |
149 | | |
150 | | $fn_all |
151 | | |
152 | | #[inline] |
153 | | pub fn shuffle(self, indices: $UintSimd) -> Self { |
154 | | Self::from_bits(self.to_bits().shuffle(indices)) |
155 | | } |
156 | | |
157 | | #[inline] |
158 | | pub fn shuffle_zeroing(self, indices: $UintSimd) -> Self { |
159 | | Self::from_bits(self.to_bits().shuffle_zeroing(indices)) |
160 | | } |
161 | | |
162 | | #[inline] |
163 | | pub fn shuffle_wrapping(self, indices: $UintSimd) -> Self { |
164 | | Self::from_bits(self.to_bits().shuffle_wrapping(indices)) |
165 | | } |
166 | | |
167 | | #[inline] |
168 | | fn shuffle(self: [$Simd; 2], indices: $UintSimd) -> $Simd { |
169 | | cast(cast::<[$Simd; 2], [$UintSimd; 2]>(self).shuffle(indices)) |
170 | | } |
171 | | |
172 | | #[inline] |
173 | | fn shuffle_zeroing(self: [$Simd; 2], indices: $UintSimd) -> $Simd { |
174 | | cast(cast::<[$Simd; 2], [$UintSimd; 2]>(self).shuffle_zeroing(indices)) |
175 | | } |
176 | | |
177 | | #[inline] |
178 | | fn shuffle_wrapping(self: [$Simd; 2], indices: $UintSimd) -> $Simd { |
179 | | cast(cast::<[$Simd; 2], [$UintSimd; 2]>(self).shuffle_wrapping(indices)) |
180 | | } |
181 | | |
182 | | #[inline] |
183 | | fn shuffle(self: [$Simd; 3], indices: $UintSimd) -> $Simd { |
184 | | cast(cast::<[$Simd; 3], [$UintSimd; 3]>(self).shuffle(indices)) |
185 | | } |
186 | | |
187 | | #[inline] |
188 | | fn shuffle_zeroing(self: [$Simd; 3], indices: $UintSimd) -> $Simd { |
189 | | cast(cast::<[$Simd; 3], [$UintSimd; 3]>(self).shuffle_zeroing(indices)) |
190 | | } |
191 | | |
192 | | #[inline] |
193 | | fn shuffle_wrapping(self: [$Simd; 3], indices: $UintSimd) -> $Simd { |
194 | | cast(cast::<[$Simd; 3], [$UintSimd; 3]>(self).shuffle_wrapping(indices)) |
195 | | } |
196 | | |
197 | | #[inline] |
198 | | fn shuffle(self: [$Simd; 4], indices: $UintSimd) -> $Simd { |
199 | | cast(cast::<[$Simd; 4], [$UintSimd; 4]>(self).shuffle(indices)) |
200 | | } |
201 | | |
202 | | #[inline] |
203 | | fn shuffle_zeroing(self: [$Simd; 4], indices: $UintSimd) -> $Simd { |
204 | | cast(cast::<[$Simd; 4], [$UintSimd; 4]>(self).shuffle_zeroing(indices)) |
205 | | } |
206 | | |
207 | | #[inline] |
208 | | fn shuffle_wrapping(self: [$Simd; 4], indices: $UintSimd) -> $Simd { |
209 | | cast(cast::<[$Simd; 4], [$UintSimd; 4]>(self).shuffle_wrapping(indices)) |
210 | | } |
211 | | |
212 | | $fn_transpose |
213 | | |
214 | | optional_fn_deserialize {} |
215 | | ); |
216 | | |
217 | | impl_unary_operator!( |
218 | | $Simd, |
219 | | Neg, |
220 | | neg, |
221 | | $fn_neg, |
222 | | /// Returns the negative of each element of `self`. |
223 | | /// |
224 | | /// This always returns the precise result, simply flipping the sign-bit. |
225 | | ); |
226 | | impl_unary_operator!( |
227 | | $Simd, |
228 | | Not, |
229 | | not, |
230 | | $fn_not, |
231 | | /// Computes bitwise NOT for each element of `self`. |
232 | | /// |
233 | | /// This operator is not implemented for primitive scalar floats, but its |
234 | | /// behavior here is the same as for integers. |
235 | | ); |
236 | | |
237 | | impl_binary_operator!( |
238 | | $T, |
239 | | $Simd, |
240 | | Add, |
241 | | add, |
242 | | AddAssign, |
243 | | add_assign, |
244 | | $fn_add, |
245 | | /// Computes addition for each element of `self` and the corresponding |
246 | | /// element of `rhs`. |
247 | | /// |
248 | | /// This always returns the precise result. |
249 | | , |
250 | | /// Computes addition for each element of `self` and the uniform scalar |
251 | | /// `rhs`. |
252 | | /// |
253 | | /// This always returns the precise result. |
254 | | , |
255 | | /// Computes addition for the uniform scalar `self` and each element of |
256 | | /// `rhs`, returning a SIMD vector. |
257 | | /// |
258 | | /// This always returns the precise result. |
259 | | ); |
260 | | impl_binary_operator!( |
261 | | $T, |
262 | | $Simd, |
263 | | Sub, |
264 | | sub, |
265 | | SubAssign, |
266 | | sub_assign, |
267 | | $fn_sub, |
268 | | /// Computes subtraction for each element of `self` and the corresponding |
269 | | /// element of `rhs`. |
270 | | /// |
271 | | /// This always returns the precise result. |
272 | | , |
273 | | /// Computes subtraction for each element of `self` and the uniform scalar |
274 | | /// `rhs`. |
275 | | /// |
276 | | /// This always returns the precise result. |
277 | | , |
278 | | /// Computes subtraction for the uniform scalar `self` and each element of |
279 | | /// `rhs`, returning a SIMD vector. |
280 | | /// |
281 | | /// This always returns the precise result. |
282 | | ); |
283 | | impl_binary_operator!( |
284 | | $T, |
285 | | $Simd, |
286 | | Mul, |
287 | | mul, |
288 | | MulAssign, |
289 | | mul_assign, |
290 | | $fn_mul, |
291 | | /// Computes multiplication for each element of `self` and the |
292 | | /// corresponding element of `rhs`. |
293 | | /// |
294 | | /// This always returns the precise result. |
295 | | , |
296 | | /// Computes multiplication for each element of `self` and the uniform |
297 | | /// scalar `rhs`. |
298 | | /// |
299 | | /// This always returns the precise result. |
300 | | , |
301 | | /// Computes multiplication for the uniform scalar `self` and each element |
302 | | /// of `rhs`, returning a SIMD vector. |
303 | | /// |
304 | | /// This always returns the precise result. |
305 | | ); |
306 | | impl_binary_operator!( |
307 | | $T, |
308 | | $Simd, |
309 | | Div, |
310 | | div, |
311 | | DivAssign, |
312 | | div_assign, |
313 | | $fn_div, |
314 | | /// Computes division for each element of `self` and the corresponding |
315 | | /// element of `rhs`. |
316 | | /// |
317 | | /// This always returns the precise result. |
318 | | , |
319 | | /// Computes division for each element of `self` and the uniform scalar |
320 | | /// `rhs`. |
321 | | /// |
322 | | /// This always returns the precise result. |
323 | | , |
324 | | /// Computes division for the uniform scalar `self` and each element of |
325 | | /// `rhs`, returning a SIMD vector. |
326 | | /// |
327 | | /// This always returns the precise result. |
328 | | ); |
329 | | impl_binary_operator!( |
330 | | $T, |
331 | | $Simd, |
332 | | Rem, |
333 | | rem, |
334 | | RemAssign, |
335 | | rem_assign, |
336 | | $fn_rem, |
337 | | /// Computes the remainder for each element of `self` and the |
338 | | /// corresponding element of `rhs`. |
339 | | /// |
340 | | /// This always returns the precise result. |
341 | | , |
342 | | /// Computes the remainder for each element of `self` and the uniform |
343 | | /// scalar `rhs`. |
344 | | /// |
345 | | /// This always returns the precise result. |
346 | | , |
347 | | /// Computes the remainder for the uniform scalar `self` and each element |
348 | | /// of `rhs`, returning a SIMD vector. |
349 | | /// |
350 | | /// This always returns the precise result. |
351 | | ); |
352 | | impl_binary_operator!( |
353 | | $T, |
354 | | $Simd, |
355 | | BitAnd, |
356 | | bitand, |
357 | | BitAndAssign, |
358 | | bitand_assign, |
359 | | $fn_bitand, |
360 | | /// Computes bitwise AND for each element of `self` and the corresponding |
361 | | /// element of `rhs`. |
362 | | /// |
363 | | /// This operator is not implemented for primitive scalar floats, but its |
364 | | /// behavior here is the same as for integers. |
365 | | , |
366 | | /// Computes bitwise AND for each element of `self` and the uniform scalar |
367 | | /// `rhs`. |
368 | | /// |
369 | | /// This operator is not implemented for primitive scalar floats, but its |
370 | | /// behavior here is the same as for integers. |
371 | | , |
372 | | /// Computes bitwise AND for the uniform scalar `self` and each element of |
373 | | /// `rhs`, returning a SIMD vector. |
374 | | /// |
375 | | /// This operator is not implemented for primitive scalar floats, but its |
376 | | /// behavior here is the same as for integers. |
377 | | ); |
378 | | impl_binary_operator!( |
379 | | $T, |
380 | | $Simd, |
381 | | BitOr, |
382 | | bitor, |
383 | | BitOrAssign, |
384 | | bitor_assign, |
385 | | $fn_bitor, |
386 | | /// Computes bitwise OR for each element of `self` and the corresponding |
387 | | /// element of `rhs`. |
388 | | /// |
389 | | /// This operator is not implemented for primitive scalar floats, but its |
390 | | /// behavior here is the same as for integers. |
391 | | , |
392 | | /// Computes bitwise OR for each element of `self` and the uniform scalar |
393 | | /// `rhs`. |
394 | | /// |
395 | | /// This operator is not implemented for primitive scalar floats, but its |
396 | | /// behavior here is the same as for integers. |
397 | | , |
398 | | /// Computes bitwise OR for the uniform scalar `self` and each element of |
399 | | /// `rhs`, returning a SIMD vector. |
400 | | /// |
401 | | /// This operator is not implemented for primitive scalar floats, but its |
402 | | /// behavior here is the same as for integers. |
403 | | ); |
404 | | impl_binary_operator!( |
405 | | $T, |
406 | | $Simd, |
407 | | BitXor, |
408 | | bitxor, |
409 | | BitXorAssign, |
410 | | bitxor_assign, |
411 | | $fn_bitxor, |
412 | | /// Computes bitwise XOR for each element of `self` and the corresponding |
413 | | /// element of `rhs`. |
414 | | /// |
415 | | /// This operator is not implemented for primitive scalar floats, but its |
416 | | /// behavior here is the same as for integers. |
417 | | , |
418 | | /// Computes bitwise XOR for each element of `self` and the uniform scalar |
419 | | /// `rhs`. |
420 | | /// |
421 | | /// This operator is not implemented for primitive scalar floats, but its |
422 | | /// behavior here is the same as for integers. |
423 | | , |
424 | | /// Computes bitwise XOR for the uniform scalar `self` and each element of |
425 | | /// `rhs`, returning a SIMD vector. |
426 | | /// |
427 | | /// This operator is not implemented for primitive scalar floats, but its |
428 | | /// behavior here is the same as for integers. |
429 | | ); |
430 | | |
431 | | impl<Rhs> core::iter::Sum<Rhs> for $Simd |
432 | | where |
433 | | $Simd: AddAssign<Rhs>, |
434 | | { |
435 | | /// Computes the sum of multiple SIMD vectors for each lane. |
436 | | /// |
437 | | /// The order of addition is not specified. |
438 | | #[inline] |
439 | | fn sum<I: Iterator<Item = Rhs>>(iter: I) -> Self { |
440 | | let mut total = Self::zeroed(); |
441 | | for val in iter { |
442 | | total += val; |
443 | | } |
444 | | total |
445 | | } |
446 | | } |
447 | | |
448 | | impl<Rhs> core::iter::Product<Rhs> for $Simd |
449 | | where |
450 | | $Simd: MulAssign<Rhs>, |
451 | | { |
452 | | /// Computes the product of multiple SIMD vectors for each lane. |
453 | | /// |
454 | | /// The order of multiplication is not specified. |
455 | | #[inline] |
456 | | fn product<I: Iterator<Item = Rhs>>(iter: I) -> Self { |
457 | | let mut total = Self::from(1.0); |
458 | | for val in iter { |
459 | | total *= val; |
460 | | } |
461 | | total |
462 | | } |
463 | | } |
464 | | |
465 | | macro_rules! impl_formatting_trait { |
466 | | ($Trait:path) => { |
467 | | impl $Trait for $Simd { |
468 | | #[allow(clippy::missing_inline_in_public_items)] |
469 | 0 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { |
470 | 0 | write!(f, "(")?; |
471 | 0 | for (i, x) in self.to_array().iter().enumerate() { |
472 | 0 | if i > 0 { |
473 | 0 | write!(f, ", ")?; |
474 | 0 | } |
475 | 0 | <$UintT as $Trait>::fmt(&x.to_bits(), f)?; |
476 | | } |
477 | 0 | write!(f, ")") |
478 | 0 | } Unexecuted instantiation: <wide::f64x4_::f64x4 as core::fmt::Binary>::fmt Unexecuted instantiation: <wide::f64x4_::f64x4 as core::fmt::LowerHex>::fmt Unexecuted instantiation: <wide::f64x4_::f64x4 as core::fmt::Octal>::fmt Unexecuted instantiation: <wide::f64x4_::f64x4 as core::fmt::UpperHex>::fmt |
479 | | } |
480 | | } |
481 | | } |
482 | | impl_formatting_trait!(core::fmt::Binary); |
483 | | impl_formatting_trait!(core::fmt::LowerHex); |
484 | | impl_formatting_trait!(core::fmt::Octal); |
485 | | impl_formatting_trait!(core::fmt::UpperHex); |
486 | | |
487 | | impl Select<$Simd> for $UintSimd { |
488 | | #[inline] |
489 | | fn select(self, if_true: $Simd, if_false: $Simd) -> $Simd { |
490 | | $Simd::from_bits(self).select(if_true, if_false) |
491 | | } |
492 | | } |
493 | | |
494 | | impl Select<$UintSimd> for $Simd { |
495 | | #[inline] |
496 | | fn select(self, if_true: $UintSimd, if_false: $UintSimd) -> $UintSimd { |
497 | | self.to_bits().select(if_true, if_false) |
498 | | } |
499 | | } |
500 | | |
501 | | impl Select<$Simd> for $IntSimd { |
502 | | #[inline] |
503 | | fn select(self, if_true: $Simd, if_false: $Simd) -> $Simd { |
504 | | $Simd::from_bits(self.cast_unsigned()).select(if_true, if_false) |
505 | | } |
506 | | } |
507 | | |
508 | | impl Select<$IntSimd> for $Simd { |
509 | | #[inline] |
510 | | fn select(self, if_true: $IntSimd, if_false: $IntSimd) -> $IntSimd { |
511 | | self.to_bits().cast_signed().select(if_true, if_false) |
512 | | } |
513 | | } |
514 | | |
515 | | /// The following functionality exists for all SIMD vectors of floats. |
516 | | impl $Simd { |
517 | | /// A SIMD vector with all elements set to `1.0`. |
518 | | pub const ONE: Self = Self::splat(1.0); |
519 | | |
520 | | /// A SIMD vector with all elements set to `0.5`. |
521 | | pub const HALF: Self = Self::splat(0.5); |
522 | | |
523 | | /// A SIMD vector with all elements set to `0.0`. |
524 | | pub const ZERO: Self = Self::splat(0.0); |
525 | | |
526 | | #[doc = concat!("A SIMD vector with all elements set to [`", stringify!($T) ,"::EPSILON`].")] |
527 | | pub const EPSILON: Self = Self::splat($T::EPSILON); |
528 | | |
529 | | #[doc = concat!("A SIMD vector with all elements set to [`", stringify!($T) ,"::MIN`].")] |
530 | | pub const MIN: Self = Self::splat($T::MIN); |
531 | | |
532 | | #[doc = concat!("A SIMD vector with all elements set to [`", stringify!($T) ,"::MIN_POSITIVE`].")] |
533 | | pub const MIN_POSITIVE: Self = Self::splat($T::MIN_POSITIVE); |
534 | | |
535 | | #[doc = concat!("A SIMD vector with all elements set to [`", stringify!($T) ,"::MAX`].")] |
536 | | pub const MAX: Self = Self::splat($T::MAX); |
537 | | |
538 | | #[doc = concat!("A SIMD vector with all elements set to [`", stringify!($T) ,"::NAN`].")] |
539 | | pub const NAN: Self = Self::splat($T::NAN); |
540 | | |
541 | | #[doc = concat!("A SIMD vector with all elements set to [`", stringify!($T) ,"::INFINITY`].")] |
542 | | pub const INFINITY: Self = Self::splat($T::INFINITY); |
543 | | |
544 | | #[doc = concat!("A SIMD vector with all elements set to [`", stringify!($T) ,"::NEG_INFINITY`].")] |
545 | | pub const NEG_INFINITY: Self = Self::splat($T::NEG_INFINITY); |
546 | | |
547 | | /// A SIMD vector with all elements set to [Euler's number (e)]. |
548 | | /// |
549 | | #[doc = concat!("[Euler's number (e)]: core::", stringify!($T), "::consts::E")] |
550 | | pub const E: Self = Self::splat(core::$T::consts::E); |
551 | | |
552 | | /// A SIMD vector with all elements set to [1/Ï€]. |
553 | | /// |
554 | | #[doc = concat!("[1/Ï€]: core::", stringify!($T), "::consts::FRAC_1_PI")] |
555 | | pub const FRAC_1_PI: Self = Self::splat(core::$T::consts::FRAC_1_PI); |
556 | | |
557 | | /// A SIMD vector with all elements set to [2/Ï€]. |
558 | | /// |
559 | | #[doc = concat!("[2/Ï€]: core::", stringify!($T), "::consts::FRAC_2_PI")] |
560 | | pub const FRAC_2_PI: Self = Self::splat(core::$T::consts::FRAC_2_PI); |
561 | | |
562 | | /// A SIMD vector with all elements set to [2/sqrt(Ï€)]. |
563 | | /// |
564 | | #[doc = concat!("[2/sqrt(Ï€)]: core::", stringify!($T), "::consts::FRAC_2_SQRT_PI")] |
565 | | pub const FRAC_2_SQRT_PI: Self = |
566 | | Self::splat(core::$T::consts::FRAC_2_SQRT_PI); |
567 | | |
568 | | /// A SIMD vector with all elements set to [1/sqrt(2)]. |
569 | | /// |
570 | | #[doc = concat!("[1/sqrt(2)]: core::", stringify!($T), "::consts::FRAC_1_SQRT_2")] |
571 | | pub const FRAC_1_SQRT_2: Self = |
572 | | Self::splat(core::$T::consts::FRAC_1_SQRT_2); |
573 | | |
574 | | /// A SIMD vector with all elements set to [Ï€/2]. |
575 | | /// |
576 | | #[doc = concat!("[Ï€/2]: core::", stringify!($T), "::consts::FRAC_PI_2")] |
577 | | pub const FRAC_PI_2: Self = Self::splat(core::$T::consts::FRAC_PI_2); |
578 | | |
579 | | /// A SIMD vector with all elements set to [Ï€/3]. |
580 | | /// |
581 | | #[doc = concat!("[Ï€/3]: core::", stringify!($T), "::consts::FRAC_PI_3")] |
582 | | pub const FRAC_PI_3: Self = Self::splat(core::$T::consts::FRAC_PI_3); |
583 | | |
584 | | /// A SIMD vector with all elements set to [Ï€/4]. |
585 | | /// |
586 | | #[doc = concat!("[Ï€/4]: core::", stringify!($T), "::consts::FRAC_PI_4")] |
587 | | pub const FRAC_PI_4: Self = Self::splat(core::$T::consts::FRAC_PI_4); |
588 | | |
589 | | /// A SIMD vector with all elements set to [Ï€/6]. |
590 | | /// |
591 | | #[doc = concat!("[Ï€/6]: core::", stringify!($T), "::consts::FRAC_PI_6")] |
592 | | pub const FRAC_PI_6: Self = Self::splat(core::$T::consts::FRAC_PI_6); |
593 | | |
594 | | /// A SIMD vector with all elements set to [Ï€/8]. |
595 | | /// |
596 | | #[doc = concat!("[Ï€/8]: core::", stringify!($T), "::consts::FRAC_PI_8")] |
597 | | pub const FRAC_PI_8: Self = Self::splat(core::$T::consts::FRAC_PI_8); |
598 | | |
599 | | /// A SIMD vector with all elements set to [ln(2)]. |
600 | | /// |
601 | | #[doc = concat!("[ln(2)]: core::", stringify!($T), "::consts::LN_2")] |
602 | | pub const LN_2: Self = Self::splat(core::$T::consts::LN_2); |
603 | | |
604 | | /// A SIMD vector with all elements set to [ln(10)]. |
605 | | /// |
606 | | #[doc = concat!("[ln(10)]: core::", stringify!($T), "::consts::LN_10")] |
607 | | pub const LN_10: Self = Self::splat(core::$T::consts::LN_10); |
608 | | |
609 | | /// A SIMD vector with all elements set to [log<sub>2</sub>(e)]. |
610 | | /// |
611 | | #[doc = concat!("[log<sub>2</sub>(e)]: core::", stringify!($T), "::consts::LOG2_E")] |
612 | | pub const LOG2_E: Self = Self::splat(core::$T::consts::LOG2_E); |
613 | | |
614 | | /// A SIMD vector with all elements set to [log<sub>10</sub>(e)]. |
615 | | /// |
616 | | #[doc = concat!("[log<sub>10</sub>(e)]: core::", stringify!($T), "::consts::LOG10_E")] |
617 | | pub const LOG10_E: Self = Self::splat(core::$T::consts::LOG10_E); |
618 | | |
619 | | /// A SIMD vector with all elements set to [log<sub>10</sub>(2)]. |
620 | | /// |
621 | | #[doc = concat!("[log<sub>10</sub>(2)]: core::", stringify!($T), "::consts::LOG10_2")] |
622 | | pub const LOG10_2: Self = Self::splat(core::$T::consts::LOG10_2); |
623 | | |
624 | | /// A SIMD vector with all elements set to [log<sub>2</sub>(10)]. |
625 | | /// |
626 | | #[doc = concat!("[log<sub>2</sub>(10)]: core::", stringify!($T), "::consts::LOG2_10")] |
627 | | pub const LOG2_10: Self = Self::splat(core::$T::consts::LOG2_10); |
628 | | |
629 | | /// A SIMD vector with all elements set to [Archimedes’ constant (π)]. |
630 | | /// |
631 | | #[doc = concat!("[Archimedes’ constant (π)]: core::", stringify!($T), "::consts::PI")] |
632 | | pub const PI: Self = Self::splat(core::$T::consts::PI); |
633 | | |
634 | | /// A SIMD vector with all elements set to [sqrt(2)]. |
635 | | /// |
636 | | #[doc = concat!("[sqrt(2)]: core::", stringify!($T), "::consts::SQRT_2")] |
637 | | pub const SQRT_2: Self = Self::splat(core::$T::consts::SQRT_2); |
638 | | |
639 | | /// A SIMD vector with all elements set to [the full circle constant (Ï„)]. |
640 | | /// |
641 | | /// Equal to 2Ï€. |
642 | | /// |
643 | | #[doc = concat!("[the full circle constant (Ï„)]: core::", stringify!($T), "::consts::TAU")] |
644 | | pub const TAU: Self = Self::splat(core::$T::consts::TAU); |
645 | | |
646 | | /// Returns a [mask] that checks if each element is NaN. |
647 | | /// |
648 | | /// [mask]: crate#masks |
649 | | #[must_use] |
650 | | $fn_is_nan |
651 | | |
652 | | /// Returns a [mask] that checks if each element is infinity (either |
653 | | /// positive or negative). |
654 | | /// |
655 | | /// [mask]: crate#masks |
656 | | #[must_use] |
657 | | $fn_is_inf |
658 | | |
659 | | /// Returns a [mask] that checks if each element is neither infinite nor |
660 | | /// NaN. |
661 | | /// |
662 | | /// [mask]: crate#masks |
663 | | #[must_use] |
664 | | $fn_is_finite |
665 | | |
666 | | /// Returns a [mask] that checks if each element has a positive sign, |
667 | | /// including `+0.0`, NaNs with positive sign bit and positive infinity. |
668 | | /// |
669 | | /// [mask]: crate#masks |
670 | | #[must_use] |
671 | | $fn_is_sign_positive |
672 | | |
673 | | /// Returns a [mask] that checks if each element has a negative sign, |
674 | | /// including `-0.0`, NaNs with negative sign bit and negative infinity. |
675 | | /// |
676 | | /// [mask]: crate#masks |
677 | | #[must_use] |
678 | | $fn_is_sign_negative |
679 | | |
680 | | /// Returns the reciprocal (inverse) of a number, `1/x`. |
681 | | /// |
682 | | /// # Unspecified precision |
683 | | /// |
684 | | /// The precision of this function is non-deterministic. This means it |
685 | | /// varies by platform, version, and can even differ within the same |
686 | | /// execution from one invocation to the next. |
687 | | /// |
688 | | #[doc = concat!( |
689 | | "To compute the reciprocal deterministically, use `", |
690 | | stringify!($Simd), |
691 | | "::ONE / x`." |
692 | | )] |
693 | | #[must_use] |
694 | | $fn_recip |
695 | | |
696 | | /// Returns the square root of the reciprocal (inverse) of a number, |
697 | | /// `sqrt(1/x)`. |
698 | | /// |
699 | | /// # Unspecified precision |
700 | | /// |
701 | | /// The precision of this function is non-deterministic. This means it |
702 | | /// varies by platform, version, and can even differ within the same |
703 | | /// execution from one invocation to the next. |
704 | | #[must_use] |
705 | | $fn_recip_sqrt |
706 | | |
707 | | /// Converts radians to degrees. |
708 | | /// |
709 | | /// # Unspecified precision |
710 | | /// |
711 | | /// The precision of this function is non-deterministic. This means it |
712 | | /// varies by platform, version, and can even differ within the same |
713 | | /// execution from one invocation to the next. |
714 | | #[inline] |
715 | | #[must_use] |
716 | | pub fn to_degrees(self) -> Self { |
717 | | const RAD_TO_DEG_RATIO: $Simd = $Simd::splat(180.0 / core::$T::consts::PI); |
718 | | self * RAD_TO_DEG_RATIO |
719 | | } |
720 | | |
721 | | /// Converts degrees to radians. |
722 | | /// |
723 | | /// # Unspecified precision |
724 | | /// |
725 | | /// The precision of this function is non-deterministic. This means it |
726 | | /// varies by platform, version, and can even differ within the same |
727 | | /// execution from one invocation to the next. |
728 | | #[inline] |
729 | | #[must_use] |
730 | | pub fn to_radians(self) -> Self { |
731 | | const DEG_TO_RAD_RATIO: $Simd = $Simd::splat(core::$T::consts::PI / 180.0); |
732 | | self * DEG_TO_RAD_RATIO |
733 | | } |
734 | | |
735 | | /// Returns the maximum between each element of `self` and the |
736 | | /// corresponding element of `other`, ignoring NaN. |
737 | | /// |
738 | | /// For each lane, if exactly one of the arguments is NaN, then the other |
739 | | /// argument is returned. If both arguments are NaN, the return value is |
740 | | /// NaN. If the inputs compare equal (such as for the case of `+0.0` and |
741 | | /// `-0.0`), either input may be returned non-deterministically. |
742 | | /// |
743 | | /// See [`fast_max`] for a faster variant that does not handle NaNs. |
744 | | /// |
745 | | /// [`fast_max`]: Self::fast_max |
746 | | #[must_use] |
747 | | $fn_max |
748 | | |
749 | | /// Returns the maximum between each element of `self` and the |
750 | | /// corresponding element of `other`, not specifying behavior for NaNs. |
751 | | /// |
752 | | /// For each lane, if both arguments are NaN, the return value is NaN. If |
753 | | /// the inputs compare equal (such as for the case of `+0.0` and `-0.0`), |
754 | | /// or if exactly one of the arguments is NaN, either input may be |
755 | | /// returned non-deterministically. |
756 | | /// |
757 | | /// See [`max`] for a slower variant that does handle NaNs. |
758 | | /// |
759 | | /// [`max`]: Self::max |
760 | | #[must_use] |
761 | | $fn_fast_max |
762 | | |
763 | | /// Returns the minimum between each element of `self` and the |
764 | | /// corresponding element of `other`, ignoring NaN. |
765 | | /// |
766 | | /// For each lane, if exactly one of the arguments is NaN, then the other |
767 | | /// argument is returned. If both arguments are NaN, the return value is |
768 | | /// NaN. If the inputs compare equal (such as for the case of `+0.0` and |
769 | | /// `-0.0`), either input may be returned non-deterministically. |
770 | | /// |
771 | | /// See [`fast_min`] for a faster variant that does not handle NaNs. |
772 | | /// |
773 | | /// [`fast_min`]: Self::fast_min |
774 | | #[must_use] |
775 | | $fn_min |
776 | | |
777 | | /// Returns the minimum between each element of `self` and the |
778 | | /// corresponding element of `other`, not specifying behavior for NaNs. |
779 | | /// |
780 | | /// For each lane, if both arguments are NaN, the return value is NaN. If |
781 | | /// the inputs compare equal (such as for the case of `+0.0` and `-0.0`), |
782 | | /// or if exactly one of the arguments is NaN, either input may be |
783 | | /// returned non-deterministically. |
784 | | /// |
785 | | /// See [`min`] for a slower variant that does handle NaNs. |
786 | | /// |
787 | | /// [`min`]: Self::min |
788 | | #[must_use] |
789 | | $fn_fast_min |
790 | | |
791 | | /// Calculates the midpoint (average) between `self` and `other`. |
792 | | /// |
793 | | /// This returns NaN when *either* argument is NaN or if a combination of |
794 | | /// +inf and -inf is provided as arguments. |
795 | | /// |
796 | | /// This function currently returns a less precise result than |
797 | | #[doc = concat!("[`", stringify!($T), "::midpoint`]")] |
798 | | /// in order to gain performance, but this may change in the future. |
799 | | /// |
800 | | /// # Unspecified precision |
801 | | /// |
802 | | /// The precision of this function is non-deterministic. This means it |
803 | | /// varies by platform, version, and can even differ within the same |
804 | | /// execution from one invocation to the next. |
805 | | #[inline] |
806 | | #[must_use] |
807 | | pub fn midpoint(self, other: Self) -> Self { |
808 | | (self + other) * 0.5 |
809 | | } |
810 | | |
811 | | /// Raw transmutation to unsigned integer vector. |
812 | | /// |
813 | | /// Note that this function preserves the *bitwise* value, and not the |
814 | | /// numeric value. |
815 | | #[inline] |
816 | | #[must_use] |
817 | | pub const fn to_bits(self) -> $UintSimd { |
818 | | // SAFETY: Both types accept all bit-patterns and only contain |
819 | | // initialized memory. |
820 | | unsafe { core::mem::transmute::<$Simd, $UintSimd>(self) } |
821 | | } |
822 | | |
823 | | /// Raw transmutation from unsigned integer vector. |
824 | | /// |
825 | | /// Note that this function preserves the *bitwise* value, and not the |
826 | | /// numeric value. |
827 | | #[inline] |
828 | | #[must_use] |
829 | | pub const fn from_bits(bits: $UintSimd) -> Self { |
830 | | // SAFETY: Both types accept all bit-patterns and only contain |
831 | | // initialized memory. |
832 | | unsafe { core::mem::transmute::<$UintSimd, $Simd>(bits) } |
833 | | } |
834 | | |
835 | | /// Restrict a value to a certain interval unless it is NaN. |
836 | | /// |
837 | | /// If `self`, `min` or `max` are NaN, the result is NaN. If `min > max`, |
838 | | /// the result is `min`. If inputs compare equal (such as for the case of |
839 | | /// `+0.0` and `-0.0`), either input may be returned |
840 | | /// non-deterministically. |
841 | | /// |
842 | | /// See [`fast_clamp`] for a faster variant that does not handle `min` or |
843 | | /// `max` being NaN. |
844 | | /// |
845 | | /// [`fast_clamp`]: Self::fast_clamp |
846 | | #[must_use] |
847 | | $fn_clamp |
848 | | |
849 | | /// Restrict a value to a certain interval unless it is NaN. |
850 | | /// |
851 | | /// If `self` is NaN, the result is NaN. If `min > max`, the result is |
852 | | /// `min`. If inputs compare equal (such as for the case of |
853 | | /// `+0.0` and `-0.0`), or if `min` or `max` are NaN, any input may be |
854 | | /// returned non-deterministically. |
855 | | /// |
856 | | /// See [`clamp`] for a slower variant that also handles `min` or `max` |
857 | | /// being NaN. |
858 | | /// |
859 | | /// [`clamp`]: Self::clamp |
860 | | #[must_use] |
861 | | $fn_fast_clamp |
862 | | |
863 | | /// Computes the absolute value of `self`. |
864 | | /// |
865 | | /// This function always returns the precise result. |
866 | | #[must_use] |
867 | | $fn_abs |
868 | | |
869 | | /// Returns numbers representing the sign of each element. |
870 | | /// |
871 | | /// - `1.0` if the element is positive, `+0.0`, or `INFINITY` |
872 | | /// - `-1.0` if the element is negative, `-0.0`, or `NEG_INFINITY` |
873 | | /// - NaN if the element is NaN |
874 | | /// |
875 | | /// This matches the behavior of [`f32::signum`]. |
876 | | /// |
877 | | /// [`f32::signum`]: https://doc.rust-lang.org/std/primitive.f32.html#method.signum |
878 | | #[inline] |
879 | | #[must_use] |
880 | | pub fn signum(self) -> Self { |
881 | | Self::ONE | self & -Self::ZERO | self.is_nan() |
882 | | } |
883 | | |
884 | | /// Returns numbers composed of the magnitudes of `self` and the signs of |
885 | | /// `sign`. |
886 | | /// |
887 | | /// Equal to `self` if the sign of `self` and `sign` are the same, |
888 | | /// otherwise equal to `-self`. Even if `self` or `sign` are NaN, the |
889 | | /// result is the exact bit pattern of `self` with the sign bit of `sign`. |
890 | | #[inline] |
891 | | #[must_use] |
892 | | pub fn copysign(self, sign: Self) -> Self { |
893 | | Self::splat(-0.0).bitselect(sign, self) |
894 | | } |
895 | | |
896 | | /// Flips the sign of `self` based on the sign of `sign`. |
897 | | /// |
898 | | /// If `sign` has a positive sign, the result is `self`. If `sign` has a |
899 | | /// negative sign, the result is `-self`. Even if `self` or `sign` are |
900 | | /// NaN, the result is the exact bit pattern of `self` with a sign flipped |
901 | | /// based on the sign bit of `sign`. |
902 | | #[inline] |
903 | | #[must_use] |
904 | | pub fn flip_signs(self, sign: Self) -> Self { |
905 | | self ^ (sign & Self::from(-0.0)) |
906 | | } |
907 | | |
908 | | /// Returns the largest integer less than or equal to each input element. |
909 | | /// |
910 | | /// This function always returns the precise result. |
911 | | #[must_use] |
912 | | $fn_floor |
913 | | |
914 | | /// Returns the smallest integer greater than or equal to each input |
915 | | /// element. |
916 | | /// |
917 | | /// This function always returns the precise result. |
918 | | #[must_use] |
919 | | $fn_ceil |
920 | | |
921 | | /// Returns the nearest integer to each input element. If a value is |
922 | | /// half-way between two integers, round away from `0.0`. |
923 | | /// |
924 | | /// This function always returns the precise result. |
925 | | /// |
926 | | /// For most targets architectures, [`round`] is slower than |
927 | | /// [`round_ties_even`]. If you do not care about the difference, consider |
928 | | /// using that instead. |
929 | | /// |
930 | | /// [`round`]: Self::round |
931 | | /// [`round_ties_even`]: Self::round_ties_even |
932 | | #[must_use] |
933 | | $fn_round |
934 | | |
935 | | /// Returns the nearest integer to each input element. |
936 | | /// |
937 | | /// The result for values half-way between two integers is currently not |
938 | | /// specified. |
939 | | /// |
940 | | /// This saturates out of range values and turns NaNs to `0`. See |
941 | | /// [`fast_round_int`] for a faster variant that does not handle out of |
942 | | /// range values or NaNs. |
943 | | /// |
944 | | /// [`fast_round_int`]: Self::fast_round_int |
945 | | #[must_use] |
946 | | $fn_round_int |
947 | | |
948 | | /// Returns the nearest integer to each input element. |
949 | | /// |
950 | | /// The result for values half-way between two integers is currently not |
951 | | /// specified. |
952 | | /// |
953 | | /// This function does not handle out of range values or NaNs. See |
954 | | /// [`round_int`] for a slower variant that does handle out of range |
955 | | /// values and NaNs. |
956 | | /// |
957 | | /// [`round_int`]: Self::round_int |
958 | | #[must_use] |
959 | | $fn_fast_round_int |
960 | | |
961 | | /// Returns the nearest integer to each input element. Rounds half-way |
962 | | /// cases to the number with an even least significant digit. |
963 | | /// |
964 | | /// This function always returns the precise result. |
965 | | #[must_use] |
966 | | $fn_round_ties_even |
967 | | |
968 | | /// Returns the integer part of each input element. This means that |
969 | | /// non-integer numbers are always truncated towards zero. |
970 | | /// |
971 | | /// This function always returns the precise result. |
972 | | #[must_use] |
973 | | $fn_trunc |
974 | | |
975 | | /// Returns the integer part of each input element. This means that |
976 | | /// non-integer numbers are always truncated towards zero. |
977 | | /// |
978 | | /// This saturates out of range values and turns NaNs to `0`. See |
979 | | /// [`fast_trunc_int`] for a faster variant that does not handle out of |
980 | | /// range values or NaNs. |
981 | | /// |
982 | | /// [`fast_trunc_int`]: Self::fast_trunc_int |
983 | | #[must_use] |
984 | | $fn_trunc_int |
985 | | |
986 | | /// Returns the integer part of each input element. This means that |
987 | | /// non-integer numbers are always truncated towards zero. |
988 | | /// |
989 | | /// This function does not handle out of range values or NaNs. See |
990 | | /// [`trunc_int`] for a slower variant that does handle out of range |
991 | | /// values and NaNs. |
992 | | /// |
993 | | /// [`trunc_int`]: Self::trunc_int |
994 | | #[must_use] |
995 | | $fn_fast_trunc_int |
996 | | |
997 | | /// Returns the fractional part of each input element. |
998 | | /// |
999 | | /// This function always returns the precise result. |
1000 | | #[inline] |
1001 | | #[must_use] |
1002 | | pub fn fract(self) -> Self { |
1003 | | self - self.trunc() |
1004 | | } |
1005 | | |
1006 | | /// Fused multiply-add. Computes `(self * a) + b`. |
1007 | | /// |
1008 | | /// If there is hardware FMA support, this computes the result with only |
1009 | | /// one rounding error. If not, this falls back to separate multiply and |
1010 | | /// add operations, resulting in two rounding errors. Note that in the |
1011 | | /// future, this function may change to always having one rounding error, |
1012 | | /// at the cost of worse performance. |
1013 | | #[must_use] |
1014 | | $fn_mul_add |
1015 | | |
1016 | | /// Fused multiply-sub. Computes `(self * a) - b`. |
1017 | | /// |
1018 | | /// If there is hardware FMA support, this computes the result with only |
1019 | | /// one rounding error. If not, this falls back to separate multiply and |
1020 | | /// add operations, resulting in two rounding errors. Note that in the |
1021 | | /// future, this function may change to always having one rounding error, |
1022 | | /// at the cost of worse performance. |
1023 | | #[must_use] |
1024 | | $fn_mul_sub |
1025 | | |
1026 | | /// Fused multiply-negate-add. Computes `-(self * a) + b`. |
1027 | | /// |
1028 | | /// If there is hardware FMA support, this computes the result with only |
1029 | | /// one rounding error. If not, this falls back to separate multiply and |
1030 | | /// add operations, resulting in two rounding errors. Note that in the |
1031 | | /// future, this function may change to always having one rounding error, |
1032 | | /// at the cost of worse performance. |
1033 | | #[must_use] |
1034 | | $fn_mul_neg_add |
1035 | | |
1036 | | /// Fused multiply-negate-sub. Computes `-(self * a) - b`. |
1037 | | /// |
1038 | | /// If there is hardware FMA support, this computes the result with only |
1039 | | /// one rounding error. If not, this falls back to separate multiply and |
1040 | | /// add operations, resulting in two rounding errors. Note that in the |
1041 | | /// future, this function may change to always having one rounding error, |
1042 | | /// at the cost of worse performance. |
1043 | | #[must_use] |
1044 | | $fn_mul_neg_sub |
1045 | | |
1046 | | /// Calculates Euclidean division, the matching function for |
1047 | | /// [`rem_euclid`]. |
1048 | | /// |
1049 | | /// This computes the integer `n` such that |
1050 | | /// `self = n * rhs + self.rem_euclid(rhs)`. In other words, the result is |
1051 | | /// `self / rhs` rounded to the integer `n` such that `self >= n * rhs`. |
1052 | | /// |
1053 | | /// This function is not guaranteed to exactly match |
1054 | | #[doc = concat!("[`", stringify!($T), "::div_euclid`].")] |
1055 | | /// |
1056 | | /// [`rem_euclid`]: Self::rem_euclid |
1057 | | #[inline] |
1058 | | #[must_use] |
1059 | | pub fn div_euclid(self, rhs: Self) -> Self { |
1060 | | let q = (self / rhs).trunc(); |
1061 | | (self % rhs) |
1062 | | .simd_lt(Self::ZERO) |
1063 | | .select(rhs.simd_gt(Self::ZERO).select(q - Self::ONE, q + Self::ONE), q) |
1064 | | } |
1065 | | |
1066 | | /// Calculates the least nonnegative remainder of `self` when divided by |
1067 | | /// `rhs`. |
1068 | | /// |
1069 | | /// In particular, the return value `r` satisfies `0.0 <= r < rhs.abs()` in |
1070 | | /// most cases. However, due to a floating point round-off error it can |
1071 | | /// result in `r == rhs.abs()`, violating the mathematical definition, if |
1072 | | /// `self` is much smaller than `rhs.abs()` in magnitude and `self < 0.0`. |
1073 | | /// This result is not an element of the function's codomain, but it is the |
1074 | | /// closest floating point number in the real numbers and thus fulfills the |
1075 | | /// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)` |
1076 | | /// approximately. |
1077 | | /// |
1078 | | /// This function is not guaranteed to exactly match |
1079 | | #[doc = concat!("[`", stringify!($T), "::rem_euclid`].")] |
1080 | | #[inline] |
1081 | | #[must_use] |
1082 | | pub fn rem_euclid(self, rhs: Self) -> Self { |
1083 | | let r = self % rhs; |
1084 | | r.simd_lt(Self::ZERO).select(r + rhs.abs(), r) |
1085 | | } |
1086 | | |
1087 | | /// Raises each element of the number `self` to the corresponding element |
1088 | | /// of the floating point power `n`. |
1089 | | /// |
1090 | | /// This function cannot be named simply `powf`, because a now deprecated |
1091 | | /// function already uses that name. |
1092 | | /// |
1093 | | /// # Unspecified precision |
1094 | | /// |
1095 | | /// The precision of this function is non-deterministic. This means it |
1096 | | /// varies by platform, version, and can even differ within the same |
1097 | | /// execution from one invocation to the next. |
1098 | | #[must_use] |
1099 | | $fn_powf_simd |
1100 | | |
1101 | | /// Returns the square root of a number for each input element. |
1102 | | /// |
1103 | | /// Returns NaN if `self` is a negative number other than `-0.0`. |
1104 | | /// |
1105 | | /// This function always returns the precise result. |
1106 | | #[must_use] |
1107 | | $fn_sqrt |
1108 | | |
1109 | | /// Returns `e^(self)`, (the exponential function) for each input element. |
1110 | | /// |
1111 | | /// # Unspecified precision |
1112 | | /// |
1113 | | /// The precision of this function is non-deterministic. This means it |
1114 | | /// varies by platform, version, and can even differ within the same |
1115 | | /// execution from one invocation to the next. |
1116 | | #[must_use] |
1117 | | $fn_exp |
1118 | | |
1119 | | /// Returns `2^(self)` for each input element. |
1120 | | /// |
1121 | | /// # Unspecified precision |
1122 | | /// |
1123 | | /// The precision of this function is non-deterministic. This means it |
1124 | | /// varies by platform, version, and can even differ within the same |
1125 | | /// execution from one invocation to the next. |
1126 | | #[must_use] |
1127 | | $fn_exp2 |
1128 | | |
1129 | | /// Returns the natural logarithm of a number for each input element. |
1130 | | /// |
1131 | | /// # Unspecified precision |
1132 | | /// |
1133 | | /// The precision of this function is non-deterministic. This means it |
1134 | | /// varies by platform, version, and can even differ within the same |
1135 | | /// execution from one invocation to the next. |
1136 | | #[must_use] |
1137 | | $fn_ln |
1138 | | |
1139 | | /// Returns the base 2 logarithm of a number for each input element. |
1140 | | /// |
1141 | | /// # Unspecified precision |
1142 | | /// |
1143 | | /// The precision of this function is non-deterministic. This means it |
1144 | | /// varies by platform, version, and can even differ within the same |
1145 | | /// execution from one invocation to the next. |
1146 | | #[inline] |
1147 | | #[must_use] |
1148 | | pub fn log2(self) -> Self { |
1149 | | Self::ln(self) * Self::LOG2_E |
1150 | | } |
1151 | | |
1152 | | /// Returns the base 10 logarithm of a number for each input element. |
1153 | | /// |
1154 | | /// # Unspecified precision |
1155 | | /// |
1156 | | /// The precision of this function is non-deterministic. This means it |
1157 | | /// varies by platform, version, and can even differ within the same |
1158 | | /// execution from one invocation to the next. |
1159 | | #[inline] |
1160 | | #[must_use] |
1161 | | pub fn log10(self) -> Self { |
1162 | | Self::ln(self) * Self::LOG10_E |
1163 | | } |
1164 | | |
1165 | | /// Returns the cube root of a number for each input element. |
1166 | | /// |
1167 | | /// # Unspecified precision |
1168 | | /// |
1169 | | /// The precision of this function is non-deterministic. This means it |
1170 | | /// varies by platform, version, and can even differ within the same |
1171 | | /// execution from one invocation to the next. |
1172 | | #[must_use] |
1173 | | $fn_cbrt |
1174 | | |
1175 | | /// Computes the sine of a number (in radians) for each input element. |
1176 | | /// |
1177 | | /// # Unspecified precision |
1178 | | /// |
1179 | | /// The precision of this function is non-deterministic. This means it |
1180 | | /// varies by platform, version, and can even differ within the same |
1181 | | /// execution from one invocation to the next. |
1182 | | #[inline] |
1183 | | #[must_use] |
1184 | | pub fn sin(self) -> Self { |
1185 | | let (s, _) = self.sin_cos(); |
1186 | | s |
1187 | | } |
1188 | | |
1189 | | /// Computes the cosine of a number (in radians) for each input element. |
1190 | | /// |
1191 | | /// # Unspecified precision |
1192 | | /// |
1193 | | /// The precision of this function is non-deterministic. This means it |
1194 | | /// varies by platform, version, and can even differ within the same |
1195 | | /// execution from one invocation to the next. |
1196 | | #[inline] |
1197 | | #[must_use] |
1198 | | pub fn cos(self) -> Self { |
1199 | | let (_, c) = self.sin_cos(); |
1200 | | c |
1201 | | } |
1202 | | |
1203 | | /// Computes the tangent of a number (in radians) for each input element. |
1204 | | /// |
1205 | | /// # Unspecified precision |
1206 | | /// |
1207 | | /// The precision of this function is non-deterministic. This means it |
1208 | | /// varies by platform, version, and can even differ within the same |
1209 | | /// execution from one invocation to the next. |
1210 | | #[inline] |
1211 | | #[must_use] |
1212 | | pub fn tan(self) -> Self { |
1213 | | let (s, c) = self.sin_cos(); |
1214 | | s / c |
1215 | | } |
1216 | | |
1217 | | /// Computes the arcsine of a number for each input element. Return value |
1218 | | /// is in radians in the range [-pi/2, pi/2] or NaN if the number is |
1219 | | /// outside the range [-1, 1]. |
1220 | | /// |
1221 | | /// # Unspecified precision |
1222 | | /// |
1223 | | /// The precision of this function is non-deterministic. This means it |
1224 | | /// varies by platform, version, and can even differ within the same |
1225 | | /// execution from one invocation to the next. |
1226 | | #[must_use] |
1227 | | $fn_asin |
1228 | | |
1229 | | /// Computes the arccosine of a number for each input element. Return |
1230 | | /// value is in radians in the range [0, pi] or NaN if the number is |
1231 | | /// outside the range [-1, 1]. |
1232 | | /// |
1233 | | /// # Unspecified precision |
1234 | | /// |
1235 | | /// The precision of this function is non-deterministic. This means it |
1236 | | /// varies by platform, version, and can even differ within the same |
1237 | | /// execution from one invocation to the next. |
1238 | | #[must_use] |
1239 | | $fn_acos |
1240 | | |
1241 | | /// Computes the arctangent of a number for each input element. Return |
1242 | | /// value is in radians in the range [-pi/2, pi/2]. |
1243 | | /// |
1244 | | /// # Unspecified precision |
1245 | | /// |
1246 | | /// The precision of this function is non-deterministic. This means it |
1247 | | /// varies by platform, version, and can even differ within the same |
1248 | | /// execution from one invocation to the next. |
1249 | | #[must_use] |
1250 | | $fn_atan |
1251 | | |
1252 | | /// Computes the four quadrant arctangent of each element of `self` (`y`) |
1253 | | /// and the corresponding element of `other` (`x`) in radians. |
1254 | | /// |
1255 | | /// | `x` | `y` | Piecewise Definition | Range | |
1256 | | /// |---------|---------|----------------------|---------------| |
1257 | | /// | `>= +0` | `>= +0` | `arctan(y/x)` | `[+0, +pi/2]` | |
1258 | | /// | `>= +0` | `<= -0` | `arctan(y/x)` | `[-pi/2, -0]` | |
1259 | | /// | `<= -0` | `>= +0` | `arctan(y/x) + pi` | `[+pi/2, +pi]`| |
1260 | | /// | `<= -0` | `<= -0` | `arctan(y/x) - pi` | `[-pi, -pi/2]`| |
1261 | | /// |
1262 | | /// # Unspecified precision |
1263 | | /// |
1264 | | /// The precision of this function is non-deterministic. This means it |
1265 | | /// varies by platform, version, and can even differ within the same |
1266 | | /// execution from one invocation to the next. |
1267 | | #[must_use] |
1268 | | $fn_atan2 |
1269 | | |
1270 | | /// Simultaneously computes the sine and cosine of a number `x` for each |
1271 | | /// input element. Returns `(sin(x), cos(x))`. |
1272 | | /// |
1273 | | /// # Unspecified precision |
1274 | | /// |
1275 | | /// The precision of this function is non-deterministic. This means it |
1276 | | /// varies by platform, version, and can even differ within the same |
1277 | | /// execution from one invocation to the next. |
1278 | | #[must_use] |
1279 | | $fn_sin_cos |
1280 | | |
1281 | | /// Simultaneously computes the arcsine and arccosine of a number `x` for |
1282 | | /// each input element. Returns `(asin(x), acos(x))`. |
1283 | | /// |
1284 | | /// # Unspecified precision |
1285 | | /// |
1286 | | /// The precision of this function is non-deterministic. This means it |
1287 | | /// varies by platform, version, and can even differ within the same |
1288 | | /// execution from one invocation to the next. |
1289 | | #[must_use] |
1290 | | $fn_asin_acos |
1291 | | |
1292 | | /// Returns `e^(self) - 1` for each input element in a way that is |
1293 | | /// accurate even if a number is close to zero. |
1294 | | /// |
1295 | | /// # Unspecified precision |
1296 | | /// |
1297 | | /// The precision of this function is non-deterministic. This means it |
1298 | | /// varies by platform, version, and can even differ within the same |
1299 | | /// execution from one invocation to the next. |
1300 | | #[must_use] |
1301 | | $fn_exp_m1 |
1302 | | |
1303 | | /// Returns `ln(1+n)` (natural logarithm) for each input element more |
1304 | | /// accurately than if the operations were performed separately. |
1305 | | /// |
1306 | | /// # Unspecified precision |
1307 | | /// |
1308 | | /// The precision of this function is non-deterministic. This means it |
1309 | | /// varies by platform, version, and can even differ within the same |
1310 | | /// execution from one invocation to the next. |
1311 | | #[must_use] |
1312 | | $fn_ln_1p |
1313 | | |
1314 | | /// Returns the hyperbolic sine (`(e^self - e^(-self))/2`) for each input |
1315 | | /// element. |
1316 | | /// |
1317 | | /// # Unspecified precision |
1318 | | /// |
1319 | | /// The precision of this function is non-deterministic. This means it |
1320 | | /// varies by platform, version, and can even differ within the same |
1321 | | /// execution from one invocation to the next. |
1322 | | #[must_use] |
1323 | | $fn_sinh |
1324 | | |
1325 | | /// Returns the hyperbolic cosine (`(e^self + e^(-self))/2`) for each |
1326 | | /// input element. |
1327 | | /// |
1328 | | /// # Unspecified precision |
1329 | | /// |
1330 | | /// The precision of this function is non-deterministic. This means it |
1331 | | /// varies by platform, version, and can even differ within the same |
1332 | | /// execution from one invocation to the next. |
1333 | | #[must_use] |
1334 | | $fn_cosh |
1335 | | |
1336 | | /// Returns the hyperbolic tangent (`sinh(self)/cosh(self)`) for each |
1337 | | /// input element. |
1338 | | /// |
1339 | | /// # Unspecified precision |
1340 | | /// |
1341 | | /// The precision of this function is non-deterministic. This means it |
1342 | | /// varies by platform, version, and can even differ within the same |
1343 | | /// execution from one invocation to the next. |
1344 | | #[must_use] |
1345 | | $fn_tanh |
1346 | | |
1347 | | /// Raises each element of the number `self` to the corresponding element |
1348 | | /// of the floating point power `n`. |
1349 | | /// |
1350 | | /// This function has been renamed to [`powf_simd`]. |
1351 | | /// |
1352 | | /// # Unspecified precision |
1353 | | /// |
1354 | | /// The precision of this function is non-deterministic. This means it |
1355 | | /// varies by platform, version, and can even differ within the same |
1356 | | /// execution from one invocation to the next. |
1357 | | /// |
1358 | | /// [`powf_simd`]: Self::powf_simd |
1359 | | #[deprecated(since = "1.6.0", note = "renamed to `powf_simd`")] |
1360 | | #[inline] |
1361 | | #[must_use] |
1362 | | pub fn $old_powf_simd_fn_name(self, n: Self) -> Self { |
1363 | | self.powf_simd(n) |
1364 | | } |
1365 | | |
1366 | | /// Raises each element of the number `self` to the scalar floating point |
1367 | | /// power `n`. |
1368 | | /// |
1369 | | /// This function has been deprecated because it raises all elements of |
1370 | | /// `x` to the same power, even though that brings no performance benefit. |
1371 | | #[doc = concat!("Use `x.powf_simd(", stringify!($Simd), "::splat(n))` instead.")] |
1372 | | /// |
1373 | | /// # Unspecified precision |
1374 | | /// |
1375 | | /// The precision of this function is non-deterministic. This means it |
1376 | | /// varies by platform, version, and can even differ within the same |
1377 | | /// execution from one invocation to the next. |
1378 | | #[deprecated(since = "1.6.0", note = "use `x.powf_simd(splat(n))` instead")] |
1379 | | #[inline] |
1380 | | #[must_use] |
1381 | | pub fn powf(self, n: $T) -> Self { |
1382 | | self.powf_simd(Self::splat(n)) |
1383 | | } |
1384 | | } |
1385 | | }; |
1386 | | } |