1#[cfg(feature = "f16")]
8use crate::bf16::bf16;
9#[cfg(feature = "f16")]
10use crate::f16::f16;
11use core::{fmt, mem, ops};
12
13pub trait AsPrimitive: Copy + PartialEq + PartialOrd + Send + Sync + Sized {
18 fn as_u8(self) -> u8;
19 fn as_u16(self) -> u16;
20 fn as_u32(self) -> u32;
21 fn as_u64(self) -> u64;
22 fn as_u128(self) -> u128;
23 fn as_usize(self) -> usize;
24 fn as_i8(self) -> i8;
25 fn as_i16(self) -> i16;
26 fn as_i32(self) -> i32;
27 fn as_i64(self) -> i64;
28 fn as_i128(self) -> i128;
29 fn as_isize(self) -> isize;
30 fn as_f32(self) -> f32;
31 fn as_f64(self) -> f64;
32 fn from_u32(value: u32) -> Self;
33
34 #[cfg(feature = "f16")]
35 fn as_f16(self) -> f16;
36
37 #[cfg(feature = "f16")]
38 fn as_bf16(self) -> bf16;
39}
40
41macro_rules! as_primitive {
42 ($($t:ty)*) => ($(
43 impl AsPrimitive for $t {
44 #[inline(always)]
45 fn as_u8(self) -> u8 {
46 self as _
47 }
48
49 #[inline(always)]
50 fn as_u16(self) -> u16 {
51 self as _
52 }
53
54 #[inline(always)]
55 fn as_u32(self) -> u32 {
56 self as _
57 }
58
59 #[inline(always)]
60 fn as_u64(self) -> u64 {
61 self as _
62 }
63
64 #[inline(always)]
65 fn as_u128(self) -> u128 {
66 self as _
67 }
68
69 #[inline(always)]
70 fn as_usize(self) -> usize {
71 self as _
72 }
73
74 #[inline(always)]
75 fn as_i8(self) -> i8 {
76 self as _
77 }
78
79 #[inline(always)]
80 fn as_i16(self) -> i16 {
81 self as _
82 }
83
84 #[inline(always)]
85 fn as_i32(self) -> i32 {
86 self as _
87 }
88
89 #[inline(always)]
90 fn as_i64(self) -> i64 {
91 self as _
92 }
93
94 #[inline(always)]
95 fn as_i128(self) -> i128 {
96 self as _
97 }
98
99 #[inline(always)]
100 fn as_isize(self) -> isize {
101 self as _
102 }
103
104 #[inline(always)]
105 fn as_f32(self) -> f32 {
106 self as _
107 }
108
109 #[inline(always)]
110 fn as_f64(self) -> f64 {
111 self as _
112 }
113
114 #[inline(always)]
115 fn from_u32(value: u32) -> Self {
116 value as _
117 }
118
119 #[cfg(feature = "f16")]
120 #[inline(always)]
121 fn as_f16(self) -> f16 {
122 f16::from_f32(self as f32)
123 }
124
125 #[cfg(feature = "f16")]
126 #[inline(always)]
127 fn as_bf16(self) -> bf16 {
128 bf16::from_f32(self as f32)
129 }
130 }
131 )*)
132}
133
134as_primitive! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64 }
135
136#[cfg(feature = "f16")]
137macro_rules! half_as_primitive {
138 ($($t:ty)*) => ($(
139 impl AsPrimitive for $t {
140 #[inline(always)]
141 fn as_u8(self) -> u8 {
142 self.as_f32() as _
143 }
144
145 #[inline(always)]
146 fn as_u16(self) -> u16 {
147 self.as_f32() as _
148 }
149
150 #[inline(always)]
151 fn as_u32(self) -> u32 {
152 self.as_f32() as _
153 }
154
155 #[inline(always)]
156 fn as_u64(self) -> u64 {
157 self.as_f32() as _
158 }
159
160 #[inline(always)]
161 fn as_u128(self) -> u128 {
162 self.as_f32() as _
163 }
164
165 #[inline(always)]
166 fn as_usize(self) -> usize {
167 self.as_f32() as _
168 }
169
170 #[inline(always)]
171 fn as_i8(self) -> i8 {
172 self.as_f32() as _
173 }
174
175 #[inline(always)]
176 fn as_i16(self) -> i16 {
177 self.as_f32() as _
178 }
179
180 #[inline(always)]
181 fn as_i32(self) -> i32 {
182 self.as_f32() as _
183 }
184
185 #[inline(always)]
186 fn as_i64(self) -> i64 {
187 self.as_f32() as _
188 }
189
190 #[inline(always)]
191 fn as_i128(self) -> i128 {
192 self.as_f32() as _
193 }
194
195 #[inline(always)]
196 fn as_isize(self) -> isize {
197 self.as_f32() as _
198 }
199
200 #[inline(always)]
201 fn as_f32(self) -> f32 {
202 self.as_f32() as _
203 }
204
205 #[inline(always)]
206 fn as_f64(self) -> f64 {
207 self.as_f32() as _
208 }
209
210 #[inline(always)]
211 fn from_u32(value: u32) -> Self {
212 Self::from_f32(value as _)
213 }
214
215 #[inline(always)]
216 fn as_f16(self) -> f16 {
217 f16::from_f32(self.as_f32())
218 }
219
220 #[inline(always)]
221 fn as_bf16(self) -> bf16 {
222 bf16::from_f32(self.as_f32())
223 }
224 }
225 )*)
226}
227
228#[cfg(feature = "f16")]
229half_as_primitive! { f16 bf16 }
230
231pub trait AsCast: AsPrimitive {
236 fn as_cast<N: AsPrimitive>(n: N) -> Self;
239}
240
241#[inline]
243pub fn as_cast<U: AsCast, T: AsCast>(t: T) -> U {
244 U::as_cast(t)
245}
246
247macro_rules! as_cast {
248 ($($t:ty, $meth:ident ; )*) => ($(
249 impl AsCast for $t {
250 #[inline]
251 fn as_cast<N: AsPrimitive>(n: N) -> $t {
252 n.$meth() as _
253 }
254 }
255 )*);
256}
257
258as_cast!(
259 u8, as_u8 ;
260 u16, as_u16 ;
261 u32, as_u32 ;
262 u64, as_u64 ;
263 u128, as_u128 ;
264 usize, as_usize ;
265 i8, as_i8 ;
266 i16, as_i16 ;
267 i32, as_i32 ;
268 i64, as_i64 ;
269 i128, as_i128 ;
270 isize, as_isize ;
271 f32, as_f32 ;
272 f64, as_f64 ;
273);
274
275#[cfg(feature = "f16")]
276as_cast!(
277 f16, as_f16 ;
278 bf16, as_bf16 ;
279);
280
281pub trait Primitive: 'static + fmt::Debug + fmt::Display + AsCast {}
286
287macro_rules! primitive {
288 ($($t:ty)*) => ($(
289 impl Primitive for $t {}
290 )*)
291}
292
293primitive! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64 }
294
295#[cfg(feature = "f16")]
296primitive! { f16 bf16 }
297
298pub trait Number:
303 Default +
304 Primitive +
305 ops::Add<Output=Self> +
307 ops::AddAssign +
308 ops::Div<Output=Self> +
309 ops::DivAssign +
310 ops::Mul<Output=Self> +
311 ops::MulAssign +
312 ops::Rem<Output=Self> +
313 ops::RemAssign +
314 ops::Sub<Output=Self> +
315 ops::SubAssign
316{
317 const IS_SIGNED: bool;
319}
320
321macro_rules! number_impl {
322 ($($t:tt $is_signed:literal ; )*) => ($(
323 impl Number for $t {
324 const IS_SIGNED: bool = $is_signed;
325 }
326 )*)
327}
328
329number_impl! {
330 u8 false ;
331 u16 false ;
332 u32 false ;
333 u64 false ;
334 u128 false ;
335 usize false ;
336 i8 true ;
337 i16 true ;
338 i32 true ;
339 i64 true ;
340 i128 true ;
341 isize true ;
342 f32 true ;
343 f64 true ;
344 }
346
347#[cfg(feature = "f16")]
348number_impl! {
349 f16 true ;
350 bf16 true ;
351}
352
353pub trait Integer:
358 Number + Eq + Ord +
360 ops::BitAnd<Output=Self> +
362 ops::BitAndAssign +
363 ops::BitOr<Output=Self> +
364 ops::BitOrAssign +
365 ops::BitXor<Output=Self> +
366 ops::BitXorAssign +
367 ops::Not<Output=Self> +
368 ops::Shl<Self, Output=Self> +
369 ops::Shl<i32, Output=Self> +
370 ops::ShlAssign<i32> +
371 ops::Shr<i32, Output=Self> +
372 ops::ShrAssign<i32> +
373{
374 const ZERO: Self;
376 const ONE: Self;
377 const TWO: Self;
378 const MAX: Self;
379 const MIN: Self;
380 const BITS: usize;
381
382 fn leading_zeros(self) -> u32;
384 fn trailing_zeros(self) -> u32;
385 fn pow(self, exp: u32) -> Self;
386 fn checked_add(self, i: Self) -> Option<Self>;
387 fn checked_sub(self, i: Self) -> Option<Self>;
388 fn checked_mul(self, i: Self) -> Option<Self>;
389 fn overflowing_add(self, i: Self) -> (Self, bool);
390 fn overflowing_mul(self, i: Self) -> (Self, bool);
391 fn wrapping_add(self, i: Self) -> Self;
392 fn wrapping_sub(self, i: Self) -> Self;
393 fn wrapping_mul(self, i: Self) -> Self;
394 fn wrapping_neg(self) -> Self;
395 fn saturating_add(self, i: Self) -> Self;
396 fn saturating_sub(self, i: Self) -> Self;
397 fn saturating_mul(self, i: Self) -> Self;
398
399 #[inline]
402 fn ceil_divmod(self, y: Self) -> (Self, i32) {
403 let q = self / y;
404 let r = self % y;
405 match r == Self::ZERO {
406 true => (q, i32::as_cast(r)),
407 false => (q + Self::ONE, i32::as_cast(r) - i32::as_cast(y))
408 }
409 }
410
411 #[inline]
414 fn ceil_div(self, y: Self) -> Self {
415 self.ceil_divmod(y).0
416 }
417
418 #[inline]
421 fn ceil_mod(self, y: Self) -> i32 {
422 self.ceil_divmod(y).1
423 }
424
425 #[inline]
429 fn bit_length(self) -> u32 {
430 Self::BITS as u32 - self.leading_zeros()
431 }
432
433 #[inline]
435 fn is_odd(self) -> bool {
436 self & Self::ONE == Self::ONE
437 }
438
439 #[inline]
441 fn is_even(self) -> bool {
442 !self.is_odd()
443 }
444}
445
446macro_rules! integer_impl {
447 ($($t:tt)*) => ($(
448 impl Integer for $t {
449 const ZERO: $t = 0;
450 const ONE: $t = 1;
451 const TWO: $t = 2;
452 const MAX: $t = $t::max_value();
453 const MIN: $t = $t::min_value();
454 const BITS: usize = mem::size_of::<$t>() * 8;
456
457 #[inline]
458 fn leading_zeros(self) -> u32 {
459 $t::leading_zeros(self)
460 }
461
462 #[inline]
463 fn trailing_zeros(self) -> u32 {
464 $t::trailing_zeros(self)
465 }
466
467 #[inline]
468 fn checked_add(self, i: Self) -> Option<Self> {
469 $t::checked_add(self, i)
470 }
471
472 #[inline]
473 fn checked_sub(self, i: Self) -> Option<Self> {
474 $t::checked_sub(self, i)
475 }
476
477 #[inline]
478 fn checked_mul(self, i: Self) -> Option<Self> {
479 $t::checked_mul(self, i)
480 }
481
482 #[inline]
483 fn overflowing_add(self, i: Self) -> (Self, bool) {
484 $t::overflowing_add(self, i)
485 }
486
487 #[inline]
488 fn overflowing_mul(self, i: Self) -> (Self, bool) {
489 $t::overflowing_mul(self, i)
490 }
491
492 #[inline]
493 fn wrapping_add(self, i: Self) -> Self {
494 $t::wrapping_add(self, i)
495 }
496
497 #[inline]
498 fn wrapping_sub(self, i: Self) -> Self {
499 $t::wrapping_sub(self, i)
500 }
501
502 #[inline]
503 fn wrapping_mul(self, i: Self) -> Self {
504 $t::wrapping_mul(self, i)
505 }
506
507 #[inline]
508 fn wrapping_neg(self) -> Self {
509 $t::wrapping_neg(self)
510 }
511
512 #[inline]
513 fn pow(self, exp: u32) -> Self {
514 Self::pow(self, exp)
515 }
516
517 #[inline]
518 fn saturating_add(self, i: Self) -> Self {
519 $t::saturating_add(self, i)
520 }
521
522 #[inline]
523 fn saturating_sub(self, i: Self) -> Self {
524 $t::saturating_sub(self, i)
525 }
526
527 #[inline]
528 fn saturating_mul(self, i: Self) -> Self {
529 $t::saturating_mul(self, i)
530 }
531 }
532 )*)
533}
534
535integer_impl! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
536
537pub trait SignedInteger: Integer + ops::Neg<Output = Self> {}
542
543macro_rules! signed_integer_impl {
544 ($($t:tt)*) => ($(
545 impl SignedInteger for $t {}
546 )*)
547}
548
549signed_integer_impl! { i8 i16 i32 i64 i128 isize }
550
551pub trait UnsignedInteger: Integer {}
556
557macro_rules! unsigned_integer_impl {
558 ($($t:ty)*) => ($(
559 impl UnsignedInteger for $t {}
560 )*)
561}
562
563unsigned_integer_impl! { u8 u16 u32 u64 u128 usize }
564
565#[cfg(feature = "floats")]
570pub trait Float: Number + ops::Neg<Output = Self> {
571 type Unsigned: UnsignedInteger;
573
574 const ZERO: Self;
576 const ONE: Self;
577 const TWO: Self;
578 const MAX: Self;
579 const MIN: Self;
580 const INFINITY: Self;
581 const NEG_INFINITY: Self;
582 const NAN: Self;
583 const BITS: usize;
584
585 const SIGN_MASK: Self::Unsigned;
587 const EXPONENT_MASK: Self::Unsigned;
589 const HIDDEN_BIT_MASK: Self::Unsigned;
591 const MANTISSA_MASK: Self::Unsigned;
593 const CARRY_MASK: Self::Unsigned;
595
596 const INFINITY_BITS: Self::Unsigned;
607 const NEGATIVE_INFINITY_BITS: Self::Unsigned;
609 const EXPONENT_SIZE: i32;
611 const MANTISSA_SIZE: i32;
613 const EXPONENT_BIAS: i32;
615 const DENORMAL_EXPONENT: i32;
617 const MAX_EXPONENT: i32;
619
620 fn to_bits(self) -> Self::Unsigned;
624 fn from_bits(u: Self::Unsigned) -> Self;
625 fn ln(self) -> Self;
626 fn floor(self) -> Self;
627 fn is_sign_positive(self) -> bool;
628 fn is_sign_negative(self) -> bool;
629
630 #[inline]
632 fn is_denormal(self) -> bool {
633 self.to_bits() & Self::EXPONENT_MASK == Self::Unsigned::ZERO
634 }
635
636 #[inline]
638 fn is_special(self) -> bool {
639 self.to_bits() & Self::EXPONENT_MASK == Self::EXPONENT_MASK
640 }
641
642 #[inline]
644 fn is_nan(self) -> bool {
645 self.is_special() && (self.to_bits() & Self::MANTISSA_MASK) != Self::Unsigned::ZERO
646 }
647
648 #[inline]
650 fn is_inf(self) -> bool {
651 self.is_special() && (self.to_bits() & Self::MANTISSA_MASK) == Self::Unsigned::ZERO
652 }
653
654 #[inline]
656 fn is_odd(self) -> bool {
657 self.to_bits().is_odd()
658 }
659
660 #[inline]
662 fn is_even(self) -> bool {
663 !self.is_odd()
664 }
665
666 #[inline]
668 fn exponent(self) -> i32 {
669 if self.is_denormal() {
670 return Self::DENORMAL_EXPONENT;
671 }
672
673 let bits = self.to_bits();
674 let biased_e = i32::as_cast((bits & Self::EXPONENT_MASK) >> Self::MANTISSA_SIZE).as_i32();
675 biased_e - Self::EXPONENT_BIAS
676 }
677
678 #[inline]
680 fn mantissa(self) -> Self::Unsigned {
681 let bits = self.to_bits();
682 let s = bits & Self::MANTISSA_MASK;
683 if !self.is_denormal() {
684 s + Self::HIDDEN_BIT_MASK
685 } else {
686 s
687 }
688 }
689
690 #[inline]
692 fn next(self) -> Self {
693 let bits = self.to_bits();
694 if self.is_sign_negative() && self == Self::ZERO {
695 Self::ZERO
697 } else if bits == Self::INFINITY_BITS {
698 Self::from_bits(Self::INFINITY_BITS)
699 } else if self.is_sign_negative() {
700 Self::from_bits(bits.saturating_sub(Self::Unsigned::ONE))
701 } else {
702 Self::from_bits(bits.saturating_add(Self::Unsigned::ONE))
703 }
704 }
705
706 #[inline]
709 fn next_positive(self) -> Self {
710 debug_assert!(self.is_sign_positive() && !self.is_inf());
711 Self::from_bits(self.to_bits() + Self::Unsigned::ONE)
712 }
713
714 #[inline]
716 fn prev(self) -> Self {
717 let bits = self.to_bits();
718 if self.is_sign_positive() && self == Self::ZERO {
719 -Self::ZERO
721 } else if bits == Self::NEGATIVE_INFINITY_BITS {
722 Self::from_bits(Self::NEGATIVE_INFINITY_BITS)
723 } else if self.is_sign_negative() {
724 Self::from_bits(bits.saturating_add(Self::Unsigned::ONE))
725 } else {
726 Self::from_bits(bits.saturating_sub(Self::Unsigned::ONE))
727 }
728 }
729
730 #[inline]
733 fn prev_positive(self) -> Self {
734 debug_assert!(self.is_sign_positive() && self != Self::ZERO);
735 Self::from_bits(self.to_bits() - Self::Unsigned::ONE)
736 }
737
738 #[inline]
740 fn round_positive_even(self) -> Self {
741 if self.mantissa().is_odd() {
742 self.next_positive()
743 } else {
744 self
745 }
746 }
747
748 #[inline]
750 fn max_finite(self, f: Self) -> Self {
751 debug_assert!(!self.is_special() && !f.is_special(), "max_finite self={} f={}", self, f);
752 if self < f {
753 f
754 } else {
755 self
756 }
757 }
758
759 #[inline]
761 fn min_finite(self, f: Self) -> Self {
762 debug_assert!(!self.is_special() && !f.is_special(), "min_finite self={} f={}", self, f);
763 if self < f {
764 self
765 } else {
766 f
767 }
768 }
769}
770
771#[cfg(feature = "floats")]
773macro_rules! float_literals {
774 ($float:ty) => {
775 const ZERO: $float = 0.0;
776 const ONE: $float = 1.0;
777 const TWO: $float = 2.0;
778 const MAX: $float = <$float>::MAX;
779 const MIN: $float = <$float>::MIN;
780 const INFINITY: $float = <$float>::INFINITY;
781 const NEG_INFINITY: $float = <$float>::NEG_INFINITY;
782 const NAN: $float = <$float>::NAN;
783 const BITS: usize = mem::size_of::<$float>() * 8;
784 };
785}
786
787#[cfg(feature = "floats")]
789macro_rules! float_masks {
790 (
791 float =>
792 $float:ty,sign_mask =>
793 $sign:literal,exponent_mask =>
794 $exponent:literal,hidden_bit_mask =>
795 $hidden:literal,mantissa_mask =>
796 $mantissa:literal,
797 ) => {
798 const SIGN_MASK: <$float>::Unsigned = $sign;
799 const EXPONENT_MASK: <$float>::Unsigned = $exponent;
800 const HIDDEN_BIT_MASK: <$float>::Unsigned = $hidden;
801 const MANTISSA_MASK: <$float>::Unsigned = $mantissa;
802 const CARRY_MASK: <$float>::Unsigned = $hidden << 1;
804 const INFINITY_BITS: <$float>::Unsigned = $exponent;
806 const NEGATIVE_INFINITY_BITS: <$float>::Unsigned = $exponent | $sign;
808 };
809}
810
811#[cfg(feature = "f16")]
816macro_rules! float_one {
817 ($f:ident) => {
818 (($f::EXPONENT_BIAS - $f::MANTISSA_SIZE) as u16) << $f::MANTISSA_SIZE
819 };
820}
821
822#[cfg(feature = "f16")]
823macro_rules! float_two {
824 ($f:ident) => {
825 (($f::EXPONENT_BIAS - $f::MANTISSA_SIZE + 1) as u16) << $f::MANTISSA_SIZE
826 };
827}
828
829#[cfg(feature = "f16")]
830macro_rules! float_max {
831 ($f:ident) => {
832 ($f::EXPONENT_MASK ^ $f::HIDDEN_BIT_MASK) | $f::MANTISSA_MASK
833 };
834}
835
836#[cfg(feature = "f16")]
837macro_rules! float_min {
838 ($f:ident) => {
839 $f::MAX.to_bits() | $f::SIGN_MASK
840 };
841}
842
843#[cfg(feature = "f16")]
844macro_rules! float_nan {
845 ($f:ident) => {
846 $f::EXPONENT_MASK | ($f::HIDDEN_BIT_MASK >> 1)
847 };
848}
849
850#[cfg(feature = "f16")]
851impl Float for f16 {
852 type Unsigned = u16;
853
854 const ZERO: Self = Self::from_bits(0);
855 const ONE: Self = Self::from_bits(float_one!(Self));
856 const TWO: Self = Self::from_bits(float_two!(Self));
857 const MAX: Self = Self::from_bits(float_max!(Self));
858 const MIN: Self = Self::from_bits(float_min!(Self));
859 const INFINITY: Self = Self::from_bits(Self::INFINITY_BITS);
860 const NEG_INFINITY: Self = Self::from_bits(Self::NEGATIVE_INFINITY_BITS);
861 const NAN: Self = Self::from_bits(float_nan!(Self));
862 const BITS: usize = mem::size_of::<Self>() * 8;
863
864 float_masks!(
865 float => Self,
866 sign_mask => 0x8000,
867 exponent_mask => 0x7C00,
868 hidden_bit_mask => 0x0400,
869 mantissa_mask => 0x03FF,
870 );
871 const EXPONENT_SIZE: i32 = 5;
872 const MANTISSA_SIZE: i32 = 10;
873 const EXPONENT_BIAS: i32 = 15 + Self::MANTISSA_SIZE;
874 const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
875 const MAX_EXPONENT: i32 = 0x1F - Self::EXPONENT_BIAS;
876
877 #[inline]
878 fn to_bits(self) -> u16 {
879 f16::to_bits(self)
880 }
881
882 #[inline]
883 fn from_bits(u: u16) -> f16 {
884 f16::from_bits(u)
885 }
886
887 #[inline]
888 fn ln(self) -> f16 {
889 f16::from_f32(self.as_f32().ln())
890 }
891
892 #[inline]
893 fn floor(self) -> f16 {
894 f16::from_f32(self.as_f32().floor())
895 }
896
897 #[inline]
898 fn is_sign_positive(self) -> bool {
899 self.to_bits() & Self::SIGN_MASK == 0
900 }
901
902 #[inline]
903 fn is_sign_negative(self) -> bool {
904 !self.is_sign_positive()
905 }
906}
907
908#[cfg(feature = "f16")]
909impl Float for bf16 {
910 type Unsigned = u16;
911
912 const ZERO: Self = Self::from_bits(0);
913 const ONE: Self = Self::from_bits(float_one!(Self));
914 const TWO: Self = Self::from_bits(float_two!(Self));
915 const MAX: Self = Self::from_bits(float_max!(Self));
916 const MIN: Self = Self::from_bits(float_min!(Self));
917 const INFINITY: Self = Self::from_bits(Self::INFINITY_BITS);
918 const NEG_INFINITY: Self = Self::from_bits(Self::NEGATIVE_INFINITY_BITS);
919 const NAN: Self = Self::from_bits(float_nan!(Self));
920 const BITS: usize = mem::size_of::<Self>() * 8;
921
922 float_masks!(
923 float => Self,
924 sign_mask => 0x8000,
925 exponent_mask => 0x7F80,
926 hidden_bit_mask => 0x0080,
927 mantissa_mask => 0x007F,
928 );
929 const EXPONENT_SIZE: i32 = 8;
930 const MANTISSA_SIZE: i32 = 7;
931 const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE;
932 const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
933 const MAX_EXPONENT: i32 = 0xFF - Self::EXPONENT_BIAS;
934
935 #[inline]
936 fn to_bits(self) -> u16 {
937 bf16::to_bits(self)
938 }
939
940 #[inline]
941 fn from_bits(u: u16) -> bf16 {
942 bf16::from_bits(u)
943 }
944
945 #[inline]
946 fn ln(self) -> bf16 {
947 bf16::from_f32(self.as_f32().ln())
948 }
949
950 #[inline]
951 fn floor(self) -> bf16 {
952 bf16::from_f32(self.as_f32().floor())
953 }
954
955 #[inline]
956 fn is_sign_positive(self) -> bool {
957 self.to_bits() & Self::SIGN_MASK == 0
958 }
959
960 #[inline]
961 fn is_sign_negative(self) -> bool {
962 !self.is_sign_positive()
963 }
964}
965
966#[cfg(feature = "floats")]
967impl Float for f32 {
968 type Unsigned = u32;
969 float_literals!(f32);
970 float_masks!(
971 float => Self,
972 sign_mask => 0x80000000,
973 exponent_mask => 0x7F800000,
974 hidden_bit_mask => 0x00800000,
975 mantissa_mask => 0x007FFFFF,
976 );
977 const EXPONENT_SIZE: i32 = 8;
978 const MANTISSA_SIZE: i32 = 23;
979 const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE;
980 const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
981 const MAX_EXPONENT: i32 = 0xFF - Self::EXPONENT_BIAS;
982
983 #[inline]
984 fn to_bits(self) -> u32 {
985 f32::to_bits(self)
986 }
987
988 #[inline]
989 fn from_bits(u: u32) -> f32 {
990 f32::from_bits(u)
991 }
992
993 #[inline]
994 fn ln(self) -> f32 {
995 #[cfg(feature = "std")]
996 return f32::ln(self);
997
998 #[cfg(not(feature = "std"))]
999 return logf(self);
1000 }
1001
1002 #[inline]
1003 fn floor(self) -> f32 {
1004 #[cfg(feature = "std")]
1005 return f32::floor(self);
1006
1007 #[cfg(not(feature = "std"))]
1008 return floorf(self);
1009 }
1010
1011 #[inline]
1012 fn is_sign_positive(self) -> bool {
1013 f32::is_sign_positive(self)
1014 }
1015
1016 #[inline]
1017 fn is_sign_negative(self) -> bool {
1018 f32::is_sign_negative(self)
1019 }
1020}
1021
1022#[cfg(feature = "floats")]
1023impl Float for f64 {
1024 type Unsigned = u64;
1025 float_literals!(f64);
1026 float_masks!(
1027 float => Self,
1028 sign_mask => 0x8000000000000000,
1029 exponent_mask => 0x7FF0000000000000,
1030 hidden_bit_mask => 0x0010000000000000,
1031 mantissa_mask => 0x000FFFFFFFFFFFFF,
1032 );
1033 const EXPONENT_SIZE: i32 = 11;
1034 const MANTISSA_SIZE: i32 = 52;
1035 const EXPONENT_BIAS: i32 = 1023 + Self::MANTISSA_SIZE;
1036 const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
1037 const MAX_EXPONENT: i32 = 0x7FF - Self::EXPONENT_BIAS;
1038
1039 #[inline]
1040 fn to_bits(self) -> u64 {
1041 f64::to_bits(self)
1042 }
1043
1044 #[inline]
1045 fn from_bits(u: u64) -> f64 {
1046 f64::from_bits(u)
1047 }
1048
1049 #[inline]
1050 fn ln(self) -> f64 {
1051 #[cfg(feature = "std")]
1052 return f64::ln(self);
1053
1054 #[cfg(not(feature = "std"))]
1055 return logd(self);
1056 }
1057
1058 #[inline]
1059 fn floor(self) -> f64 {
1060 #[cfg(feature = "std")]
1061 return f64::floor(self);
1062
1063 #[cfg(not(feature = "std"))]
1064 return floord(self);
1065 }
1066
1067 #[inline]
1068 fn is_sign_positive(self) -> bool {
1069 f64::is_sign_positive(self)
1070 }
1071
1072 #[inline]
1073 fn is_sign_negative(self) -> bool {
1074 f64::is_sign_negative(self)
1075 }
1076}
1077
1078#[cfg(all(not(feature = "std"), feature = "floats"))]
1107macro_rules! volatile {
1108 ($e:expr) => {
1109 unsafe {
1111 core::ptr::read_volatile(&$e);
1112 }
1113 };
1114}
1115
1116#[cfg(all(not(feature = "std"), feature = "floats"))]
1120fn floord(x: f64) -> f64 {
1121 const TOINT: f64 = 1. / f64::EPSILON;
1122
1123 let ui = x.to_bits();
1124 let e = ((ui >> 52) & 0x7ff) as i32;
1125
1126 if (e >= 0x3ff + 52) || (x == 0.) {
1127 return x;
1128 }
1129 let y = if (ui >> 63) != 0 {
1131 x - TOINT + TOINT - x
1132 } else {
1133 x + TOINT - TOINT - x
1134 };
1135 if e < 0x3ff {
1137 volatile!(y);
1138 return if (ui >> 63) != 0 {
1139 -1.
1140 } else {
1141 0.
1142 };
1143 }
1144 if y > 0. {
1145 x + y - 1.
1146 } else {
1147 x + y
1148 }
1149}
1150
1151#[cfg(all(not(feature = "std"), feature = "floats"))]
1155fn floorf(x: f32) -> f32 {
1156 let mut ui = x.to_bits();
1157 let e = (((ui >> 23) as i32) & 0xff) - 0x7f;
1158
1159 if e >= 23 {
1160 return x;
1161 }
1162 if e >= 0 {
1163 let m: u32 = 0x007fffff >> e;
1164 if (ui & m) == 0 {
1165 return x;
1166 }
1167 volatile!(x + f32::from_bits(0x7b800000));
1168 if ui >> 31 != 0 {
1169 ui += m;
1170 }
1171 ui &= !m;
1172 } else {
1173 volatile!(x + f32::from_bits(0x7b800000));
1174 if ui >> 31 == 0 {
1175 ui = 0;
1176 } else if ui << 1 != 0 {
1177 return -1.0;
1178 }
1179 }
1180 f32::from_bits(ui)
1181}
1182
1183#[allow(clippy::eq_op, clippy::excessive_precision)]
1246#[cfg(all(not(feature = "std"), feature = "floats"))]
1247fn logd(mut x: f64) -> f64 {
1248 const LN2_HI: f64 = 6.93147180369123816490e-01; const LN2_LO: f64 = 1.90821492927058770002e-10; const LG1: f64 = 6.666666666666735130e-01; const LG2: f64 = 3.999999999940941908e-01; const LG3: f64 = 2.857142874366239149e-01; const LG4: f64 = 2.222219843214978396e-01; const LG5: f64 = 1.818357216161805012e-01; const LG6: f64 = 1.531383769920937332e-01; const LG7: f64 = 1.479819860511658591e-01; let x1p54 = f64::from_bits(0x4350000000000000); let mut ui = x.to_bits();
1261 let mut hx: u32 = (ui >> 32) as u32;
1262 let mut k: i32 = 0;
1263
1264 if (hx < 0x00100000) || ((hx >> 31) != 0) {
1265 if ui << 1 == 0 {
1267 return -1. / (x * x); }
1269 if hx >> 31 != 0 {
1270 return (x - x) / 0.0; }
1272 k -= 54;
1274 x *= x1p54;
1275 ui = x.to_bits();
1276 hx = (ui >> 32) as u32;
1277 } else if hx >= 0x7ff00000 {
1278 return x;
1279 } else if hx == 0x3ff00000 && ui << 32 == 0 {
1280 return 0.;
1281 }
1282
1283 hx += 0x3ff00000 - 0x3fe6a09e;
1285 k += ((hx >> 20) as i32) - 0x3ff;
1286 hx = (hx & 0x000fffff) + 0x3fe6a09e;
1287 ui = ((hx as u64) << 32) | (ui & 0xffffffff);
1288 x = f64::from_bits(ui);
1289
1290 let f: f64 = x - 1.0;
1291 let hfsq: f64 = 0.5 * f * f;
1292 let s: f64 = f / (2.0 + f);
1293 let z: f64 = s * s;
1294 let w: f64 = z * z;
1295 let t1: f64 = w * (LG2 + w * (LG4 + w * LG6));
1296 let t2: f64 = z * (LG1 + w * (LG3 + w * (LG5 + w * LG7)));
1297 let r: f64 = t2 + t1;
1298 let dk: f64 = k as f64;
1299 s * (hfsq + r) + dk * LN2_LO - hfsq + f + dk * LN2_HI
1300}
1301
1302#[allow(clippy::eq_op, clippy::excessive_precision)]
1318#[cfg(all(not(feature = "std"), feature = "floats"))]
1319fn logf(mut x: f32) -> f32 {
1320 const LN2_HI: f32 = 6.9313812256e-01; const LN2_LO: f32 = 9.0580006145e-06; const LG1: f32 = 0.66666662693; const LG2: f32 = 0.40000972152; const LG3: f32 = 0.28498786688; const LG4: f32 = 0.24279078841; let x1p25 = f32::from_bits(0x4c000000); let mut ix = x.to_bits();
1331 let mut k = 0i32;
1332
1333 if (ix < 0x00800000) || ((ix >> 31) != 0) {
1334 if ix << 1 == 0 {
1336 return -1. / (x * x); }
1338 if (ix >> 31) != 0 {
1339 return (x - x) / 0.; }
1341 k -= 25;
1343 x *= x1p25;
1344 ix = x.to_bits();
1345 } else if ix >= 0x7f800000 {
1346 return x;
1347 } else if ix == 0x3f800000 {
1348 return 0.;
1349 }
1350
1351 ix += 0x3f800000 - 0x3f3504f3;
1353 k += ((ix >> 23) as i32) - 0x7f;
1354 ix = (ix & 0x007fffff) + 0x3f3504f3;
1355 x = f32::from_bits(ix);
1356
1357 let f = x - 1.;
1358 let s = f / (2. + f);
1359 let z = s * s;
1360 let w = z * z;
1361 let t1 = w * (LG2 + w * LG4);
1362 let t2 = z * (LG1 + w * LG3);
1363 let r = t2 + t1;
1364 let hfsq = 0.5 * f * f;
1365 let dk = k as f32;
1366 s * (hfsq + r) + dk * LN2_LO - hfsq + f + dk * LN2_HI
1367}