Coverage Report

Created: 2026-10-28 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}