1 use crate::{bf16, f16};
2 use core::cmp::Ordering;
3 use core::{num::FpCategory, ops::Div};
4 use num_traits::{
5     AsPrimitive, Bounded, FloatConst, FromPrimitive, Num, NumCast, One, ToPrimitive, Zero,
6 };
7 
8 impl ToPrimitive for f16 {
9     #[inline]
to_i64(&self) -> Option<i64>10     fn to_i64(&self) -> Option<i64> {
11         Self::to_f32(*self).to_i64()
12     }
13     #[inline]
to_u64(&self) -> Option<u64>14     fn to_u64(&self) -> Option<u64> {
15         Self::to_f32(*self).to_u64()
16     }
17     #[inline]
to_i8(&self) -> Option<i8>18     fn to_i8(&self) -> Option<i8> {
19         Self::to_f32(*self).to_i8()
20     }
21     #[inline]
to_u8(&self) -> Option<u8>22     fn to_u8(&self) -> Option<u8> {
23         Self::to_f32(*self).to_u8()
24     }
25     #[inline]
to_i16(&self) -> Option<i16>26     fn to_i16(&self) -> Option<i16> {
27         Self::to_f32(*self).to_i16()
28     }
29     #[inline]
to_u16(&self) -> Option<u16>30     fn to_u16(&self) -> Option<u16> {
31         Self::to_f32(*self).to_u16()
32     }
33     #[inline]
to_i32(&self) -> Option<i32>34     fn to_i32(&self) -> Option<i32> {
35         Self::to_f32(*self).to_i32()
36     }
37     #[inline]
to_u32(&self) -> Option<u32>38     fn to_u32(&self) -> Option<u32> {
39         Self::to_f32(*self).to_u32()
40     }
41     #[inline]
to_f32(&self) -> Option<f32>42     fn to_f32(&self) -> Option<f32> {
43         Some(Self::to_f32(*self))
44     }
45     #[inline]
to_f64(&self) -> Option<f64>46     fn to_f64(&self) -> Option<f64> {
47         Some(Self::to_f64(*self))
48     }
49 }
50 
51 impl FromPrimitive for f16 {
52     #[inline]
from_i64(n: i64) -> Option<Self>53     fn from_i64(n: i64) -> Option<Self> {
54         n.to_f32().map(Self::from_f32)
55     }
56     #[inline]
from_u64(n: u64) -> Option<Self>57     fn from_u64(n: u64) -> Option<Self> {
58         n.to_f32().map(Self::from_f32)
59     }
60     #[inline]
from_i8(n: i8) -> Option<Self>61     fn from_i8(n: i8) -> Option<Self> {
62         n.to_f32().map(Self::from_f32)
63     }
64     #[inline]
from_u8(n: u8) -> Option<Self>65     fn from_u8(n: u8) -> Option<Self> {
66         n.to_f32().map(Self::from_f32)
67     }
68     #[inline]
from_i16(n: i16) -> Option<Self>69     fn from_i16(n: i16) -> Option<Self> {
70         n.to_f32().map(Self::from_f32)
71     }
72     #[inline]
from_u16(n: u16) -> Option<Self>73     fn from_u16(n: u16) -> Option<Self> {
74         n.to_f32().map(Self::from_f32)
75     }
76     #[inline]
from_i32(n: i32) -> Option<Self>77     fn from_i32(n: i32) -> Option<Self> {
78         n.to_f32().map(Self::from_f32)
79     }
80     #[inline]
from_u32(n: u32) -> Option<Self>81     fn from_u32(n: u32) -> Option<Self> {
82         n.to_f32().map(Self::from_f32)
83     }
84     #[inline]
from_f32(n: f32) -> Option<Self>85     fn from_f32(n: f32) -> Option<Self> {
86         n.to_f32().map(Self::from_f32)
87     }
88     #[inline]
from_f64(n: f64) -> Option<Self>89     fn from_f64(n: f64) -> Option<Self> {
90         n.to_f64().map(Self::from_f64)
91     }
92 }
93 
94 impl Num for f16 {
95     type FromStrRadixErr = <f32 as Num>::FromStrRadixErr;
96 
97     #[inline]
from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr>98     fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
99         Ok(Self::from_f32(f32::from_str_radix(str, radix)?))
100     }
101 }
102 
103 impl One for f16 {
104     #[inline]
one() -> Self105     fn one() -> Self {
106         Self::ONE
107     }
108 }
109 
110 impl Zero for f16 {
111     #[inline]
zero() -> Self112     fn zero() -> Self {
113         Self::ZERO
114     }
115 
116     #[inline]
is_zero(&self) -> bool117     fn is_zero(&self) -> bool {
118         *self == Self::ZERO
119     }
120 }
121 
122 impl NumCast for f16 {
123     #[inline]
from<T: ToPrimitive>(n: T) -> Option<Self>124     fn from<T: ToPrimitive>(n: T) -> Option<Self> {
125         n.to_f32().map(Self::from_f32)
126     }
127 }
128 
129 impl num_traits::float::FloatCore for f16 {
130     #[inline]
infinity() -> Self131     fn infinity() -> Self {
132         Self::INFINITY
133     }
134 
135     #[inline]
neg_infinity() -> Self136     fn neg_infinity() -> Self {
137         Self::NEG_INFINITY
138     }
139 
140     #[inline]
nan() -> Self141     fn nan() -> Self {
142         Self::NAN
143     }
144 
145     #[inline]
neg_zero() -> Self146     fn neg_zero() -> Self {
147         Self::NEG_ZERO
148     }
149 
150     #[inline]
min_value() -> Self151     fn min_value() -> Self {
152         Self::MIN
153     }
154 
155     #[inline]
min_positive_value() -> Self156     fn min_positive_value() -> Self {
157         Self::MIN_POSITIVE
158     }
159 
160     #[inline]
epsilon() -> Self161     fn epsilon() -> Self {
162         Self::EPSILON
163     }
164 
165     #[inline]
max_value() -> Self166     fn max_value() -> Self {
167         Self::MAX
168     }
169 
170     #[inline]
is_nan(self) -> bool171     fn is_nan(self) -> bool {
172         self.is_nan()
173     }
174 
175     #[inline]
is_infinite(self) -> bool176     fn is_infinite(self) -> bool {
177         self.is_infinite()
178     }
179 
180     #[inline]
is_finite(self) -> bool181     fn is_finite(self) -> bool {
182         self.is_finite()
183     }
184 
185     #[inline]
is_normal(self) -> bool186     fn is_normal(self) -> bool {
187         self.is_normal()
188     }
189 
190     #[inline]
classify(self) -> FpCategory191     fn classify(self) -> FpCategory {
192         self.classify()
193     }
194 
195     #[inline]
floor(self) -> Self196     fn floor(self) -> Self {
197         Self::from_f32(self.to_f32().floor())
198     }
199 
200     #[inline]
ceil(self) -> Self201     fn ceil(self) -> Self {
202         Self::from_f32(self.to_f32().ceil())
203     }
204 
205     #[inline]
round(self) -> Self206     fn round(self) -> Self {
207         Self::from_f32(self.to_f32().round())
208     }
209 
210     #[inline]
trunc(self) -> Self211     fn trunc(self) -> Self {
212         Self::from_f32(self.to_f32().trunc())
213     }
214 
215     #[inline]
fract(self) -> Self216     fn fract(self) -> Self {
217         Self::from_f32(self.to_f32().fract())
218     }
219 
220     #[inline]
abs(self) -> Self221     fn abs(self) -> Self {
222         Self::from_bits(self.to_bits() & 0x7FFF)
223     }
224 
225     #[inline]
signum(self) -> Self226     fn signum(self) -> Self {
227         self.signum()
228     }
229 
230     #[inline]
is_sign_positive(self) -> bool231     fn is_sign_positive(self) -> bool {
232         self.is_sign_positive()
233     }
234 
235     #[inline]
is_sign_negative(self) -> bool236     fn is_sign_negative(self) -> bool {
237         self.is_sign_negative()
238     }
239 
min(self, other: Self) -> Self240     fn min(self, other: Self) -> Self {
241         match self.partial_cmp(&other) {
242             None => {
243                 if self.is_nan() {
244                     other
245                 } else {
246                     self
247                 }
248             }
249             Some(Ordering::Greater) | Some(Ordering::Equal) => other,
250             Some(Ordering::Less) => self,
251         }
252     }
253 
max(self, other: Self) -> Self254     fn max(self, other: Self) -> Self {
255         match self.partial_cmp(&other) {
256             None => {
257                 if self.is_nan() {
258                     other
259                 } else {
260                     self
261                 }
262             }
263             Some(Ordering::Greater) | Some(Ordering::Equal) => self,
264             Some(Ordering::Less) => other,
265         }
266     }
267 
268     #[inline]
recip(self) -> Self269     fn recip(self) -> Self {
270         Self::from_f32(self.to_f32().recip())
271     }
272 
273     #[inline]
powi(self, exp: i32) -> Self274     fn powi(self, exp: i32) -> Self {
275         Self::from_f32(self.to_f32().powi(exp))
276     }
277 
278     #[inline]
to_degrees(self) -> Self279     fn to_degrees(self) -> Self {
280         Self::from_f32(self.to_f32().to_degrees())
281     }
282 
283     #[inline]
to_radians(self) -> Self284     fn to_radians(self) -> Self {
285         Self::from_f32(self.to_f32().to_radians())
286     }
287 
288     #[inline]
integer_decode(self) -> (u64, i16, i8)289     fn integer_decode(self) -> (u64, i16, i8) {
290         num_traits::float::FloatCore::integer_decode(self.to_f32())
291     }
292 }
293 
294 impl num_traits::float::Float for f16 {
295     #[inline]
nan() -> Self296     fn nan() -> Self {
297         Self::NAN
298     }
299 
300     #[inline]
infinity() -> Self301     fn infinity() -> Self {
302         Self::INFINITY
303     }
304 
305     #[inline]
neg_infinity() -> Self306     fn neg_infinity() -> Self {
307         Self::NEG_INFINITY
308     }
309 
310     #[inline]
neg_zero() -> Self311     fn neg_zero() -> Self {
312         Self::NEG_ZERO
313     }
314 
315     #[inline]
min_value() -> Self316     fn min_value() -> Self {
317         Self::MIN
318     }
319 
320     #[inline]
min_positive_value() -> Self321     fn min_positive_value() -> Self {
322         Self::MIN_POSITIVE
323     }
324 
325     #[inline]
epsilon() -> Self326     fn epsilon() -> Self {
327         Self::EPSILON
328     }
329 
330     #[inline]
max_value() -> Self331     fn max_value() -> Self {
332         Self::MAX
333     }
334 
335     #[inline]
is_nan(self) -> bool336     fn is_nan(self) -> bool {
337         self.is_nan()
338     }
339 
340     #[inline]
is_infinite(self) -> bool341     fn is_infinite(self) -> bool {
342         self.is_infinite()
343     }
344 
345     #[inline]
is_finite(self) -> bool346     fn is_finite(self) -> bool {
347         self.is_finite()
348     }
349 
350     #[inline]
is_normal(self) -> bool351     fn is_normal(self) -> bool {
352         self.is_normal()
353     }
354 
355     #[inline]
classify(self) -> FpCategory356     fn classify(self) -> FpCategory {
357         self.classify()
358     }
359 
360     #[inline]
floor(self) -> Self361     fn floor(self) -> Self {
362         Self::from_f32(self.to_f32().floor())
363     }
364 
365     #[inline]
ceil(self) -> Self366     fn ceil(self) -> Self {
367         Self::from_f32(self.to_f32().ceil())
368     }
369 
370     #[inline]
round(self) -> Self371     fn round(self) -> Self {
372         Self::from_f32(self.to_f32().round())
373     }
374 
375     #[inline]
trunc(self) -> Self376     fn trunc(self) -> Self {
377         Self::from_f32(self.to_f32().trunc())
378     }
379 
380     #[inline]
fract(self) -> Self381     fn fract(self) -> Self {
382         Self::from_f32(self.to_f32().fract())
383     }
384 
385     #[inline]
abs(self) -> Self386     fn abs(self) -> Self {
387         Self::from_f32(self.to_f32().abs())
388     }
389 
390     #[inline]
signum(self) -> Self391     fn signum(self) -> Self {
392         Self::from_f32(self.to_f32().signum())
393     }
394 
395     #[inline]
is_sign_positive(self) -> bool396     fn is_sign_positive(self) -> bool {
397         self.is_sign_positive()
398     }
399 
400     #[inline]
is_sign_negative(self) -> bool401     fn is_sign_negative(self) -> bool {
402         self.is_sign_negative()
403     }
404 
405     #[inline]
mul_add(self, a: Self, b: Self) -> Self406     fn mul_add(self, a: Self, b: Self) -> Self {
407         Self::from_f32(self.to_f32().mul_add(a.to_f32(), b.to_f32()))
408     }
409 
410     #[inline]
recip(self) -> Self411     fn recip(self) -> Self {
412         Self::from_f32(self.to_f32().recip())
413     }
414 
415     #[inline]
powi(self, n: i32) -> Self416     fn powi(self, n: i32) -> Self {
417         Self::from_f32(self.to_f32().powi(n))
418     }
419 
420     #[inline]
powf(self, n: Self) -> Self421     fn powf(self, n: Self) -> Self {
422         Self::from_f32(self.to_f32().powf(n.to_f32()))
423     }
424 
425     #[inline]
sqrt(self) -> Self426     fn sqrt(self) -> Self {
427         Self::from_f32(self.to_f32().sqrt())
428     }
429 
430     #[inline]
exp(self) -> Self431     fn exp(self) -> Self {
432         Self::from_f32(self.to_f32().exp())
433     }
434 
435     #[inline]
exp2(self) -> Self436     fn exp2(self) -> Self {
437         Self::from_f32(self.to_f32().exp2())
438     }
439 
440     #[inline]
ln(self) -> Self441     fn ln(self) -> Self {
442         Self::from_f32(self.to_f32().ln())
443     }
444 
445     #[inline]
log(self, base: Self) -> Self446     fn log(self, base: Self) -> Self {
447         Self::from_f32(self.to_f32().log(base.to_f32()))
448     }
449 
450     #[inline]
log2(self) -> Self451     fn log2(self) -> Self {
452         Self::from_f32(self.to_f32().log2())
453     }
454 
455     #[inline]
log10(self) -> Self456     fn log10(self) -> Self {
457         Self::from_f32(self.to_f32().log10())
458     }
459 
460     #[inline]
to_degrees(self) -> Self461     fn to_degrees(self) -> Self {
462         Self::from_f32(self.to_f32().to_degrees())
463     }
464 
465     #[inline]
to_radians(self) -> Self466     fn to_radians(self) -> Self {
467         Self::from_f32(self.to_f32().to_radians())
468     }
469 
470     #[inline]
max(self, other: Self) -> Self471     fn max(self, other: Self) -> Self {
472         self.max(other)
473     }
474 
475     #[inline]
min(self, other: Self) -> Self476     fn min(self, other: Self) -> Self {
477         self.min(other)
478     }
479 
480     #[inline]
abs_sub(self, other: Self) -> Self481     fn abs_sub(self, other: Self) -> Self {
482         Self::from_f32((self.to_f32() - other.to_f32()).max(0.0))
483     }
484 
485     #[inline]
cbrt(self) -> Self486     fn cbrt(self) -> Self {
487         Self::from_f32(self.to_f32().cbrt())
488     }
489 
490     #[inline]
hypot(self, other: Self) -> Self491     fn hypot(self, other: Self) -> Self {
492         Self::from_f32(self.to_f32().hypot(other.to_f32()))
493     }
494 
495     #[inline]
sin(self) -> Self496     fn sin(self) -> Self {
497         Self::from_f32(self.to_f32().sin())
498     }
499 
500     #[inline]
cos(self) -> Self501     fn cos(self) -> Self {
502         Self::from_f32(self.to_f32().cos())
503     }
504 
505     #[inline]
tan(self) -> Self506     fn tan(self) -> Self {
507         Self::from_f32(self.to_f32().tan())
508     }
509 
510     #[inline]
asin(self) -> Self511     fn asin(self) -> Self {
512         Self::from_f32(self.to_f32().asin())
513     }
514 
515     #[inline]
acos(self) -> Self516     fn acos(self) -> Self {
517         Self::from_f32(self.to_f32().acos())
518     }
519 
520     #[inline]
atan(self) -> Self521     fn atan(self) -> Self {
522         Self::from_f32(self.to_f32().atan())
523     }
524 
525     #[inline]
atan2(self, other: Self) -> Self526     fn atan2(self, other: Self) -> Self {
527         Self::from_f32(self.to_f32().atan2(other.to_f32()))
528     }
529 
530     #[inline]
sin_cos(self) -> (Self, Self)531     fn sin_cos(self) -> (Self, Self) {
532         let (sin, cos) = self.to_f32().sin_cos();
533         (Self::from_f32(sin), Self::from_f32(cos))
534     }
535 
536     #[inline]
exp_m1(self) -> Self537     fn exp_m1(self) -> Self {
538         Self::from_f32(self.to_f32().exp_m1())
539     }
540 
541     #[inline]
ln_1p(self) -> Self542     fn ln_1p(self) -> Self {
543         Self::from_f32(self.to_f32().ln_1p())
544     }
545 
546     #[inline]
sinh(self) -> Self547     fn sinh(self) -> Self {
548         Self::from_f32(self.to_f32().sinh())
549     }
550 
551     #[inline]
cosh(self) -> Self552     fn cosh(self) -> Self {
553         Self::from_f32(self.to_f32().cosh())
554     }
555 
556     #[inline]
tanh(self) -> Self557     fn tanh(self) -> Self {
558         Self::from_f32(self.to_f32().tanh())
559     }
560 
561     #[inline]
asinh(self) -> Self562     fn asinh(self) -> Self {
563         Self::from_f32(self.to_f32().asinh())
564     }
565 
566     #[inline]
acosh(self) -> Self567     fn acosh(self) -> Self {
568         Self::from_f32(self.to_f32().acosh())
569     }
570 
571     #[inline]
atanh(self) -> Self572     fn atanh(self) -> Self {
573         Self::from_f32(self.to_f32().atanh())
574     }
575 
576     #[inline]
integer_decode(self) -> (u64, i16, i8)577     fn integer_decode(self) -> (u64, i16, i8) {
578         num_traits::float::Float::integer_decode(self.to_f32())
579     }
580 }
581 
582 impl FloatConst for f16 {
583     #[inline]
E() -> Self584     fn E() -> Self {
585         Self::E
586     }
587 
588     #[inline]
FRAC_1_PI() -> Self589     fn FRAC_1_PI() -> Self {
590         Self::FRAC_1_PI
591     }
592 
593     #[inline]
FRAC_1_SQRT_2() -> Self594     fn FRAC_1_SQRT_2() -> Self {
595         Self::FRAC_1_SQRT_2
596     }
597 
598     #[inline]
FRAC_2_PI() -> Self599     fn FRAC_2_PI() -> Self {
600         Self::FRAC_2_PI
601     }
602 
603     #[inline]
FRAC_2_SQRT_PI() -> Self604     fn FRAC_2_SQRT_PI() -> Self {
605         Self::FRAC_2_SQRT_PI
606     }
607 
608     #[inline]
FRAC_PI_2() -> Self609     fn FRAC_PI_2() -> Self {
610         Self::FRAC_PI_2
611     }
612 
613     #[inline]
FRAC_PI_3() -> Self614     fn FRAC_PI_3() -> Self {
615         Self::FRAC_PI_3
616     }
617 
618     #[inline]
FRAC_PI_4() -> Self619     fn FRAC_PI_4() -> Self {
620         Self::FRAC_PI_4
621     }
622 
623     #[inline]
FRAC_PI_6() -> Self624     fn FRAC_PI_6() -> Self {
625         Self::FRAC_PI_6
626     }
627 
628     #[inline]
FRAC_PI_8() -> Self629     fn FRAC_PI_8() -> Self {
630         Self::FRAC_PI_8
631     }
632 
633     #[inline]
LN_10() -> Self634     fn LN_10() -> Self {
635         Self::LN_10
636     }
637 
638     #[inline]
LN_2() -> Self639     fn LN_2() -> Self {
640         Self::LN_2
641     }
642 
643     #[inline]
LOG10_E() -> Self644     fn LOG10_E() -> Self {
645         Self::LOG10_E
646     }
647 
648     #[inline]
LOG2_E() -> Self649     fn LOG2_E() -> Self {
650         Self::LOG2_E
651     }
652 
653     #[inline]
PI() -> Self654     fn PI() -> Self {
655         Self::PI
656     }
657 
SQRT_2() -> Self658     fn SQRT_2() -> Self {
659         Self::SQRT_2
660     }
661 
662     #[inline]
LOG10_2() -> Self where Self: Sized + Div<Self, Output = Self>,663     fn LOG10_2() -> Self
664     where
665         Self: Sized + Div<Self, Output = Self>,
666     {
667         Self::LOG10_2
668     }
669 
670     #[inline]
LOG2_10() -> Self where Self: Sized + Div<Self, Output = Self>,671     fn LOG2_10() -> Self
672     where
673         Self: Sized + Div<Self, Output = Self>,
674     {
675         Self::LOG2_10
676     }
677 }
678 
679 impl Bounded for f16 {
680     #[inline]
min_value() -> Self681     fn min_value() -> Self {
682         f16::MIN
683     }
684 
685     #[inline]
max_value() -> Self686     fn max_value() -> Self {
687         f16::MAX
688     }
689 }
690 
691 macro_rules! impl_as_primitive_to_f16 {
692     ($ty:ty, $meth:ident) => {
693         impl AsPrimitive<$ty> for f16 {
694             #[inline]
695             fn as_(self) -> $ty {
696                 self.$meth().as_()
697             }
698         }
699     };
700 }
701 
702 impl AsPrimitive<f16> for f16 {
703     #[inline]
as_(self) -> f16704     fn as_(self) -> f16 {
705         self
706     }
707 }
708 
709 impl_as_primitive_to_f16!(i64, to_f32);
710 impl_as_primitive_to_f16!(u64, to_f32);
711 impl_as_primitive_to_f16!(i8, to_f32);
712 impl_as_primitive_to_f16!(u8, to_f32);
713 impl_as_primitive_to_f16!(i16, to_f32);
714 impl_as_primitive_to_f16!(u16, to_f32);
715 impl_as_primitive_to_f16!(i32, to_f32);
716 impl_as_primitive_to_f16!(u32, to_f32);
717 impl_as_primitive_to_f16!(isize, to_f32);
718 impl_as_primitive_to_f16!(usize, to_f32);
719 impl_as_primitive_to_f16!(f32, to_f32);
720 impl_as_primitive_to_f16!(f64, to_f64);
721 
722 macro_rules! impl_as_primitive_f16_from {
723     ($ty:ty, $meth:ident) => {
724         impl AsPrimitive<f16> for $ty {
725             #[inline]
726             fn as_(self) -> f16 {
727                 f16::$meth(self.as_())
728             }
729         }
730     };
731 }
732 
733 impl_as_primitive_f16_from!(i64, from_f32);
734 impl_as_primitive_f16_from!(u64, from_f32);
735 impl_as_primitive_f16_from!(i8, from_f32);
736 impl_as_primitive_f16_from!(u8, from_f32);
737 impl_as_primitive_f16_from!(i16, from_f32);
738 impl_as_primitive_f16_from!(u16, from_f32);
739 impl_as_primitive_f16_from!(i32, from_f32);
740 impl_as_primitive_f16_from!(u32, from_f32);
741 impl_as_primitive_f16_from!(isize, from_f32);
742 impl_as_primitive_f16_from!(usize, from_f32);
743 impl_as_primitive_f16_from!(f32, from_f32);
744 impl_as_primitive_f16_from!(f64, from_f64);
745 
746 impl ToPrimitive for bf16 {
747     #[inline]
to_i64(&self) -> Option<i64>748     fn to_i64(&self) -> Option<i64> {
749         Self::to_f32(*self).to_i64()
750     }
751     #[inline]
to_u64(&self) -> Option<u64>752     fn to_u64(&self) -> Option<u64> {
753         Self::to_f32(*self).to_u64()
754     }
755     #[inline]
to_i8(&self) -> Option<i8>756     fn to_i8(&self) -> Option<i8> {
757         Self::to_f32(*self).to_i8()
758     }
759     #[inline]
to_u8(&self) -> Option<u8>760     fn to_u8(&self) -> Option<u8> {
761         Self::to_f32(*self).to_u8()
762     }
763     #[inline]
to_i16(&self) -> Option<i16>764     fn to_i16(&self) -> Option<i16> {
765         Self::to_f32(*self).to_i16()
766     }
767     #[inline]
to_u16(&self) -> Option<u16>768     fn to_u16(&self) -> Option<u16> {
769         Self::to_f32(*self).to_u16()
770     }
771     #[inline]
to_i32(&self) -> Option<i32>772     fn to_i32(&self) -> Option<i32> {
773         Self::to_f32(*self).to_i32()
774     }
775     #[inline]
to_u32(&self) -> Option<u32>776     fn to_u32(&self) -> Option<u32> {
777         Self::to_f32(*self).to_u32()
778     }
779     #[inline]
to_f32(&self) -> Option<f32>780     fn to_f32(&self) -> Option<f32> {
781         Some(Self::to_f32(*self))
782     }
783     #[inline]
to_f64(&self) -> Option<f64>784     fn to_f64(&self) -> Option<f64> {
785         Some(Self::to_f64(*self))
786     }
787 }
788 
789 impl FromPrimitive for bf16 {
790     #[inline]
from_i64(n: i64) -> Option<Self>791     fn from_i64(n: i64) -> Option<Self> {
792         n.to_f32().map(Self::from_f32)
793     }
794     #[inline]
from_u64(n: u64) -> Option<Self>795     fn from_u64(n: u64) -> Option<Self> {
796         n.to_f32().map(Self::from_f32)
797     }
798     #[inline]
from_i8(n: i8) -> Option<Self>799     fn from_i8(n: i8) -> Option<Self> {
800         n.to_f32().map(Self::from_f32)
801     }
802     #[inline]
from_u8(n: u8) -> Option<Self>803     fn from_u8(n: u8) -> Option<Self> {
804         n.to_f32().map(Self::from_f32)
805     }
806     #[inline]
from_i16(n: i16) -> Option<Self>807     fn from_i16(n: i16) -> Option<Self> {
808         n.to_f32().map(Self::from_f32)
809     }
810     #[inline]
from_u16(n: u16) -> Option<Self>811     fn from_u16(n: u16) -> Option<Self> {
812         n.to_f32().map(Self::from_f32)
813     }
814     #[inline]
from_i32(n: i32) -> Option<Self>815     fn from_i32(n: i32) -> Option<Self> {
816         n.to_f32().map(Self::from_f32)
817     }
818     #[inline]
from_u32(n: u32) -> Option<Self>819     fn from_u32(n: u32) -> Option<Self> {
820         n.to_f32().map(Self::from_f32)
821     }
822     #[inline]
from_f32(n: f32) -> Option<Self>823     fn from_f32(n: f32) -> Option<Self> {
824         n.to_f32().map(Self::from_f32)
825     }
826     #[inline]
from_f64(n: f64) -> Option<Self>827     fn from_f64(n: f64) -> Option<Self> {
828         n.to_f64().map(Self::from_f64)
829     }
830 }
831 
832 impl Num for bf16 {
833     type FromStrRadixErr = <f32 as Num>::FromStrRadixErr;
834 
835     #[inline]
from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr>836     fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
837         Ok(Self::from_f32(f32::from_str_radix(str, radix)?))
838     }
839 }
840 
841 impl One for bf16 {
842     #[inline]
one() -> Self843     fn one() -> Self {
844         Self::ONE
845     }
846 }
847 
848 impl Zero for bf16 {
849     #[inline]
zero() -> Self850     fn zero() -> Self {
851         Self::ZERO
852     }
853 
854     #[inline]
is_zero(&self) -> bool855     fn is_zero(&self) -> bool {
856         *self == Self::ZERO
857     }
858 }
859 
860 impl NumCast for bf16 {
861     #[inline]
from<T: ToPrimitive>(n: T) -> Option<Self>862     fn from<T: ToPrimitive>(n: T) -> Option<Self> {
863         n.to_f32().map(Self::from_f32)
864     }
865 }
866 
867 impl num_traits::float::FloatCore for bf16 {
868     #[inline]
infinity() -> Self869     fn infinity() -> Self {
870         Self::INFINITY
871     }
872 
873     #[inline]
neg_infinity() -> Self874     fn neg_infinity() -> Self {
875         Self::NEG_INFINITY
876     }
877 
878     #[inline]
nan() -> Self879     fn nan() -> Self {
880         Self::NAN
881     }
882 
883     #[inline]
neg_zero() -> Self884     fn neg_zero() -> Self {
885         Self::NEG_ZERO
886     }
887 
888     #[inline]
min_value() -> Self889     fn min_value() -> Self {
890         Self::MIN
891     }
892 
893     #[inline]
min_positive_value() -> Self894     fn min_positive_value() -> Self {
895         Self::MIN_POSITIVE
896     }
897 
898     #[inline]
epsilon() -> Self899     fn epsilon() -> Self {
900         Self::EPSILON
901     }
902 
903     #[inline]
max_value() -> Self904     fn max_value() -> Self {
905         Self::MAX
906     }
907 
908     #[inline]
is_nan(self) -> bool909     fn is_nan(self) -> bool {
910         self.is_nan()
911     }
912 
913     #[inline]
is_infinite(self) -> bool914     fn is_infinite(self) -> bool {
915         self.is_infinite()
916     }
917 
918     #[inline]
is_finite(self) -> bool919     fn is_finite(self) -> bool {
920         self.is_finite()
921     }
922 
923     #[inline]
is_normal(self) -> bool924     fn is_normal(self) -> bool {
925         self.is_normal()
926     }
927 
928     #[inline]
classify(self) -> FpCategory929     fn classify(self) -> FpCategory {
930         self.classify()
931     }
932 
933     #[inline]
floor(self) -> Self934     fn floor(self) -> Self {
935         Self::from_f32(self.to_f32().floor())
936     }
937 
938     #[inline]
ceil(self) -> Self939     fn ceil(self) -> Self {
940         Self::from_f32(self.to_f32().ceil())
941     }
942 
943     #[inline]
round(self) -> Self944     fn round(self) -> Self {
945         Self::from_f32(self.to_f32().round())
946     }
947 
948     #[inline]
trunc(self) -> Self949     fn trunc(self) -> Self {
950         Self::from_f32(self.to_f32().trunc())
951     }
952 
953     #[inline]
fract(self) -> Self954     fn fract(self) -> Self {
955         Self::from_f32(self.to_f32().fract())
956     }
957 
958     #[inline]
abs(self) -> Self959     fn abs(self) -> Self {
960         Self::from_bits(self.to_bits() & 0x7FFF)
961     }
962 
963     #[inline]
signum(self) -> Self964     fn signum(self) -> Self {
965         self.signum()
966     }
967 
968     #[inline]
is_sign_positive(self) -> bool969     fn is_sign_positive(self) -> bool {
970         self.is_sign_positive()
971     }
972 
973     #[inline]
is_sign_negative(self) -> bool974     fn is_sign_negative(self) -> bool {
975         self.is_sign_negative()
976     }
977 
min(self, other: Self) -> Self978     fn min(self, other: Self) -> Self {
979         match self.partial_cmp(&other) {
980             None => {
981                 if self.is_nan() {
982                     other
983                 } else {
984                     self
985                 }
986             }
987             Some(Ordering::Greater) | Some(Ordering::Equal) => other,
988             Some(Ordering::Less) => self,
989         }
990     }
991 
max(self, other: Self) -> Self992     fn max(self, other: Self) -> Self {
993         match self.partial_cmp(&other) {
994             None => {
995                 if self.is_nan() {
996                     other
997                 } else {
998                     self
999                 }
1000             }
1001             Some(Ordering::Greater) | Some(Ordering::Equal) => self,
1002             Some(Ordering::Less) => other,
1003         }
1004     }
1005 
1006     #[inline]
recip(self) -> Self1007     fn recip(self) -> Self {
1008         Self::from_f32(self.to_f32().recip())
1009     }
1010 
1011     #[inline]
powi(self, exp: i32) -> Self1012     fn powi(self, exp: i32) -> Self {
1013         Self::from_f32(self.to_f32().powi(exp))
1014     }
1015 
1016     #[inline]
to_degrees(self) -> Self1017     fn to_degrees(self) -> Self {
1018         Self::from_f32(self.to_f32().to_degrees())
1019     }
1020 
1021     #[inline]
to_radians(self) -> Self1022     fn to_radians(self) -> Self {
1023         Self::from_f32(self.to_f32().to_radians())
1024     }
1025 
1026     #[inline]
integer_decode(self) -> (u64, i16, i8)1027     fn integer_decode(self) -> (u64, i16, i8) {
1028         num_traits::float::FloatCore::integer_decode(self.to_f32())
1029     }
1030 }
1031 
1032 impl num_traits::float::Float for bf16 {
1033     #[inline]
nan() -> Self1034     fn nan() -> Self {
1035         Self::NAN
1036     }
1037 
1038     #[inline]
infinity() -> Self1039     fn infinity() -> Self {
1040         Self::INFINITY
1041     }
1042 
1043     #[inline]
neg_infinity() -> Self1044     fn neg_infinity() -> Self {
1045         Self::NEG_INFINITY
1046     }
1047 
1048     #[inline]
neg_zero() -> Self1049     fn neg_zero() -> Self {
1050         Self::NEG_ZERO
1051     }
1052 
1053     #[inline]
min_value() -> Self1054     fn min_value() -> Self {
1055         Self::MIN
1056     }
1057 
1058     #[inline]
min_positive_value() -> Self1059     fn min_positive_value() -> Self {
1060         Self::MIN_POSITIVE
1061     }
1062 
1063     #[inline]
epsilon() -> Self1064     fn epsilon() -> Self {
1065         Self::EPSILON
1066     }
1067 
1068     #[inline]
max_value() -> Self1069     fn max_value() -> Self {
1070         Self::MAX
1071     }
1072 
1073     #[inline]
is_nan(self) -> bool1074     fn is_nan(self) -> bool {
1075         self.is_nan()
1076     }
1077 
1078     #[inline]
is_infinite(self) -> bool1079     fn is_infinite(self) -> bool {
1080         self.is_infinite()
1081     }
1082 
1083     #[inline]
is_finite(self) -> bool1084     fn is_finite(self) -> bool {
1085         self.is_finite()
1086     }
1087 
1088     #[inline]
is_normal(self) -> bool1089     fn is_normal(self) -> bool {
1090         self.is_normal()
1091     }
1092 
1093     #[inline]
classify(self) -> FpCategory1094     fn classify(self) -> FpCategory {
1095         self.classify()
1096     }
1097 
1098     #[inline]
floor(self) -> Self1099     fn floor(self) -> Self {
1100         Self::from_f32(self.to_f32().floor())
1101     }
1102 
1103     #[inline]
ceil(self) -> Self1104     fn ceil(self) -> Self {
1105         Self::from_f32(self.to_f32().ceil())
1106     }
1107 
1108     #[inline]
round(self) -> Self1109     fn round(self) -> Self {
1110         Self::from_f32(self.to_f32().round())
1111     }
1112 
1113     #[inline]
trunc(self) -> Self1114     fn trunc(self) -> Self {
1115         Self::from_f32(self.to_f32().trunc())
1116     }
1117 
1118     #[inline]
fract(self) -> Self1119     fn fract(self) -> Self {
1120         Self::from_f32(self.to_f32().fract())
1121     }
1122 
1123     #[inline]
abs(self) -> Self1124     fn abs(self) -> Self {
1125         Self::from_f32(self.to_f32().abs())
1126     }
1127 
1128     #[inline]
signum(self) -> Self1129     fn signum(self) -> Self {
1130         Self::from_f32(self.to_f32().signum())
1131     }
1132 
1133     #[inline]
is_sign_positive(self) -> bool1134     fn is_sign_positive(self) -> bool {
1135         self.is_sign_positive()
1136     }
1137 
1138     #[inline]
is_sign_negative(self) -> bool1139     fn is_sign_negative(self) -> bool {
1140         self.is_sign_negative()
1141     }
1142 
1143     #[inline]
mul_add(self, a: Self, b: Self) -> Self1144     fn mul_add(self, a: Self, b: Self) -> Self {
1145         Self::from_f32(self.to_f32().mul_add(a.to_f32(), b.to_f32()))
1146     }
1147 
1148     #[inline]
recip(self) -> Self1149     fn recip(self) -> Self {
1150         Self::from_f32(self.to_f32().recip())
1151     }
1152 
1153     #[inline]
powi(self, n: i32) -> Self1154     fn powi(self, n: i32) -> Self {
1155         Self::from_f32(self.to_f32().powi(n))
1156     }
1157 
1158     #[inline]
powf(self, n: Self) -> Self1159     fn powf(self, n: Self) -> Self {
1160         Self::from_f32(self.to_f32().powf(n.to_f32()))
1161     }
1162 
1163     #[inline]
sqrt(self) -> Self1164     fn sqrt(self) -> Self {
1165         Self::from_f32(self.to_f32().sqrt())
1166     }
1167 
1168     #[inline]
exp(self) -> Self1169     fn exp(self) -> Self {
1170         Self::from_f32(self.to_f32().exp())
1171     }
1172 
1173     #[inline]
exp2(self) -> Self1174     fn exp2(self) -> Self {
1175         Self::from_f32(self.to_f32().exp2())
1176     }
1177 
1178     #[inline]
ln(self) -> Self1179     fn ln(self) -> Self {
1180         Self::from_f32(self.to_f32().ln())
1181     }
1182 
1183     #[inline]
log(self, base: Self) -> Self1184     fn log(self, base: Self) -> Self {
1185         Self::from_f32(self.to_f32().log(base.to_f32()))
1186     }
1187 
1188     #[inline]
log2(self) -> Self1189     fn log2(self) -> Self {
1190         Self::from_f32(self.to_f32().log2())
1191     }
1192 
1193     #[inline]
log10(self) -> Self1194     fn log10(self) -> Self {
1195         Self::from_f32(self.to_f32().log10())
1196     }
1197 
1198     #[inline]
to_degrees(self) -> Self1199     fn to_degrees(self) -> Self {
1200         Self::from_f32(self.to_f32().to_degrees())
1201     }
1202 
1203     #[inline]
to_radians(self) -> Self1204     fn to_radians(self) -> Self {
1205         Self::from_f32(self.to_f32().to_radians())
1206     }
1207 
1208     #[inline]
max(self, other: Self) -> Self1209     fn max(self, other: Self) -> Self {
1210         self.max(other)
1211     }
1212 
1213     #[inline]
min(self, other: Self) -> Self1214     fn min(self, other: Self) -> Self {
1215         self.min(other)
1216     }
1217 
1218     #[inline]
abs_sub(self, other: Self) -> Self1219     fn abs_sub(self, other: Self) -> Self {
1220         Self::from_f32((self.to_f32() - other.to_f32()).max(0.0))
1221     }
1222 
1223     #[inline]
cbrt(self) -> Self1224     fn cbrt(self) -> Self {
1225         Self::from_f32(self.to_f32().cbrt())
1226     }
1227 
1228     #[inline]
hypot(self, other: Self) -> Self1229     fn hypot(self, other: Self) -> Self {
1230         Self::from_f32(self.to_f32().hypot(other.to_f32()))
1231     }
1232 
1233     #[inline]
sin(self) -> Self1234     fn sin(self) -> Self {
1235         Self::from_f32(self.to_f32().sin())
1236     }
1237 
1238     #[inline]
cos(self) -> Self1239     fn cos(self) -> Self {
1240         Self::from_f32(self.to_f32().cos())
1241     }
1242 
1243     #[inline]
tan(self) -> Self1244     fn tan(self) -> Self {
1245         Self::from_f32(self.to_f32().tan())
1246     }
1247 
1248     #[inline]
asin(self) -> Self1249     fn asin(self) -> Self {
1250         Self::from_f32(self.to_f32().asin())
1251     }
1252 
1253     #[inline]
acos(self) -> Self1254     fn acos(self) -> Self {
1255         Self::from_f32(self.to_f32().acos())
1256     }
1257 
1258     #[inline]
atan(self) -> Self1259     fn atan(self) -> Self {
1260         Self::from_f32(self.to_f32().atan())
1261     }
1262 
1263     #[inline]
atan2(self, other: Self) -> Self1264     fn atan2(self, other: Self) -> Self {
1265         Self::from_f32(self.to_f32().atan2(other.to_f32()))
1266     }
1267 
1268     #[inline]
sin_cos(self) -> (Self, Self)1269     fn sin_cos(self) -> (Self, Self) {
1270         let (sin, cos) = self.to_f32().sin_cos();
1271         (Self::from_f32(sin), Self::from_f32(cos))
1272     }
1273 
1274     #[inline]
exp_m1(self) -> Self1275     fn exp_m1(self) -> Self {
1276         Self::from_f32(self.to_f32().exp_m1())
1277     }
1278 
1279     #[inline]
ln_1p(self) -> Self1280     fn ln_1p(self) -> Self {
1281         Self::from_f32(self.to_f32().ln_1p())
1282     }
1283 
1284     #[inline]
sinh(self) -> Self1285     fn sinh(self) -> Self {
1286         Self::from_f32(self.to_f32().sinh())
1287     }
1288 
1289     #[inline]
cosh(self) -> Self1290     fn cosh(self) -> Self {
1291         Self::from_f32(self.to_f32().cosh())
1292     }
1293 
1294     #[inline]
tanh(self) -> Self1295     fn tanh(self) -> Self {
1296         Self::from_f32(self.to_f32().tanh())
1297     }
1298 
1299     #[inline]
asinh(self) -> Self1300     fn asinh(self) -> Self {
1301         Self::from_f32(self.to_f32().asinh())
1302     }
1303 
1304     #[inline]
acosh(self) -> Self1305     fn acosh(self) -> Self {
1306         Self::from_f32(self.to_f32().acosh())
1307     }
1308 
1309     #[inline]
atanh(self) -> Self1310     fn atanh(self) -> Self {
1311         Self::from_f32(self.to_f32().atanh())
1312     }
1313 
1314     #[inline]
integer_decode(self) -> (u64, i16, i8)1315     fn integer_decode(self) -> (u64, i16, i8) {
1316         num_traits::float::Float::integer_decode(self.to_f32())
1317     }
1318 }
1319 
1320 impl FloatConst for bf16 {
1321     #[inline]
E() -> Self1322     fn E() -> Self {
1323         Self::E
1324     }
1325 
1326     #[inline]
FRAC_1_PI() -> Self1327     fn FRAC_1_PI() -> Self {
1328         Self::FRAC_1_PI
1329     }
1330 
1331     #[inline]
FRAC_1_SQRT_2() -> Self1332     fn FRAC_1_SQRT_2() -> Self {
1333         Self::FRAC_1_SQRT_2
1334     }
1335 
1336     #[inline]
FRAC_2_PI() -> Self1337     fn FRAC_2_PI() -> Self {
1338         Self::FRAC_2_PI
1339     }
1340 
1341     #[inline]
FRAC_2_SQRT_PI() -> Self1342     fn FRAC_2_SQRT_PI() -> Self {
1343         Self::FRAC_2_SQRT_PI
1344     }
1345 
1346     #[inline]
FRAC_PI_2() -> Self1347     fn FRAC_PI_2() -> Self {
1348         Self::FRAC_PI_2
1349     }
1350 
1351     #[inline]
FRAC_PI_3() -> Self1352     fn FRAC_PI_3() -> Self {
1353         Self::FRAC_PI_3
1354     }
1355 
1356     #[inline]
FRAC_PI_4() -> Self1357     fn FRAC_PI_4() -> Self {
1358         Self::FRAC_PI_4
1359     }
1360 
1361     #[inline]
FRAC_PI_6() -> Self1362     fn FRAC_PI_6() -> Self {
1363         Self::FRAC_PI_6
1364     }
1365 
1366     #[inline]
FRAC_PI_8() -> Self1367     fn FRAC_PI_8() -> Self {
1368         Self::FRAC_PI_8
1369     }
1370 
1371     #[inline]
LN_10() -> Self1372     fn LN_10() -> Self {
1373         Self::LN_10
1374     }
1375 
1376     #[inline]
LN_2() -> Self1377     fn LN_2() -> Self {
1378         Self::LN_2
1379     }
1380 
1381     #[inline]
LOG10_E() -> Self1382     fn LOG10_E() -> Self {
1383         Self::LOG10_E
1384     }
1385 
1386     #[inline]
LOG2_E() -> Self1387     fn LOG2_E() -> Self {
1388         Self::LOG2_E
1389     }
1390 
1391     #[inline]
PI() -> Self1392     fn PI() -> Self {
1393         Self::PI
1394     }
1395 
1396     #[inline]
SQRT_2() -> Self1397     fn SQRT_2() -> Self {
1398         Self::SQRT_2
1399     }
1400 
1401     #[inline]
LOG10_2() -> Self where Self: Sized + Div<Self, Output = Self>,1402     fn LOG10_2() -> Self
1403     where
1404         Self: Sized + Div<Self, Output = Self>,
1405     {
1406         Self::LOG10_2
1407     }
1408 
1409     #[inline]
LOG2_10() -> Self where Self: Sized + Div<Self, Output = Self>,1410     fn LOG2_10() -> Self
1411     where
1412         Self: Sized + Div<Self, Output = Self>,
1413     {
1414         Self::LOG2_10
1415     }
1416 }
1417 
1418 impl Bounded for bf16 {
1419     #[inline]
min_value() -> Self1420     fn min_value() -> Self {
1421         bf16::MIN
1422     }
1423 
1424     #[inline]
max_value() -> Self1425     fn max_value() -> Self {
1426         bf16::MAX
1427     }
1428 }
1429 
1430 impl AsPrimitive<bf16> for bf16 {
1431     #[inline]
as_(self) -> bf161432     fn as_(self) -> bf16 {
1433         self
1434     }
1435 }
1436 
1437 macro_rules! impl_as_primitive_to_bf16 {
1438     ($ty:ty, $meth:ident) => {
1439         impl AsPrimitive<$ty> for bf16 {
1440             #[inline]
1441             fn as_(self) -> $ty {
1442                 self.$meth().as_()
1443             }
1444         }
1445     };
1446 }
1447 
1448 impl_as_primitive_to_bf16!(i64, to_f32);
1449 impl_as_primitive_to_bf16!(u64, to_f32);
1450 impl_as_primitive_to_bf16!(i8, to_f32);
1451 impl_as_primitive_to_bf16!(u8, to_f32);
1452 impl_as_primitive_to_bf16!(i16, to_f32);
1453 impl_as_primitive_to_bf16!(u16, to_f32);
1454 impl_as_primitive_to_bf16!(i32, to_f32);
1455 impl_as_primitive_to_bf16!(u32, to_f32);
1456 impl_as_primitive_to_bf16!(isize, to_f32);
1457 impl_as_primitive_to_bf16!(usize, to_f32);
1458 impl_as_primitive_to_bf16!(f32, to_f32);
1459 impl_as_primitive_to_bf16!(f64, to_f64);
1460 
1461 macro_rules! impl_as_primitive_bf16_from {
1462     ($ty:ty, $meth:ident) => {
1463         impl AsPrimitive<bf16> for $ty {
1464             #[inline]
1465             fn as_(self) -> bf16 {
1466                 bf16::$meth(self.as_())
1467             }
1468         }
1469     };
1470 }
1471 
1472 impl_as_primitive_bf16_from!(i64, from_f32);
1473 impl_as_primitive_bf16_from!(u64, from_f32);
1474 impl_as_primitive_bf16_from!(i8, from_f32);
1475 impl_as_primitive_bf16_from!(u8, from_f32);
1476 impl_as_primitive_bf16_from!(i16, from_f32);
1477 impl_as_primitive_bf16_from!(u16, from_f32);
1478 impl_as_primitive_bf16_from!(i32, from_f32);
1479 impl_as_primitive_bf16_from!(u32, from_f32);
1480 impl_as_primitive_bf16_from!(isize, from_f32);
1481 impl_as_primitive_bf16_from!(usize, from_f32);
1482 impl_as_primitive_bf16_from!(f32, from_f32);
1483 impl_as_primitive_bf16_from!(f64, from_f64);
1484