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}