half/
num_traits.rs

1use crate::{bf16, f16};
2use core::cmp::Ordering;
3use core::{num::FpCategory, ops::Div};
4use num_traits::{
5    AsPrimitive, Bounded, FloatConst, FromBytes, FromPrimitive, Num, NumCast, One, ToBytes,
6    ToPrimitive, Zero,
7};
8
9impl ToPrimitive for f16 {
10    #[inline]
11    fn to_i64(&self) -> Option<i64> {
12        Self::to_f32(*self).to_i64()
13    }
14    #[inline]
15    fn to_u64(&self) -> Option<u64> {
16        Self::to_f32(*self).to_u64()
17    }
18    #[inline]
19    fn to_i8(&self) -> Option<i8> {
20        Self::to_f32(*self).to_i8()
21    }
22    #[inline]
23    fn to_u8(&self) -> Option<u8> {
24        Self::to_f32(*self).to_u8()
25    }
26    #[inline]
27    fn to_i16(&self) -> Option<i16> {
28        Self::to_f32(*self).to_i16()
29    }
30    #[inline]
31    fn to_u16(&self) -> Option<u16> {
32        Self::to_f32(*self).to_u16()
33    }
34    #[inline]
35    fn to_i32(&self) -> Option<i32> {
36        Self::to_f32(*self).to_i32()
37    }
38    #[inline]
39    fn to_u32(&self) -> Option<u32> {
40        Self::to_f32(*self).to_u32()
41    }
42    #[inline]
43    fn to_f32(&self) -> Option<f32> {
44        Some(Self::to_f32(*self))
45    }
46    #[inline]
47    fn to_f64(&self) -> Option<f64> {
48        Some(Self::to_f64(*self))
49    }
50}
51
52impl FromPrimitive for f16 {
53    #[inline]
54    fn from_i64(n: i64) -> Option<Self> {
55        n.to_f32().map(Self::from_f32)
56    }
57    #[inline]
58    fn from_u64(n: u64) -> Option<Self> {
59        n.to_f32().map(Self::from_f32)
60    }
61    #[inline]
62    fn from_i8(n: i8) -> Option<Self> {
63        n.to_f32().map(Self::from_f32)
64    }
65    #[inline]
66    fn from_u8(n: u8) -> Option<Self> {
67        n.to_f32().map(Self::from_f32)
68    }
69    #[inline]
70    fn from_i16(n: i16) -> Option<Self> {
71        n.to_f32().map(Self::from_f32)
72    }
73    #[inline]
74    fn from_u16(n: u16) -> Option<Self> {
75        n.to_f32().map(Self::from_f32)
76    }
77    #[inline]
78    fn from_i32(n: i32) -> Option<Self> {
79        n.to_f32().map(Self::from_f32)
80    }
81    #[inline]
82    fn from_u32(n: u32) -> Option<Self> {
83        n.to_f32().map(Self::from_f32)
84    }
85    #[inline]
86    fn from_f32(n: f32) -> Option<Self> {
87        n.to_f32().map(Self::from_f32)
88    }
89    #[inline]
90    fn from_f64(n: f64) -> Option<Self> {
91        n.to_f64().map(Self::from_f64)
92    }
93}
94
95impl Num for f16 {
96    type FromStrRadixErr = <f32 as Num>::FromStrRadixErr;
97
98    #[inline]
99    fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
100        Ok(Self::from_f32(f32::from_str_radix(str, radix)?))
101    }
102}
103
104impl One for f16 {
105    #[inline]
106    fn one() -> Self {
107        Self::ONE
108    }
109}
110
111impl Zero for f16 {
112    #[inline]
113    fn zero() -> Self {
114        Self::ZERO
115    }
116
117    #[inline]
118    fn is_zero(&self) -> bool {
119        *self == Self::ZERO
120    }
121}
122
123impl NumCast for f16 {
124    #[inline]
125    fn from<T: ToPrimitive>(n: T) -> Option<Self> {
126        n.to_f32().map(Self::from_f32)
127    }
128}
129
130impl num_traits::float::FloatCore for f16 {
131    #[inline]
132    fn infinity() -> Self {
133        Self::INFINITY
134    }
135
136    #[inline]
137    fn neg_infinity() -> Self {
138        Self::NEG_INFINITY
139    }
140
141    #[inline]
142    fn nan() -> Self {
143        Self::NAN
144    }
145
146    #[inline]
147    fn neg_zero() -> Self {
148        Self::NEG_ZERO
149    }
150
151    #[inline]
152    fn min_value() -> Self {
153        Self::MIN
154    }
155
156    #[inline]
157    fn min_positive_value() -> Self {
158        Self::MIN_POSITIVE
159    }
160
161    #[inline]
162    fn epsilon() -> Self {
163        Self::EPSILON
164    }
165
166    #[inline]
167    fn max_value() -> Self {
168        Self::MAX
169    }
170
171    #[inline]
172    fn is_nan(self) -> bool {
173        self.is_nan()
174    }
175
176    #[inline]
177    fn is_infinite(self) -> bool {
178        self.is_infinite()
179    }
180
181    #[inline]
182    fn is_finite(self) -> bool {
183        self.is_finite()
184    }
185
186    #[inline]
187    fn is_normal(self) -> bool {
188        self.is_normal()
189    }
190
191    #[inline]
192    fn classify(self) -> FpCategory {
193        self.classify()
194    }
195
196    #[inline]
197    fn floor(self) -> Self {
198        Self::from_f32(self.to_f32().floor())
199    }
200
201    #[inline]
202    fn ceil(self) -> Self {
203        Self::from_f32(self.to_f32().ceil())
204    }
205
206    #[inline]
207    fn round(self) -> Self {
208        Self::from_f32(self.to_f32().round())
209    }
210
211    #[inline]
212    fn trunc(self) -> Self {
213        Self::from_f32(self.to_f32().trunc())
214    }
215
216    #[inline]
217    fn fract(self) -> Self {
218        Self::from_f32(self.to_f32().fract())
219    }
220
221    #[inline]
222    fn abs(self) -> Self {
223        Self::from_bits(self.to_bits() & 0x7FFF)
224    }
225
226    #[inline]
227    fn signum(self) -> Self {
228        self.signum()
229    }
230
231    #[inline]
232    fn is_sign_positive(self) -> bool {
233        self.is_sign_positive()
234    }
235
236    #[inline]
237    fn is_sign_negative(self) -> bool {
238        self.is_sign_negative()
239    }
240
241    fn min(self, other: Self) -> Self {
242        match self.partial_cmp(&other) {
243            None => {
244                if self.is_nan() {
245                    other
246                } else {
247                    self
248                }
249            }
250            Some(Ordering::Greater) | Some(Ordering::Equal) => other,
251            Some(Ordering::Less) => self,
252        }
253    }
254
255    fn max(self, other: Self) -> Self {
256        match self.partial_cmp(&other) {
257            None => {
258                if self.is_nan() {
259                    other
260                } else {
261                    self
262                }
263            }
264            Some(Ordering::Greater) | Some(Ordering::Equal) => self,
265            Some(Ordering::Less) => other,
266        }
267    }
268
269    #[inline]
270    fn recip(self) -> Self {
271        Self::from_f32(self.to_f32().recip())
272    }
273
274    #[inline]
275    fn powi(self, exp: i32) -> Self {
276        Self::from_f32(self.to_f32().powi(exp))
277    }
278
279    #[inline]
280    fn to_degrees(self) -> Self {
281        Self::from_f32(self.to_f32().to_degrees())
282    }
283
284    #[inline]
285    fn to_radians(self) -> Self {
286        Self::from_f32(self.to_f32().to_radians())
287    }
288
289    #[inline]
290    fn integer_decode(self) -> (u64, i16, i8) {
291        num_traits::float::FloatCore::integer_decode(self.to_f32())
292    }
293}
294
295impl num_traits::float::Float for f16 {
296    #[inline]
297    fn nan() -> Self {
298        Self::NAN
299    }
300
301    #[inline]
302    fn infinity() -> Self {
303        Self::INFINITY
304    }
305
306    #[inline]
307    fn neg_infinity() -> Self {
308        Self::NEG_INFINITY
309    }
310
311    #[inline]
312    fn neg_zero() -> Self {
313        Self::NEG_ZERO
314    }
315
316    #[inline]
317    fn min_value() -> Self {
318        Self::MIN
319    }
320
321    #[inline]
322    fn min_positive_value() -> Self {
323        Self::MIN_POSITIVE
324    }
325
326    #[inline]
327    fn epsilon() -> Self {
328        Self::EPSILON
329    }
330
331    #[inline]
332    fn max_value() -> Self {
333        Self::MAX
334    }
335
336    #[inline]
337    fn is_nan(self) -> bool {
338        self.is_nan()
339    }
340
341    #[inline]
342    fn is_infinite(self) -> bool {
343        self.is_infinite()
344    }
345
346    #[inline]
347    fn is_finite(self) -> bool {
348        self.is_finite()
349    }
350
351    #[inline]
352    fn is_normal(self) -> bool {
353        self.is_normal()
354    }
355
356    #[inline]
357    fn classify(self) -> FpCategory {
358        self.classify()
359    }
360
361    #[inline]
362    fn floor(self) -> Self {
363        Self::from_f32(self.to_f32().floor())
364    }
365
366    #[inline]
367    fn ceil(self) -> Self {
368        Self::from_f32(self.to_f32().ceil())
369    }
370
371    #[inline]
372    fn round(self) -> Self {
373        Self::from_f32(self.to_f32().round())
374    }
375
376    #[inline]
377    fn trunc(self) -> Self {
378        Self::from_f32(self.to_f32().trunc())
379    }
380
381    #[inline]
382    fn fract(self) -> Self {
383        Self::from_f32(self.to_f32().fract())
384    }
385
386    #[inline]
387    fn abs(self) -> Self {
388        Self::from_f32(self.to_f32().abs())
389    }
390
391    #[inline]
392    fn signum(self) -> Self {
393        Self::from_f32(self.to_f32().signum())
394    }
395
396    #[inline]
397    fn is_sign_positive(self) -> bool {
398        self.is_sign_positive()
399    }
400
401    #[inline]
402    fn is_sign_negative(self) -> bool {
403        self.is_sign_negative()
404    }
405
406    #[inline]
407    fn mul_add(self, a: Self, b: Self) -> Self {
408        Self::from_f32(self.to_f32().mul_add(a.to_f32(), b.to_f32()))
409    }
410
411    #[inline]
412    fn recip(self) -> Self {
413        Self::from_f32(self.to_f32().recip())
414    }
415
416    #[inline]
417    fn powi(self, n: i32) -> Self {
418        Self::from_f32(self.to_f32().powi(n))
419    }
420
421    #[inline]
422    fn powf(self, n: Self) -> Self {
423        Self::from_f32(self.to_f32().powf(n.to_f32()))
424    }
425
426    #[inline]
427    fn sqrt(self) -> Self {
428        Self::from_f32(self.to_f32().sqrt())
429    }
430
431    #[inline]
432    fn exp(self) -> Self {
433        Self::from_f32(self.to_f32().exp())
434    }
435
436    #[inline]
437    fn exp2(self) -> Self {
438        Self::from_f32(self.to_f32().exp2())
439    }
440
441    #[inline]
442    fn ln(self) -> Self {
443        Self::from_f32(self.to_f32().ln())
444    }
445
446    #[inline]
447    fn log(self, base: Self) -> Self {
448        Self::from_f32(self.to_f32().log(base.to_f32()))
449    }
450
451    #[inline]
452    fn log2(self) -> Self {
453        Self::from_f32(self.to_f32().log2())
454    }
455
456    #[inline]
457    fn log10(self) -> Self {
458        Self::from_f32(self.to_f32().log10())
459    }
460
461    #[inline]
462    fn to_degrees(self) -> Self {
463        Self::from_f32(self.to_f32().to_degrees())
464    }
465
466    #[inline]
467    fn to_radians(self) -> Self {
468        Self::from_f32(self.to_f32().to_radians())
469    }
470
471    #[inline]
472    fn max(self, other: Self) -> Self {
473        self.max(other)
474    }
475
476    #[inline]
477    fn min(self, other: Self) -> Self {
478        self.min(other)
479    }
480
481    #[inline]
482    fn abs_sub(self, other: Self) -> Self {
483        Self::from_f32((self.to_f32() - other.to_f32()).max(0.0))
484    }
485
486    #[inline]
487    fn cbrt(self) -> Self {
488        Self::from_f32(self.to_f32().cbrt())
489    }
490
491    #[inline]
492    fn hypot(self, other: Self) -> Self {
493        Self::from_f32(self.to_f32().hypot(other.to_f32()))
494    }
495
496    #[inline]
497    fn sin(self) -> Self {
498        Self::from_f32(self.to_f32().sin())
499    }
500
501    #[inline]
502    fn cos(self) -> Self {
503        Self::from_f32(self.to_f32().cos())
504    }
505
506    #[inline]
507    fn tan(self) -> Self {
508        Self::from_f32(self.to_f32().tan())
509    }
510
511    #[inline]
512    fn asin(self) -> Self {
513        Self::from_f32(self.to_f32().asin())
514    }
515
516    #[inline]
517    fn acos(self) -> Self {
518        Self::from_f32(self.to_f32().acos())
519    }
520
521    #[inline]
522    fn atan(self) -> Self {
523        Self::from_f32(self.to_f32().atan())
524    }
525
526    #[inline]
527    fn atan2(self, other: Self) -> Self {
528        Self::from_f32(self.to_f32().atan2(other.to_f32()))
529    }
530
531    #[inline]
532    fn sin_cos(self) -> (Self, Self) {
533        let (sin, cos) = self.to_f32().sin_cos();
534        (Self::from_f32(sin), Self::from_f32(cos))
535    }
536
537    #[inline]
538    fn exp_m1(self) -> Self {
539        Self::from_f32(self.to_f32().exp_m1())
540    }
541
542    #[inline]
543    fn ln_1p(self) -> Self {
544        Self::from_f32(self.to_f32().ln_1p())
545    }
546
547    #[inline]
548    fn sinh(self) -> Self {
549        Self::from_f32(self.to_f32().sinh())
550    }
551
552    #[inline]
553    fn cosh(self) -> Self {
554        Self::from_f32(self.to_f32().cosh())
555    }
556
557    #[inline]
558    fn tanh(self) -> Self {
559        Self::from_f32(self.to_f32().tanh())
560    }
561
562    #[inline]
563    fn asinh(self) -> Self {
564        Self::from_f32(self.to_f32().asinh())
565    }
566
567    #[inline]
568    fn acosh(self) -> Self {
569        Self::from_f32(self.to_f32().acosh())
570    }
571
572    #[inline]
573    fn atanh(self) -> Self {
574        Self::from_f32(self.to_f32().atanh())
575    }
576
577    #[inline]
578    fn integer_decode(self) -> (u64, i16, i8) {
579        num_traits::float::Float::integer_decode(self.to_f32())
580    }
581}
582
583impl FloatConst for f16 {
584    #[inline]
585    fn E() -> Self {
586        Self::E
587    }
588
589    #[inline]
590    fn FRAC_1_PI() -> Self {
591        Self::FRAC_1_PI
592    }
593
594    #[inline]
595    fn FRAC_1_SQRT_2() -> Self {
596        Self::FRAC_1_SQRT_2
597    }
598
599    #[inline]
600    fn FRAC_2_PI() -> Self {
601        Self::FRAC_2_PI
602    }
603
604    #[inline]
605    fn FRAC_2_SQRT_PI() -> Self {
606        Self::FRAC_2_SQRT_PI
607    }
608
609    #[inline]
610    fn FRAC_PI_2() -> Self {
611        Self::FRAC_PI_2
612    }
613
614    #[inline]
615    fn FRAC_PI_3() -> Self {
616        Self::FRAC_PI_3
617    }
618
619    #[inline]
620    fn FRAC_PI_4() -> Self {
621        Self::FRAC_PI_4
622    }
623
624    #[inline]
625    fn FRAC_PI_6() -> Self {
626        Self::FRAC_PI_6
627    }
628
629    #[inline]
630    fn FRAC_PI_8() -> Self {
631        Self::FRAC_PI_8
632    }
633
634    #[inline]
635    fn LN_10() -> Self {
636        Self::LN_10
637    }
638
639    #[inline]
640    fn LN_2() -> Self {
641        Self::LN_2
642    }
643
644    #[inline]
645    fn LOG10_E() -> Self {
646        Self::LOG10_E
647    }
648
649    #[inline]
650    fn LOG2_E() -> Self {
651        Self::LOG2_E
652    }
653
654    #[inline]
655    fn PI() -> Self {
656        Self::PI
657    }
658
659    fn SQRT_2() -> Self {
660        Self::SQRT_2
661    }
662
663    #[inline]
664    fn LOG10_2() -> Self
665    where
666        Self: Sized + Div<Self, Output = Self>,
667    {
668        Self::LOG10_2
669    }
670
671    #[inline]
672    fn LOG2_10() -> Self
673    where
674        Self: Sized + Div<Self, Output = Self>,
675    {
676        Self::LOG2_10
677    }
678}
679
680impl Bounded for f16 {
681    #[inline]
682    fn min_value() -> Self {
683        f16::MIN
684    }
685
686    #[inline]
687    fn max_value() -> Self {
688        f16::MAX
689    }
690}
691
692macro_rules! impl_as_primitive_to_f16 {
693    ($ty:ty, $meth:ident) => {
694        impl AsPrimitive<$ty> for f16 {
695            #[inline]
696            fn as_(self) -> $ty {
697                self.$meth().as_()
698            }
699        }
700    };
701}
702
703impl AsPrimitive<f16> for f16 {
704    #[inline]
705    fn as_(self) -> f16 {
706        self
707    }
708}
709
710impl_as_primitive_to_f16!(i64, to_f32);
711impl_as_primitive_to_f16!(u64, to_f32);
712impl_as_primitive_to_f16!(i8, to_f32);
713impl_as_primitive_to_f16!(u8, to_f32);
714impl_as_primitive_to_f16!(i16, to_f32);
715impl_as_primitive_to_f16!(u16, to_f32);
716impl_as_primitive_to_f16!(i32, to_f32);
717impl_as_primitive_to_f16!(u32, to_f32);
718impl_as_primitive_to_f16!(isize, to_f32);
719impl_as_primitive_to_f16!(usize, to_f32);
720impl_as_primitive_to_f16!(f32, to_f32);
721impl_as_primitive_to_f16!(f64, to_f64);
722impl_as_primitive_to_f16!(bf16, to_f32);
723
724macro_rules! impl_as_primitive_f16_from {
725    ($ty:ty, $meth:ident) => {
726        impl AsPrimitive<f16> for $ty {
727            #[inline]
728            fn as_(self) -> f16 {
729                f16::$meth(self.as_())
730            }
731        }
732    };
733}
734
735impl_as_primitive_f16_from!(i64, from_f32);
736impl_as_primitive_f16_from!(u64, from_f32);
737impl_as_primitive_f16_from!(i8, from_f32);
738impl_as_primitive_f16_from!(u8, from_f32);
739impl_as_primitive_f16_from!(i16, from_f32);
740impl_as_primitive_f16_from!(u16, from_f32);
741impl_as_primitive_f16_from!(i32, from_f32);
742impl_as_primitive_f16_from!(u32, from_f32);
743impl_as_primitive_f16_from!(isize, from_f32);
744impl_as_primitive_f16_from!(usize, from_f32);
745impl_as_primitive_f16_from!(f32, from_f32);
746impl_as_primitive_f16_from!(f64, from_f64);
747
748impl ToBytes for f16 {
749    type Bytes = [u8; 2];
750
751    fn to_be_bytes(&self) -> Self::Bytes {
752        Self::to_be_bytes(*self)
753    }
754
755    fn to_le_bytes(&self) -> Self::Bytes {
756        Self::to_le_bytes(*self)
757    }
758
759    fn to_ne_bytes(&self) -> Self::Bytes {
760        Self::to_ne_bytes(*self)
761    }
762}
763
764impl FromBytes for f16 {
765    type Bytes = [u8; 2];
766
767    fn from_be_bytes(bytes: &Self::Bytes) -> Self {
768        Self::from_be_bytes(*bytes)
769    }
770
771    fn from_le_bytes(bytes: &Self::Bytes) -> Self {
772        Self::from_le_bytes(*bytes)
773    }
774
775    fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
776        Self::from_ne_bytes(*bytes)
777    }
778}
779
780impl ToPrimitive for bf16 {
781    #[inline]
782    fn to_i64(&self) -> Option<i64> {
783        Self::to_f32(*self).to_i64()
784    }
785    #[inline]
786    fn to_u64(&self) -> Option<u64> {
787        Self::to_f32(*self).to_u64()
788    }
789    #[inline]
790    fn to_i8(&self) -> Option<i8> {
791        Self::to_f32(*self).to_i8()
792    }
793    #[inline]
794    fn to_u8(&self) -> Option<u8> {
795        Self::to_f32(*self).to_u8()
796    }
797    #[inline]
798    fn to_i16(&self) -> Option<i16> {
799        Self::to_f32(*self).to_i16()
800    }
801    #[inline]
802    fn to_u16(&self) -> Option<u16> {
803        Self::to_f32(*self).to_u16()
804    }
805    #[inline]
806    fn to_i32(&self) -> Option<i32> {
807        Self::to_f32(*self).to_i32()
808    }
809    #[inline]
810    fn to_u32(&self) -> Option<u32> {
811        Self::to_f32(*self).to_u32()
812    }
813    #[inline]
814    fn to_f32(&self) -> Option<f32> {
815        Some(Self::to_f32(*self))
816    }
817    #[inline]
818    fn to_f64(&self) -> Option<f64> {
819        Some(Self::to_f64(*self))
820    }
821}
822
823impl FromPrimitive for bf16 {
824    #[inline]
825    fn from_i64(n: i64) -> Option<Self> {
826        n.to_f32().map(Self::from_f32)
827    }
828    #[inline]
829    fn from_u64(n: u64) -> Option<Self> {
830        n.to_f32().map(Self::from_f32)
831    }
832    #[inline]
833    fn from_i8(n: i8) -> Option<Self> {
834        n.to_f32().map(Self::from_f32)
835    }
836    #[inline]
837    fn from_u8(n: u8) -> Option<Self> {
838        n.to_f32().map(Self::from_f32)
839    }
840    #[inline]
841    fn from_i16(n: i16) -> Option<Self> {
842        n.to_f32().map(Self::from_f32)
843    }
844    #[inline]
845    fn from_u16(n: u16) -> Option<Self> {
846        n.to_f32().map(Self::from_f32)
847    }
848    #[inline]
849    fn from_i32(n: i32) -> Option<Self> {
850        n.to_f32().map(Self::from_f32)
851    }
852    #[inline]
853    fn from_u32(n: u32) -> Option<Self> {
854        n.to_f32().map(Self::from_f32)
855    }
856    #[inline]
857    fn from_f32(n: f32) -> Option<Self> {
858        n.to_f32().map(Self::from_f32)
859    }
860    #[inline]
861    fn from_f64(n: f64) -> Option<Self> {
862        n.to_f64().map(Self::from_f64)
863    }
864}
865
866impl Num for bf16 {
867    type FromStrRadixErr = <f32 as Num>::FromStrRadixErr;
868
869    #[inline]
870    fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
871        Ok(Self::from_f32(f32::from_str_radix(str, radix)?))
872    }
873}
874
875impl One for bf16 {
876    #[inline]
877    fn one() -> Self {
878        Self::ONE
879    }
880}
881
882impl Zero for bf16 {
883    #[inline]
884    fn zero() -> Self {
885        Self::ZERO
886    }
887
888    #[inline]
889    fn is_zero(&self) -> bool {
890        *self == Self::ZERO
891    }
892}
893
894impl NumCast for bf16 {
895    #[inline]
896    fn from<T: ToPrimitive>(n: T) -> Option<Self> {
897        n.to_f32().map(Self::from_f32)
898    }
899}
900
901impl num_traits::float::FloatCore for bf16 {
902    #[inline]
903    fn infinity() -> Self {
904        Self::INFINITY
905    }
906
907    #[inline]
908    fn neg_infinity() -> Self {
909        Self::NEG_INFINITY
910    }
911
912    #[inline]
913    fn nan() -> Self {
914        Self::NAN
915    }
916
917    #[inline]
918    fn neg_zero() -> Self {
919        Self::NEG_ZERO
920    }
921
922    #[inline]
923    fn min_value() -> Self {
924        Self::MIN
925    }
926
927    #[inline]
928    fn min_positive_value() -> Self {
929        Self::MIN_POSITIVE
930    }
931
932    #[inline]
933    fn epsilon() -> Self {
934        Self::EPSILON
935    }
936
937    #[inline]
938    fn max_value() -> Self {
939        Self::MAX
940    }
941
942    #[inline]
943    fn is_nan(self) -> bool {
944        self.is_nan()
945    }
946
947    #[inline]
948    fn is_infinite(self) -> bool {
949        self.is_infinite()
950    }
951
952    #[inline]
953    fn is_finite(self) -> bool {
954        self.is_finite()
955    }
956
957    #[inline]
958    fn is_normal(self) -> bool {
959        self.is_normal()
960    }
961
962    #[inline]
963    fn classify(self) -> FpCategory {
964        self.classify()
965    }
966
967    #[inline]
968    fn floor(self) -> Self {
969        Self::from_f32(self.to_f32().floor())
970    }
971
972    #[inline]
973    fn ceil(self) -> Self {
974        Self::from_f32(self.to_f32().ceil())
975    }
976
977    #[inline]
978    fn round(self) -> Self {
979        Self::from_f32(self.to_f32().round())
980    }
981
982    #[inline]
983    fn trunc(self) -> Self {
984        Self::from_f32(self.to_f32().trunc())
985    }
986
987    #[inline]
988    fn fract(self) -> Self {
989        Self::from_f32(self.to_f32().fract())
990    }
991
992    #[inline]
993    fn abs(self) -> Self {
994        Self::from_bits(self.to_bits() & 0x7FFF)
995    }
996
997    #[inline]
998    fn signum(self) -> Self {
999        self.signum()
1000    }
1001
1002    #[inline]
1003    fn is_sign_positive(self) -> bool {
1004        self.is_sign_positive()
1005    }
1006
1007    #[inline]
1008    fn is_sign_negative(self) -> bool {
1009        self.is_sign_negative()
1010    }
1011
1012    fn min(self, other: Self) -> Self {
1013        match self.partial_cmp(&other) {
1014            None => {
1015                if self.is_nan() {
1016                    other
1017                } else {
1018                    self
1019                }
1020            }
1021            Some(Ordering::Greater) | Some(Ordering::Equal) => other,
1022            Some(Ordering::Less) => self,
1023        }
1024    }
1025
1026    fn max(self, other: Self) -> Self {
1027        match self.partial_cmp(&other) {
1028            None => {
1029                if self.is_nan() {
1030                    other
1031                } else {
1032                    self
1033                }
1034            }
1035            Some(Ordering::Greater) | Some(Ordering::Equal) => self,
1036            Some(Ordering::Less) => other,
1037        }
1038    }
1039
1040    #[inline]
1041    fn recip(self) -> Self {
1042        Self::from_f32(self.to_f32().recip())
1043    }
1044
1045    #[inline]
1046    fn powi(self, exp: i32) -> Self {
1047        Self::from_f32(self.to_f32().powi(exp))
1048    }
1049
1050    #[inline]
1051    fn to_degrees(self) -> Self {
1052        Self::from_f32(self.to_f32().to_degrees())
1053    }
1054
1055    #[inline]
1056    fn to_radians(self) -> Self {
1057        Self::from_f32(self.to_f32().to_radians())
1058    }
1059
1060    #[inline]
1061    fn integer_decode(self) -> (u64, i16, i8) {
1062        num_traits::float::FloatCore::integer_decode(self.to_f32())
1063    }
1064}
1065
1066impl num_traits::float::Float for bf16 {
1067    #[inline]
1068    fn nan() -> Self {
1069        Self::NAN
1070    }
1071
1072    #[inline]
1073    fn infinity() -> Self {
1074        Self::INFINITY
1075    }
1076
1077    #[inline]
1078    fn neg_infinity() -> Self {
1079        Self::NEG_INFINITY
1080    }
1081
1082    #[inline]
1083    fn neg_zero() -> Self {
1084        Self::NEG_ZERO
1085    }
1086
1087    #[inline]
1088    fn min_value() -> Self {
1089        Self::MIN
1090    }
1091
1092    #[inline]
1093    fn min_positive_value() -> Self {
1094        Self::MIN_POSITIVE
1095    }
1096
1097    #[inline]
1098    fn epsilon() -> Self {
1099        Self::EPSILON
1100    }
1101
1102    #[inline]
1103    fn max_value() -> Self {
1104        Self::MAX
1105    }
1106
1107    #[inline]
1108    fn is_nan(self) -> bool {
1109        self.is_nan()
1110    }
1111
1112    #[inline]
1113    fn is_infinite(self) -> bool {
1114        self.is_infinite()
1115    }
1116
1117    #[inline]
1118    fn is_finite(self) -> bool {
1119        self.is_finite()
1120    }
1121
1122    #[inline]
1123    fn is_normal(self) -> bool {
1124        self.is_normal()
1125    }
1126
1127    #[inline]
1128    fn classify(self) -> FpCategory {
1129        self.classify()
1130    }
1131
1132    #[inline]
1133    fn floor(self) -> Self {
1134        Self::from_f32(self.to_f32().floor())
1135    }
1136
1137    #[inline]
1138    fn ceil(self) -> Self {
1139        Self::from_f32(self.to_f32().ceil())
1140    }
1141
1142    #[inline]
1143    fn round(self) -> Self {
1144        Self::from_f32(self.to_f32().round())
1145    }
1146
1147    #[inline]
1148    fn trunc(self) -> Self {
1149        Self::from_f32(self.to_f32().trunc())
1150    }
1151
1152    #[inline]
1153    fn fract(self) -> Self {
1154        Self::from_f32(self.to_f32().fract())
1155    }
1156
1157    #[inline]
1158    fn abs(self) -> Self {
1159        Self::from_f32(self.to_f32().abs())
1160    }
1161
1162    #[inline]
1163    fn signum(self) -> Self {
1164        Self::from_f32(self.to_f32().signum())
1165    }
1166
1167    #[inline]
1168    fn is_sign_positive(self) -> bool {
1169        self.is_sign_positive()
1170    }
1171
1172    #[inline]
1173    fn is_sign_negative(self) -> bool {
1174        self.is_sign_negative()
1175    }
1176
1177    #[inline]
1178    fn mul_add(self, a: Self, b: Self) -> Self {
1179        Self::from_f32(self.to_f32().mul_add(a.to_f32(), b.to_f32()))
1180    }
1181
1182    #[inline]
1183    fn recip(self) -> Self {
1184        Self::from_f32(self.to_f32().recip())
1185    }
1186
1187    #[inline]
1188    fn powi(self, n: i32) -> Self {
1189        Self::from_f32(self.to_f32().powi(n))
1190    }
1191
1192    #[inline]
1193    fn powf(self, n: Self) -> Self {
1194        Self::from_f32(self.to_f32().powf(n.to_f32()))
1195    }
1196
1197    #[inline]
1198    fn sqrt(self) -> Self {
1199        Self::from_f32(self.to_f32().sqrt())
1200    }
1201
1202    #[inline]
1203    fn exp(self) -> Self {
1204        Self::from_f32(self.to_f32().exp())
1205    }
1206
1207    #[inline]
1208    fn exp2(self) -> Self {
1209        Self::from_f32(self.to_f32().exp2())
1210    }
1211
1212    #[inline]
1213    fn ln(self) -> Self {
1214        Self::from_f32(self.to_f32().ln())
1215    }
1216
1217    #[inline]
1218    fn log(self, base: Self) -> Self {
1219        Self::from_f32(self.to_f32().log(base.to_f32()))
1220    }
1221
1222    #[inline]
1223    fn log2(self) -> Self {
1224        Self::from_f32(self.to_f32().log2())
1225    }
1226
1227    #[inline]
1228    fn log10(self) -> Self {
1229        Self::from_f32(self.to_f32().log10())
1230    }
1231
1232    #[inline]
1233    fn to_degrees(self) -> Self {
1234        Self::from_f32(self.to_f32().to_degrees())
1235    }
1236
1237    #[inline]
1238    fn to_radians(self) -> Self {
1239        Self::from_f32(self.to_f32().to_radians())
1240    }
1241
1242    #[inline]
1243    fn max(self, other: Self) -> Self {
1244        self.max(other)
1245    }
1246
1247    #[inline]
1248    fn min(self, other: Self) -> Self {
1249        self.min(other)
1250    }
1251
1252    #[inline]
1253    fn abs_sub(self, other: Self) -> Self {
1254        Self::from_f32((self.to_f32() - other.to_f32()).max(0.0))
1255    }
1256
1257    #[inline]
1258    fn cbrt(self) -> Self {
1259        Self::from_f32(self.to_f32().cbrt())
1260    }
1261
1262    #[inline]
1263    fn hypot(self, other: Self) -> Self {
1264        Self::from_f32(self.to_f32().hypot(other.to_f32()))
1265    }
1266
1267    #[inline]
1268    fn sin(self) -> Self {
1269        Self::from_f32(self.to_f32().sin())
1270    }
1271
1272    #[inline]
1273    fn cos(self) -> Self {
1274        Self::from_f32(self.to_f32().cos())
1275    }
1276
1277    #[inline]
1278    fn tan(self) -> Self {
1279        Self::from_f32(self.to_f32().tan())
1280    }
1281
1282    #[inline]
1283    fn asin(self) -> Self {
1284        Self::from_f32(self.to_f32().asin())
1285    }
1286
1287    #[inline]
1288    fn acos(self) -> Self {
1289        Self::from_f32(self.to_f32().acos())
1290    }
1291
1292    #[inline]
1293    fn atan(self) -> Self {
1294        Self::from_f32(self.to_f32().atan())
1295    }
1296
1297    #[inline]
1298    fn atan2(self, other: Self) -> Self {
1299        Self::from_f32(self.to_f32().atan2(other.to_f32()))
1300    }
1301
1302    #[inline]
1303    fn sin_cos(self) -> (Self, Self) {
1304        let (sin, cos) = self.to_f32().sin_cos();
1305        (Self::from_f32(sin), Self::from_f32(cos))
1306    }
1307
1308    #[inline]
1309    fn exp_m1(self) -> Self {
1310        Self::from_f32(self.to_f32().exp_m1())
1311    }
1312
1313    #[inline]
1314    fn ln_1p(self) -> Self {
1315        Self::from_f32(self.to_f32().ln_1p())
1316    }
1317
1318    #[inline]
1319    fn sinh(self) -> Self {
1320        Self::from_f32(self.to_f32().sinh())
1321    }
1322
1323    #[inline]
1324    fn cosh(self) -> Self {
1325        Self::from_f32(self.to_f32().cosh())
1326    }
1327
1328    #[inline]
1329    fn tanh(self) -> Self {
1330        Self::from_f32(self.to_f32().tanh())
1331    }
1332
1333    #[inline]
1334    fn asinh(self) -> Self {
1335        Self::from_f32(self.to_f32().asinh())
1336    }
1337
1338    #[inline]
1339    fn acosh(self) -> Self {
1340        Self::from_f32(self.to_f32().acosh())
1341    }
1342
1343    #[inline]
1344    fn atanh(self) -> Self {
1345        Self::from_f32(self.to_f32().atanh())
1346    }
1347
1348    #[inline]
1349    fn integer_decode(self) -> (u64, i16, i8) {
1350        num_traits::float::Float::integer_decode(self.to_f32())
1351    }
1352}
1353
1354impl FloatConst for bf16 {
1355    #[inline]
1356    fn E() -> Self {
1357        Self::E
1358    }
1359
1360    #[inline]
1361    fn FRAC_1_PI() -> Self {
1362        Self::FRAC_1_PI
1363    }
1364
1365    #[inline]
1366    fn FRAC_1_SQRT_2() -> Self {
1367        Self::FRAC_1_SQRT_2
1368    }
1369
1370    #[inline]
1371    fn FRAC_2_PI() -> Self {
1372        Self::FRAC_2_PI
1373    }
1374
1375    #[inline]
1376    fn FRAC_2_SQRT_PI() -> Self {
1377        Self::FRAC_2_SQRT_PI
1378    }
1379
1380    #[inline]
1381    fn FRAC_PI_2() -> Self {
1382        Self::FRAC_PI_2
1383    }
1384
1385    #[inline]
1386    fn FRAC_PI_3() -> Self {
1387        Self::FRAC_PI_3
1388    }
1389
1390    #[inline]
1391    fn FRAC_PI_4() -> Self {
1392        Self::FRAC_PI_4
1393    }
1394
1395    #[inline]
1396    fn FRAC_PI_6() -> Self {
1397        Self::FRAC_PI_6
1398    }
1399
1400    #[inline]
1401    fn FRAC_PI_8() -> Self {
1402        Self::FRAC_PI_8
1403    }
1404
1405    #[inline]
1406    fn LN_10() -> Self {
1407        Self::LN_10
1408    }
1409
1410    #[inline]
1411    fn LN_2() -> Self {
1412        Self::LN_2
1413    }
1414
1415    #[inline]
1416    fn LOG10_E() -> Self {
1417        Self::LOG10_E
1418    }
1419
1420    #[inline]
1421    fn LOG2_E() -> Self {
1422        Self::LOG2_E
1423    }
1424
1425    #[inline]
1426    fn PI() -> Self {
1427        Self::PI
1428    }
1429
1430    #[inline]
1431    fn SQRT_2() -> Self {
1432        Self::SQRT_2
1433    }
1434
1435    #[inline]
1436    fn LOG10_2() -> Self
1437    where
1438        Self: Sized + Div<Self, Output = Self>,
1439    {
1440        Self::LOG10_2
1441    }
1442
1443    #[inline]
1444    fn LOG2_10() -> Self
1445    where
1446        Self: Sized + Div<Self, Output = Self>,
1447    {
1448        Self::LOG2_10
1449    }
1450}
1451
1452impl Bounded for bf16 {
1453    #[inline]
1454    fn min_value() -> Self {
1455        bf16::MIN
1456    }
1457
1458    #[inline]
1459    fn max_value() -> Self {
1460        bf16::MAX
1461    }
1462}
1463
1464impl AsPrimitive<bf16> for bf16 {
1465    #[inline]
1466    fn as_(self) -> bf16 {
1467        self
1468    }
1469}
1470
1471macro_rules! impl_as_primitive_to_bf16 {
1472    ($ty:ty, $meth:ident) => {
1473        impl AsPrimitive<$ty> for bf16 {
1474            #[inline]
1475            fn as_(self) -> $ty {
1476                self.$meth().as_()
1477            }
1478        }
1479    };
1480}
1481
1482impl_as_primitive_to_bf16!(i64, to_f32);
1483impl_as_primitive_to_bf16!(u64, to_f32);
1484impl_as_primitive_to_bf16!(i8, to_f32);
1485impl_as_primitive_to_bf16!(u8, to_f32);
1486impl_as_primitive_to_bf16!(i16, to_f32);
1487impl_as_primitive_to_bf16!(u16, to_f32);
1488impl_as_primitive_to_bf16!(i32, to_f32);
1489impl_as_primitive_to_bf16!(u32, to_f32);
1490impl_as_primitive_to_bf16!(isize, to_f32);
1491impl_as_primitive_to_bf16!(usize, to_f32);
1492impl_as_primitive_to_bf16!(f32, to_f32);
1493impl_as_primitive_to_bf16!(f64, to_f64);
1494impl_as_primitive_to_bf16!(f16, to_f32);
1495
1496macro_rules! impl_as_primitive_bf16_from {
1497    ($ty:ty, $meth:ident) => {
1498        impl AsPrimitive<bf16> for $ty {
1499            #[inline]
1500            fn as_(self) -> bf16 {
1501                bf16::$meth(self.as_())
1502            }
1503        }
1504    };
1505}
1506
1507impl_as_primitive_bf16_from!(i64, from_f32);
1508impl_as_primitive_bf16_from!(u64, from_f32);
1509impl_as_primitive_bf16_from!(i8, from_f32);
1510impl_as_primitive_bf16_from!(u8, from_f32);
1511impl_as_primitive_bf16_from!(i16, from_f32);
1512impl_as_primitive_bf16_from!(u16, from_f32);
1513impl_as_primitive_bf16_from!(i32, from_f32);
1514impl_as_primitive_bf16_from!(u32, from_f32);
1515impl_as_primitive_bf16_from!(isize, from_f32);
1516impl_as_primitive_bf16_from!(usize, from_f32);
1517impl_as_primitive_bf16_from!(f32, from_f32);
1518impl_as_primitive_bf16_from!(f64, from_f64);
1519
1520impl ToBytes for bf16 {
1521    type Bytes = [u8; 2];
1522
1523    fn to_be_bytes(&self) -> Self::Bytes {
1524        Self::to_be_bytes(*self)
1525    }
1526
1527    fn to_le_bytes(&self) -> Self::Bytes {
1528        Self::to_le_bytes(*self)
1529    }
1530
1531    fn to_ne_bytes(&self) -> Self::Bytes {
1532        Self::to_ne_bytes(*self)
1533    }
1534}
1535
1536impl FromBytes for bf16 {
1537    type Bytes = [u8; 2];
1538
1539    fn from_be_bytes(bytes: &Self::Bytes) -> Self {
1540        Self::from_be_bytes(*bytes)
1541    }
1542
1543    fn from_le_bytes(bytes: &Self::Bytes) -> Self {
1544        Self::from_le_bytes(*bytes)
1545    }
1546
1547    fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
1548        Self::from_ne_bytes(*bytes)
1549    }
1550}