1#![cfg_attr(any(), rustfmt::skip)]
8
9use core::{fmt, mem, ops};
10
11#[cfg(feature = "f16")]
12use crate::bf16::bf16;
13#[cfg(feature = "f16")]
14use crate::f16::f16;
15
16pub trait AsPrimitive: Copy + PartialEq + PartialOrd + Send + Sync + Sized {
21 fn as_u8(self) -> u8;
22 fn as_u16(self) -> u16;
23 fn as_u32(self) -> u32;
24 fn as_u64(self) -> u64;
25 fn as_u128(self) -> u128;
26 fn as_usize(self) -> usize;
27 fn as_i8(self) -> i8;
28 fn as_i16(self) -> i16;
29 fn as_i32(self) -> i32;
30 fn as_i64(self) -> i64;
31 fn as_i128(self) -> i128;
32 fn as_isize(self) -> isize;
33 fn as_f32(self) -> f32;
34 fn as_f64(self) -> f64;
35 fn from_u32(value: u32) -> Self;
36 fn from_u64(value: u64) -> Self;
37
38 #[cfg(feature = "f16")]
39 fn as_f16(self) -> f16;
40
41 #[cfg(feature = "f16")]
42 fn as_bf16(self) -> bf16;
43}
44
45macro_rules! as_primitive {
46 ($($t:ty)*) => ($(
47 impl AsPrimitive for $t {
48 #[inline(always)]
49 fn as_u8(self) -> u8 {
50 self as u8
51 }
52
53 #[inline(always)]
54 fn as_u16(self) -> u16 {
55 self as u16
56 }
57
58 #[inline(always)]
59 fn as_u32(self) -> u32 {
60 self as u32
61 }
62
63 #[inline(always)]
64 fn as_u64(self) -> u64 {
65 self as u64
66 }
67
68 #[inline(always)]
69 fn as_u128(self) -> u128 {
70 self as u128
71 }
72
73 #[inline(always)]
74 fn as_usize(self) -> usize {
75 self as usize
76 }
77
78 #[inline(always)]
79 fn as_i8(self) -> i8 {
80 self as i8
81 }
82
83 #[inline(always)]
84 fn as_i16(self) -> i16 {
85 self as i16
86 }
87
88 #[inline(always)]
89 fn as_i32(self) -> i32 {
90 self as i32
91 }
92
93 #[inline(always)]
94 fn as_i64(self) -> i64 {
95 self as i64
96 }
97
98 #[inline(always)]
99 fn as_i128(self) -> i128 {
100 self as i128
101 }
102
103 #[inline(always)]
104 fn as_isize(self) -> isize {
105 self as isize
106 }
107
108 #[inline(always)]
109 fn as_f32(self) -> f32 {
110 self as f32
111 }
112
113 #[inline(always)]
114 fn as_f64(self) -> f64 {
115 self as f64
116 }
117
118 #[inline(always)]
119 fn from_u32(value: u32) -> Self {
120 value as Self
121 }
122
123 #[inline(always)]
124 fn from_u64(value: u64) -> Self {
125 value as Self
126 }
127
128 #[cfg(feature = "f16")]
129 #[inline(always)]
130 fn as_f16(self) -> f16 {
131 f16::from_f32(self as f32)
132 }
133
134 #[cfg(feature = "f16")]
135 #[inline(always)]
136 fn as_bf16(self) -> bf16 {
137 bf16::from_f32(self as f32)
138 }
139 }
140 )*)
141}
142
143as_primitive! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64 }
144
145#[cfg(feature = "f16")]
146macro_rules! half_as_primitive {
147 ($($t:ty)*) => ($(
148 impl AsPrimitive for $t {
149 #[inline(always)]
150 fn as_u8(self) -> u8 {
151 self.as_f32() as u8
152 }
153
154 #[inline(always)]
155 fn as_u16(self) -> u16 {
156 self.as_f32() as u16
157 }
158
159 #[inline(always)]
160 fn as_u32(self) -> u32 {
161 self.as_f32() as u32
162 }
163
164 #[inline(always)]
165 fn as_u64(self) -> u64 {
166 self.as_f32() as u64
167 }
168
169 #[inline(always)]
170 fn as_u128(self) -> u128 {
171 self.as_f32() as u128
172 }
173
174 #[inline(always)]
175 fn as_usize(self) -> usize {
176 self.as_f32() as usize
177 }
178
179 #[inline(always)]
180 fn as_i8(self) -> i8 {
181 self.as_f32() as i8
182 }
183
184 #[inline(always)]
185 fn as_i16(self) -> i16 {
186 self.as_f32() as i16
187 }
188
189 #[inline(always)]
190 fn as_i32(self) -> i32 {
191 self.as_f32() as i32
192 }
193
194 #[inline(always)]
195 fn as_i64(self) -> i64 {
196 self.as_f32() as i64
197 }
198
199 #[inline(always)]
200 fn as_i128(self) -> i128 {
201 self.as_f32() as i128
202 }
203
204 #[inline(always)]
205 fn as_isize(self) -> isize {
206 self.as_f32() as isize
207 }
208
209 #[inline(always)]
210 fn as_f32(self) -> f32 {
211 self.as_f32() as f32
212 }
213
214 #[inline(always)]
215 fn as_f64(self) -> f64 {
216 self.as_f32() as f64
217 }
218
219 #[inline(always)]
220 #[allow(clippy::as_underscore)] fn from_u32(value: u32) -> Self {
222 Self::from_f32(value as _)
223 }
224
225 #[inline(always)]
226 fn from_u64(value: u64) -> Self {
227 _ = value;
228 unimplemented!()
229 }
230
231 #[inline(always)]
232 fn as_f16(self) -> f16 {
233 f16::from_f32(self.as_f32())
234 }
235
236 #[inline(always)]
237 fn as_bf16(self) -> bf16 {
238 bf16::from_f32(self.as_f32())
239 }
240 }
241 )*)
242}
243
244#[cfg(feature = "f16")]
245half_as_primitive! { f16 bf16 }
246
247pub trait AsCast: AsPrimitive {
252 fn as_cast<N: AsPrimitive>(n: N) -> Self;
255}
256
257#[inline(always)]
259pub fn as_cast<U: AsCast, T: AsCast>(t: T) -> U {
260 U::as_cast(t)
261}
262
263macro_rules! as_cast {
264 ($($t:ty, $meth:ident ; )*) => ($(
265 impl AsCast for $t {
266 #[inline(always)]
267 #[allow(clippy::as_underscore)] fn as_cast<N: AsPrimitive>(n: N) -> $t {
269 n.$meth() as _
270 }
271 }
272 )*);
273}
274
275as_cast!(
276 u8, as_u8 ;
277 u16, as_u16 ;
278 u32, as_u32 ;
279 u64, as_u64 ;
280 u128, as_u128 ;
281 usize, as_usize ;
282 i8, as_i8 ;
283 i16, as_i16 ;
284 i32, as_i32 ;
285 i64, as_i64 ;
286 i128, as_i128 ;
287 isize, as_isize ;
288 f32, as_f32 ;
289 f64, as_f64 ;
290);
291
292#[cfg(feature = "f16")]
293as_cast!(
294 f16, as_f16 ;
295 bf16, as_bf16 ;
296);
297
298pub trait Primitive: 'static + fmt::Debug + fmt::Display + AsCast {}
303
304macro_rules! primitive {
305 ($($t:ty)*) => ($(
306 impl Primitive for $t {}
307 )*)
308}
309
310primitive! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64 }
311
312#[cfg(feature = "f16")]
313primitive! { f16 bf16 }
314
315pub trait Number:
320 Default +
321 Primitive +
322 ops::Add<Output=Self> +
324 ops::AddAssign +
325 ops::Div<Output=Self> +
326 ops::DivAssign +
327 ops::Mul<Output=Self> +
328 ops::MulAssign +
329 ops::Rem<Output=Self> +
330 ops::RemAssign +
331 ops::Sub<Output=Self> +
332 ops::SubAssign
333{
334 const IS_SIGNED: bool;
336}
337
338macro_rules! number_impl {
339 ($($t:tt $is_signed:literal ; )*) => ($(
340 impl Number for $t {
341 const IS_SIGNED: bool = $is_signed;
342 }
343 )*)
344}
345
346number_impl! {
347 u8 false ;
348 u16 false ;
349 u32 false ;
350 u64 false ;
351 u128 false ;
352 usize false ;
353 i8 true ;
354 i16 true ;
355 i32 true ;
356 i64 true ;
357 i128 true ;
358 isize true ;
359 f32 true ;
360 f64 true ;
361 }
363
364#[cfg(feature = "f16")]
365number_impl! {
366 f16 true ;
367 bf16 true ;
368}
369
370pub trait Integer:
375 Number + Eq + Ord +
377 ops::BitAnd<Output=Self> +
379 ops::BitAndAssign +
380 ops::BitOr<Output=Self> +
381 ops::BitOrAssign +
382 ops::BitXor<Output=Self> +
383 ops::BitXorAssign +
384 ops::Not<Output=Self> +
385 ops::Shl<Self, Output=Self> +
386 ops::Shl<i32, Output=Self> +
387 ops::ShlAssign<i32> +
388 ops::Shr<i32, Output=Self> +
389 ops::ShrAssign<i32> +
390{
391 const ZERO: Self;
393 const ONE: Self;
394 const TWO: Self;
395 const MAX: Self;
396 const MIN: Self;
397 const BITS: usize;
398
399 fn leading_zeros(self) -> u32;
401 fn trailing_zeros(self) -> u32;
402 fn pow(self, exp: u32) -> Self;
403 fn checked_pow(self, exp: u32) -> Option<Self>;
404 fn overflowing_pow(self, exp: u32) -> (Self, bool);
405 fn checked_add(self, i: Self) -> Option<Self>;
406 fn checked_sub(self, i: Self) -> Option<Self>;
407 fn checked_mul(self, i: Self) -> Option<Self>;
408 fn overflowing_add(self, i: Self) -> (Self, bool);
409 fn overflowing_sub(self, i: Self) -> (Self, bool);
410 fn overflowing_mul(self, i: Self) -> (Self, bool);
411 fn wrapping_add(self, i: Self) -> Self;
412 fn wrapping_sub(self, i: Self) -> Self;
413 fn wrapping_mul(self, i: Self) -> Self;
414 fn wrapping_neg(self) -> Self;
415 fn saturating_add(self, i: Self) -> Self;
416 fn saturating_sub(self, i: Self) -> Self;
417 fn saturating_mul(self, i: Self) -> Self;
418
419 #[inline(always)]
422 fn ceil_divmod(self, y: Self) -> (Self, i32) {
423 let q = self / y;
424 let r = self % y;
425 match r == Self::ZERO {
426 true => (q, i32::as_cast(r)),
427 false => (q + Self::ONE, i32::as_cast(r) - i32::as_cast(y))
428 }
429 }
430
431 #[inline(always)]
434 fn ceil_div(self, y: Self) -> Self {
435 self.ceil_divmod(y).0
436 }
437
438 #[inline(always)]
441 fn ceil_mod(self, y: Self) -> i32 {
442 self.ceil_divmod(y).1
443 }
444
445 #[inline(always)]
449 fn bit_length(self) -> u32 {
450 Self::BITS as u32 - self.leading_zeros()
451 }
452
453 #[inline(always)]
455 fn is_odd(self) -> bool {
456 self & Self::ONE == Self::ONE
457 }
458
459 #[inline(always)]
461 fn is_even(self) -> bool {
462 !self.is_odd()
463 }
464
465 #[inline(always)]
470 fn overflow_digits(radix: u32) -> usize {
471 if radix <= 16 {
474 mem::size_of::<Self>() * 2 - Self::IS_SIGNED as usize
475 } else {
476 mem::size_of::<Self>()
478 }
479 }
480}
481
482macro_rules! integer_impl {
483($($t:tt)*) => ($(
484 impl Integer for $t {
485 const ZERO: $t = 0;
486 const ONE: $t = 1;
487 const TWO: $t = 2;
488 const MAX: $t = $t::MAX;
489 const MIN: $t = $t::MIN;
490 const BITS: usize = $t::BITS as usize;
491
492 #[inline(always)]
493 fn leading_zeros(self) -> u32 {
494 $t::leading_zeros(self)
495 }
496
497 #[inline(always)]
498 fn trailing_zeros(self) -> u32 {
499 $t::trailing_zeros(self)
500 }
501
502 #[inline(always)]
503 fn checked_add(self, i: Self) -> Option<Self> {
504 $t::checked_add(self, i)
505 }
506
507 #[inline(always)]
508 fn checked_sub(self, i: Self) -> Option<Self> {
509 $t::checked_sub(self, i)
510 }
511
512 #[inline(always)]
513 fn checked_mul(self, i: Self) -> Option<Self> {
514 $t::checked_mul(self, i)
515 }
516
517 #[inline(always)]
518 fn overflowing_add(self, i: Self) -> (Self, bool) {
519 $t::overflowing_add(self, i)
520 }
521
522 #[inline(always)]
523 fn overflowing_sub(self, i: Self) -> (Self, bool) {
524 $t::overflowing_sub(self, i)
525 }
526
527 #[inline(always)]
528 fn overflowing_mul(self, i: Self) -> (Self, bool) {
529 $t::overflowing_mul(self, i)
530 }
531
532 #[inline(always)]
533 fn wrapping_add(self, i: Self) -> Self {
534 $t::wrapping_add(self, i)
535 }
536
537 #[inline(always)]
538 fn wrapping_sub(self, i: Self) -> Self {
539 $t::wrapping_sub(self, i)
540 }
541
542 #[inline(always)]
543 fn wrapping_mul(self, i: Self) -> Self {
544 $t::wrapping_mul(self, i)
545 }
546
547 #[inline(always)]
548 fn wrapping_neg(self) -> Self {
549 $t::wrapping_neg(self)
550 }
551
552 #[inline(always)]
553 fn pow(self, exp: u32) -> Self {
554 Self::pow(self, exp)
555 }
556
557 #[inline(always)]
558 fn checked_pow(self, exp: u32) -> Option<Self> {
559 Self::checked_pow(self, exp)
560 }
561
562 #[inline(always)]
563 fn overflowing_pow(self, exp: u32) -> (Self, bool) {
564 Self::overflowing_pow(self, exp)
565 }
566
567 #[inline(always)]
568 fn saturating_add(self, i: Self) -> Self {
569 $t::saturating_add(self, i)
570 }
571
572 #[inline(always)]
573 fn saturating_sub(self, i: Self) -> Self {
574 $t::saturating_sub(self, i)
575 }
576
577 #[inline(always)]
578 fn saturating_mul(self, i: Self) -> Self {
579 $t::saturating_mul(self, i)
580 }
581 }
582)*)
583}
584
585integer_impl! { u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 usize isize }
586
587pub trait SignedInteger: Integer + ops::Neg<Output = Self> {}
592
593macro_rules! signed_integer_impl {
594($($t:tt)*) => ($(
595 impl SignedInteger for $t {}
596)*)
597}
598
599signed_integer_impl! { i8 i16 i32 i64 i128 isize }
600
601pub trait UnsignedInteger: Integer {}
606
607macro_rules! unsigned_integer_impl {
608($($t:ty)*) => ($(
609 impl UnsignedInteger for $t {}
610)*)
611}
612
613unsigned_integer_impl! { u8 u16 u32 u64 u128 usize }
614
615#[cfg(feature = "floats")]
620pub trait Float: Number + ops::Neg<Output = Self> {
621 type Unsigned: UnsignedInteger;
623
624 const ZERO: Self;
626 const ONE: Self;
627 const TWO: Self;
628 const MAX: Self;
629 const MIN: Self;
630 const INFINITY: Self;
631 const NEG_INFINITY: Self;
632 const NAN: Self;
633 const BITS: usize;
634
635 const SIGN_MASK: Self::Unsigned;
637 const EXPONENT_MASK: Self::Unsigned;
639 const HIDDEN_BIT_MASK: Self::Unsigned;
642 const MANTISSA_MASK: Self::Unsigned;
644 const CARRY_MASK: Self::Unsigned;
646
647 const INFINITY_BITS: Self::Unsigned;
658 const NEGATIVE_INFINITY_BITS: Self::Unsigned;
660 const EXPONENT_SIZE: i32;
662 const MANTISSA_SIZE: i32;
664 const EXPONENT_BIAS: i32;
666 const DENORMAL_EXPONENT: i32;
668 const MAX_EXPONENT: i32;
670
671 fn to_bits(self) -> Self::Unsigned;
675 fn from_bits(u: Self::Unsigned) -> Self;
676 fn ln(self) -> Self;
677 fn floor(self) -> Self;
678 fn is_sign_positive(self) -> bool;
679 fn is_sign_negative(self) -> bool;
680
681 #[inline(always)]
683 fn is_denormal(self) -> bool {
684 self.to_bits() & Self::EXPONENT_MASK == Self::Unsigned::ZERO
685 }
686
687 #[inline(always)]
689 fn is_special(self) -> bool {
690 self.to_bits() & Self::EXPONENT_MASK == Self::EXPONENT_MASK
691 }
692
693 #[inline(always)]
695 fn is_nan(self) -> bool {
696 self.is_special() && (self.to_bits() & Self::MANTISSA_MASK) != Self::Unsigned::ZERO
697 }
698
699 #[inline(always)]
701 fn is_inf(self) -> bool {
702 self.is_special() && (self.to_bits() & Self::MANTISSA_MASK) == Self::Unsigned::ZERO
703 }
704
705 #[inline(always)]
707 fn is_odd(self) -> bool {
708 self.to_bits().is_odd()
709 }
710
711 #[inline(always)]
713 fn is_even(self) -> bool {
714 !self.is_odd()
715 }
716
717 #[inline(always)]
722 fn needs_negative_sign(self) -> bool {
723 self.is_sign_negative() && !self.is_nan()
724 }
725
726 #[inline(always)]
728 fn exponent(self) -> i32 {
729 if self.is_denormal() {
730 return Self::DENORMAL_EXPONENT;
731 }
732
733 let bits = self.to_bits();
734 let biased_e = i32::as_cast((bits & Self::EXPONENT_MASK) >> Self::MANTISSA_SIZE).as_i32();
735 biased_e - Self::EXPONENT_BIAS
736 }
737
738 #[inline(always)]
740 fn mantissa(self) -> Self::Unsigned {
741 let bits = self.to_bits();
742 let s = bits & Self::MANTISSA_MASK;
743 if !self.is_denormal() {
744 s + Self::HIDDEN_BIT_MASK
745 } else {
746 s
747 }
748 }
749
750 #[inline(always)]
752 fn next(self) -> Self {
753 let bits = self.to_bits();
754 if self.is_sign_negative() && self == Self::ZERO {
755 Self::ZERO
757 } else if bits == Self::INFINITY_BITS {
758 Self::from_bits(Self::INFINITY_BITS)
759 } else if self.is_sign_negative() {
760 Self::from_bits(bits.saturating_sub(Self::Unsigned::ONE))
761 } else {
762 Self::from_bits(bits.saturating_add(Self::Unsigned::ONE))
763 }
764 }
765
766 #[inline(always)]
769 fn next_positive(self) -> Self {
770 debug_assert!(self.is_sign_positive() && !self.is_inf());
771 Self::from_bits(self.to_bits() + Self::Unsigned::ONE)
772 }
773
774 #[inline(always)]
776 fn prev(self) -> Self {
777 let bits = self.to_bits();
778 if self.is_sign_positive() && self == Self::ZERO {
779 -Self::ZERO
781 } else if bits == Self::NEGATIVE_INFINITY_BITS {
782 Self::from_bits(Self::NEGATIVE_INFINITY_BITS)
783 } else if self.is_sign_negative() {
784 Self::from_bits(bits.saturating_add(Self::Unsigned::ONE))
785 } else {
786 Self::from_bits(bits.saturating_sub(Self::Unsigned::ONE))
787 }
788 }
789
790 #[inline(always)]
793 fn prev_positive(self) -> Self {
794 debug_assert!(self.is_sign_positive() && self != Self::ZERO);
795 Self::from_bits(self.to_bits() - Self::Unsigned::ONE)
796 }
797
798 #[inline(always)]
800 fn round_positive_even(self) -> Self {
801 if self.mantissa().is_odd() {
802 self.next_positive()
803 } else {
804 self
805 }
806 }
807
808 #[inline(always)]
810 fn max_finite(self, f: Self) -> Self {
811 debug_assert!(!self.is_special() && !f.is_special(), "max_finite self={} f={}", self, f);
812 if self < f {
813 f
814 } else {
815 self
816 }
817 }
818
819 #[inline(always)]
821 fn min_finite(self, f: Self) -> Self {
822 debug_assert!(!self.is_special() && !f.is_special(), "min_finite self={} f={}", self, f);
823 if self < f {
824 self
825 } else {
826 f
827 }
828 }
829}
830
831#[cfg(feature = "floats")]
833macro_rules! float_literals {
834 ($float:ty) => {
835 const ZERO: $float = 0.0;
836 const ONE: $float = 1.0;
837 const TWO: $float = 2.0;
838 const MAX: $float = <$float>::MAX;
839 const MIN: $float = <$float>::MIN;
840 const INFINITY: $float = <$float>::INFINITY;
841 const NEG_INFINITY: $float = <$float>::NEG_INFINITY;
842 const NAN: $float = <$float>::NAN;
843 const BITS: usize = mem::size_of::<$float>() * 8;
844 };
845}
846
847#[cfg(feature = "floats")]
849macro_rules! float_masks {
850 (
851 float =>
852 $float:ty,sign_mask =>
853 $sign:literal,exponent_mask =>
854 $exponent:literal,hidden_bit_mask =>
855 $hidden:literal,mantissa_mask =>
856 $mantissa:literal,
857 ) => {
858 const SIGN_MASK: <$float>::Unsigned = $sign;
859 const EXPONENT_MASK: <$float>::Unsigned = $exponent;
860 const HIDDEN_BIT_MASK: <$float>::Unsigned = $hidden;
861 const MANTISSA_MASK: <$float>::Unsigned = $mantissa;
862 const CARRY_MASK: <$float>::Unsigned = $hidden << 1;
864 const INFINITY_BITS: <$float>::Unsigned = $exponent;
866 const NEGATIVE_INFINITY_BITS: <$float>::Unsigned = $exponent | $sign;
868 };
869}
870
871#[cfg(feature = "f16")]
876macro_rules! float_one {
877 ($f:ident) => {
878 (($f::EXPONENT_BIAS - $f::MANTISSA_SIZE) as u16) << $f::MANTISSA_SIZE
879 };
880}
881
882#[cfg(feature = "f16")]
883macro_rules! float_two {
884 ($f:ident) => {
885 (($f::EXPONENT_BIAS - $f::MANTISSA_SIZE + 1) as u16) << $f::MANTISSA_SIZE
886 };
887}
888
889#[cfg(feature = "f16")]
890macro_rules! float_max {
891 ($f:ident) => {
892 ($f::EXPONENT_MASK ^ $f::HIDDEN_BIT_MASK) | $f::MANTISSA_MASK
893 };
894}
895
896#[cfg(feature = "f16")]
897macro_rules! float_min {
898 ($f:ident) => {
899 $f::MAX.to_bits() | $f::SIGN_MASK
900 };
901}
902
903#[cfg(feature = "f16")]
904macro_rules! float_nan {
905 ($f:ident) => {
906 $f::EXPONENT_MASK | ($f::HIDDEN_BIT_MASK >> 1)
907 };
908}
909
910#[cfg(feature = "f16")]
911impl Float for f16 {
912 type Unsigned = u16;
913
914 const ZERO: Self = Self::from_bits(0);
915 const ONE: Self = Self::from_bits(float_one!(Self));
916 const TWO: Self = Self::from_bits(float_two!(Self));
917 const MAX: Self = Self::from_bits(float_max!(Self));
918 const MIN: Self = Self::from_bits(float_min!(Self));
919 const INFINITY: Self = Self::from_bits(Self::INFINITY_BITS);
920 const NEG_INFINITY: Self = Self::from_bits(Self::NEGATIVE_INFINITY_BITS);
921 const NAN: Self = Self::from_bits(float_nan!(Self));
922 const BITS: usize = mem::size_of::<Self>() * 8;
923
924 float_masks!(
925 float => Self,
926 sign_mask => 0x8000,
927 exponent_mask => 0x7C00,
928 hidden_bit_mask => 0x0400,
929 mantissa_mask => 0x03FF,
930 );
931 const EXPONENT_SIZE: i32 = 5;
932 const MANTISSA_SIZE: i32 = 10;
933 const EXPONENT_BIAS: i32 = 15 + Self::MANTISSA_SIZE;
934 const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
935 const MAX_EXPONENT: i32 = 0x1F - Self::EXPONENT_BIAS;
936
937 #[inline(always)]
938 fn to_bits(self) -> u16 {
939 f16::to_bits(self)
940 }
941
942 #[inline(always)]
943 fn from_bits(u: u16) -> f16 {
944 f16::from_bits(u)
945 }
946
947 #[inline(always)]
948 fn ln(self) -> f16 {
949 f16::from_f32(self.as_f32().ln())
950 }
951
952 #[inline(always)]
953 fn floor(self) -> f16 {
954 f16::from_f32(self.as_f32().floor())
955 }
956
957 #[inline(always)]
958 fn is_sign_positive(self) -> bool {
959 self.to_bits() & Self::SIGN_MASK == 0
960 }
961
962 #[inline(always)]
963 fn is_sign_negative(self) -> bool {
964 !self.is_sign_positive()
965 }
966}
967
968#[cfg(feature = "f16")]
969impl Float for bf16 {
970 type Unsigned = u16;
971
972 const ZERO: Self = Self::from_bits(0);
973 const ONE: Self = Self::from_bits(float_one!(Self));
974 const TWO: Self = Self::from_bits(float_two!(Self));
975 const MAX: Self = Self::from_bits(float_max!(Self));
976 const MIN: Self = Self::from_bits(float_min!(Self));
977 const INFINITY: Self = Self::from_bits(Self::INFINITY_BITS);
978 const NEG_INFINITY: Self = Self::from_bits(Self::NEGATIVE_INFINITY_BITS);
979 const NAN: Self = Self::from_bits(float_nan!(Self));
980 const BITS: usize = mem::size_of::<Self>() * 8;
981
982 float_masks!(
983 float => Self,
984 sign_mask => 0x8000,
985 exponent_mask => 0x7F80,
986 hidden_bit_mask => 0x0080,
987 mantissa_mask => 0x007F,
988 );
989 const EXPONENT_SIZE: i32 = 8;
990 const MANTISSA_SIZE: i32 = 7;
991 const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE;
992 const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
993 const MAX_EXPONENT: i32 = 0xFF - Self::EXPONENT_BIAS;
994
995 #[inline(always)]
996 fn to_bits(self) -> u16 {
997 bf16::to_bits(self)
998 }
999
1000 #[inline(always)]
1001 fn from_bits(u: u16) -> bf16 {
1002 bf16::from_bits(u)
1003 }
1004
1005 #[inline(always)]
1006 fn ln(self) -> bf16 {
1007 bf16::from_f32(self.as_f32().ln())
1008 }
1009
1010 #[inline(always)]
1011 fn floor(self) -> bf16 {
1012 bf16::from_f32(self.as_f32().floor())
1013 }
1014
1015 #[inline(always)]
1016 fn is_sign_positive(self) -> bool {
1017 self.to_bits() & Self::SIGN_MASK == 0
1018 }
1019
1020 #[inline(always)]
1021 fn is_sign_negative(self) -> bool {
1022 !self.is_sign_positive()
1023 }
1024}
1025
1026#[cfg(feature = "floats")]
1027impl Float for f32 {
1028 type Unsigned = u32;
1029 float_literals!(f32);
1030 float_masks!(
1031 float => Self,
1032 sign_mask => 0x80000000,
1033 exponent_mask => 0x7F800000,
1034 hidden_bit_mask => 0x00800000,
1035 mantissa_mask => 0x007FFFFF,
1036 );
1037 const EXPONENT_SIZE: i32 = 8;
1038 const MANTISSA_SIZE: i32 = 23;
1039 const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE;
1040 const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
1041 const MAX_EXPONENT: i32 = 0xFF - Self::EXPONENT_BIAS;
1042
1043 #[inline(always)]
1044 fn to_bits(self) -> u32 {
1045 f32::to_bits(self)
1046 }
1047
1048 #[inline(always)]
1049 fn from_bits(u: u32) -> f32 {
1050 f32::from_bits(u)
1051 }
1052
1053 #[inline(always)]
1054 fn ln(self) -> f32 {
1055 #[cfg(feature = "std")]
1056 return f32::ln(self);
1057
1058 #[cfg(not(feature = "std"))]
1059 return logf(self);
1060 }
1061
1062 #[inline(always)]
1063 fn floor(self) -> f32 {
1064 #[cfg(feature = "std")]
1065 return f32::floor(self);
1066
1067 #[cfg(not(feature = "std"))]
1068 return floorf(self);
1069 }
1070
1071 #[inline(always)]
1072 fn is_sign_positive(self) -> bool {
1073 f32::is_sign_positive(self)
1074 }
1075
1076 #[inline(always)]
1077 fn is_sign_negative(self) -> bool {
1078 f32::is_sign_negative(self)
1079 }
1080}
1081
1082#[cfg(feature = "floats")]
1083impl Float for f64 {
1084 type Unsigned = u64;
1085 float_literals!(f64);
1086 float_masks!(
1087 float => Self,
1088 sign_mask => 0x8000000000000000,
1089 exponent_mask => 0x7FF0000000000000,
1090 hidden_bit_mask => 0x0010000000000000,
1091 mantissa_mask => 0x000FFFFFFFFFFFFF,
1092 );
1093 const EXPONENT_SIZE: i32 = 11;
1094 const MANTISSA_SIZE: i32 = 52;
1095 const EXPONENT_BIAS: i32 = 1023 + Self::MANTISSA_SIZE;
1096 const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
1097 const MAX_EXPONENT: i32 = 0x7FF - Self::EXPONENT_BIAS;
1098
1099 #[inline(always)]
1100 fn to_bits(self) -> u64 {
1101 f64::to_bits(self)
1102 }
1103
1104 #[inline(always)]
1105 fn from_bits(u: u64) -> f64 {
1106 f64::from_bits(u)
1107 }
1108
1109 #[inline(always)]
1110 fn ln(self) -> f64 {
1111 #[cfg(feature = "std")]
1112 return f64::ln(self);
1113
1114 #[cfg(not(feature = "std"))]
1115 return logd(self);
1116 }
1117
1118 #[inline(always)]
1119 fn floor(self) -> f64 {
1120 #[cfg(feature = "std")]
1121 return f64::floor(self);
1122
1123 #[cfg(not(feature = "std"))]
1124 return floord(self);
1125 }
1126
1127 #[inline(always)]
1128 fn is_sign_positive(self) -> bool {
1129 f64::is_sign_positive(self)
1130 }
1131
1132 #[inline(always)]
1133 fn is_sign_negative(self) -> bool {
1134 f64::is_sign_negative(self)
1135 }
1136}
1137
1138#[cfg(all(not(feature = "std"), feature = "floats"))]
1167macro_rules! volatile {
1168($e:expr) => {
1169 unsafe {
1171 core::ptr::read_volatile(&$e);
1172 }
1173};
1174}
1175
1176#[cfg(all(not(feature = "std"), feature = "floats"))]
1180fn floord(x: f64) -> f64 {
1181 const TOINT: f64 = 1. / f64::EPSILON;
1182
1183 let ui = x.to_bits();
1184 let e = ((ui >> 52) & 0x7ff) as i32;
1185
1186 if (e >= 0x3ff + 52) || (x == 0.) {
1187 return x;
1188 }
1189 let y = if (ui >> 63) != 0 {
1191 x - TOINT + TOINT - x
1192 } else {
1193 x + TOINT - TOINT - x
1194 };
1195 if e < 0x3ff {
1197 volatile!(y);
1198 return if (ui >> 63) != 0 {
1199 -1.
1200 } else {
1201 0.
1202 };
1203 }
1204 if y > 0. {
1205 x + y - 1.
1206 } else {
1207 x + y
1208 }
1209}
1210
1211#[cfg(all(not(feature = "std"), feature = "floats"))]
1215fn floorf(x: f32) -> f32 {
1216 let mut ui = x.to_bits();
1217 let e = (((ui >> 23) as i32) & 0xff) - 0x7f;
1218
1219 if e >= 23 {
1220 return x;
1221 }
1222 if e >= 0 {
1223 let m: u32 = 0x007fffff >> e;
1224 if (ui & m) == 0 {
1225 return x;
1226 }
1227 volatile!(x + f32::from_bits(0x7b800000));
1228 if ui >> 31 != 0 {
1229 ui += m;
1230 }
1231 ui &= !m;
1232 } else {
1233 volatile!(x + f32::from_bits(0x7b800000));
1234 if ui >> 31 == 0 {
1235 ui = 0;
1236 } else if ui << 1 != 0 {
1237 return -1.0;
1238 }
1239 }
1240 f32::from_bits(ui)
1241}
1242
1243#[allow(clippy::eq_op, clippy::excessive_precision)] #[cfg(all(not(feature = "std"), feature = "floats"))]
1307fn logd(mut x: f64) -> f64 {
1308 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();
1321 let mut hx: u32 = (ui >> 32) as u32;
1322 let mut k: i32 = 0;
1323
1324 if (hx < 0x00100000) || ((hx >> 31) != 0) {
1325 if ui << 1 == 0 {
1327 return -1. / (x * x); }
1329 if hx >> 31 != 0 {
1330 return (x - x) / 0.0; }
1332 k -= 54;
1334 x *= x1p54;
1335 ui = x.to_bits();
1336 hx = (ui >> 32) as u32;
1337 } else if hx >= 0x7ff00000 {
1338 return x;
1339 } else if hx == 0x3ff00000 && ui << 32 == 0 {
1340 return 0.;
1341 }
1342
1343 hx += 0x3ff00000 - 0x3fe6a09e;
1345 k += ((hx >> 20) as i32) - 0x3ff;
1346 hx = (hx & 0x000fffff) + 0x3fe6a09e;
1347 ui = ((hx as u64) << 32) | (ui & 0xffffffff);
1348 x = f64::from_bits(ui);
1349
1350 let f: f64 = x - 1.0;
1351 let hfsq: f64 = 0.5 * f * f;
1352 let s: f64 = f / (2.0 + f);
1353 let z: f64 = s * s;
1354 let w: f64 = z * z;
1355 let t1: f64 = w * (LG2 + w * (LG4 + w * LG6));
1356 let t2: f64 = z * (LG1 + w * (LG3 + w * (LG5 + w * LG7)));
1357 let r: f64 = t2 + t1;
1358 let dk: f64 = k as f64;
1359 s * (hfsq + r) + dk * LN2_LO - hfsq + f + dk * LN2_HI
1360}
1361
1362#[allow(clippy::eq_op, clippy::excessive_precision)] #[cfg(all(not(feature = "std"), feature = "floats"))]
1379fn logf(mut x: f32) -> f32 {
1380 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();
1391 let mut k = 0i32;
1392
1393 if (ix < 0x00800000) || ((ix >> 31) != 0) {
1394 if ix << 1 == 0 {
1396 return -1. / (x * x); }
1398 if (ix >> 31) != 0 {
1399 return (x - x) / 0.; }
1401 k -= 25;
1403 x *= x1p25;
1404 ix = x.to_bits();
1405 } else if ix >= 0x7f800000 {
1406 return x;
1407 } else if ix == 0x3f800000 {
1408 return 0.;
1409 }
1410
1411 ix += 0x3f800000 - 0x3f3504f3;
1413 k += ((ix >> 23) as i32) - 0x7f;
1414 ix = (ix & 0x007fffff) + 0x3f3504f3;
1415 x = f32::from_bits(ix);
1416
1417 let f = x - 1.;
1418 let s = f / (2. + f);
1419 let z = s * s;
1420 let w = z * z;
1421 let t1 = w * (LG2 + w * LG4);
1422 let t2 = z * (LG1 + w * LG3);
1423 let r = t2 + t1;
1424 let hfsq = 0.5 * f * f;
1425 let dk = k as f32;
1426 s * (hfsq + r) + dk * LN2_LO - hfsq + f + dk * LN2_HI
1427}