1use core::{fmt, mem, ops};
8
9#[cfg(feature = "f16")]
10use crate::bf16::bf16;
11#[cfg(feature = "f16")]
12use crate::f16::f16;
13#[cfg(all(not(feature = "std"), any(feature = "parse-floats", feature = "write-floats")))]
14use crate::libm;
15
16pub trait AsPrimitive: Copy + PartialEq + PartialOrd + Send + Sync + Sized {
23 fn as_u8(self) -> u8;
25
26 fn as_u16(self) -> u16;
28
29 fn as_u32(self) -> u32;
31
32 fn as_u64(self) -> u64;
34
35 fn as_u128(self) -> u128;
37
38 fn as_usize(self) -> usize;
40
41 fn as_i8(self) -> i8;
43
44 fn as_i16(self) -> i16;
46
47 fn as_i32(self) -> i32;
49
50 fn as_i64(self) -> i64;
52
53 fn as_i128(self) -> i128;
55
56 fn as_isize(self) -> isize;
58
59 fn as_f32(self) -> f32;
61
62 fn as_f64(self) -> f64;
64
65 fn from_u32(value: u32) -> Self;
67
68 fn from_u64(value: u64) -> Self;
70
71 #[cfg(feature = "f16")]
74 fn as_f16(self) -> f16;
75
76 #[cfg(feature = "f16")]
79 fn as_bf16(self) -> bf16;
80}
81
82macro_rules! as_primitive {
83 ($($t:ty)*) => ($(
84 impl AsPrimitive for $t {
85 #[inline(always)]
86 fn as_u8(self) -> u8 {
87 self as u8
88 }
89
90 #[inline(always)]
91 fn as_u16(self) -> u16 {
92 self as u16
93 }
94
95 #[inline(always)]
96 fn as_u32(self) -> u32 {
97 self as u32
98 }
99
100 #[inline(always)]
101 fn as_u64(self) -> u64 {
102 self as u64
103 }
104
105 #[inline(always)]
106 fn as_u128(self) -> u128 {
107 self as u128
108 }
109
110 #[inline(always)]
111 fn as_usize(self) -> usize {
112 self as usize
113 }
114
115 #[inline(always)]
116 fn as_i8(self) -> i8 {
117 self as i8
118 }
119
120 #[inline(always)]
121 fn as_i16(self) -> i16 {
122 self as i16
123 }
124
125 #[inline(always)]
126 fn as_i32(self) -> i32 {
127 self as i32
128 }
129
130 #[inline(always)]
131 fn as_i64(self) -> i64 {
132 self as i64
133 }
134
135 #[inline(always)]
136 fn as_i128(self) -> i128 {
137 self as i128
138 }
139
140 #[inline(always)]
141 fn as_isize(self) -> isize {
142 self as isize
143 }
144
145 #[inline(always)]
146 fn as_f32(self) -> f32 {
147 self as f32
148 }
149
150 #[inline(always)]
151 fn as_f64(self) -> f64 {
152 self as f64
153 }
154
155 #[inline(always)]
156 fn from_u32(value: u32) -> Self {
157 value as Self
158 }
159
160 #[inline(always)]
161 fn from_u64(value: u64) -> Self {
162 value as Self
163 }
164
165 #[cfg(feature = "f16")]
166 #[inline(always)]
167 fn as_f16(self) -> f16 {
168 f16::from_f32(self as f32)
169 }
170
171 #[cfg(feature = "f16")]
172 #[inline(always)]
173 fn as_bf16(self) -> bf16 {
174 bf16::from_f32(self as f32)
175 }
176 }
177 )*)
178}
179
180as_primitive! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64 }
181
182#[cfg(feature = "f16")]
183macro_rules! half_as_primitive {
184 ($($t:ty)*) => ($(
185 impl AsPrimitive for $t {
186 #[inline(always)]
187 fn as_u8(self) -> u8 {
188 self.as_f32() as u8
189 }
190
191 #[inline(always)]
192 fn as_u16(self) -> u16 {
193 self.as_f32() as u16
194 }
195
196 #[inline(always)]
197 fn as_u32(self) -> u32 {
198 self.as_f32() as u32
199 }
200
201 #[inline(always)]
202 fn as_u64(self) -> u64 {
203 self.as_f32() as u64
204 }
205
206 #[inline(always)]
207 fn as_u128(self) -> u128 {
208 self.as_f32() as u128
209 }
210
211 #[inline(always)]
212 fn as_usize(self) -> usize {
213 self.as_f32() as usize
214 }
215
216 #[inline(always)]
217 fn as_i8(self) -> i8 {
218 self.as_f32() as i8
219 }
220
221 #[inline(always)]
222 fn as_i16(self) -> i16 {
223 self.as_f32() as i16
224 }
225
226 #[inline(always)]
227 fn as_i32(self) -> i32 {
228 self.as_f32() as i32
229 }
230
231 #[inline(always)]
232 fn as_i64(self) -> i64 {
233 self.as_f32() as i64
234 }
235
236 #[inline(always)]
237 fn as_i128(self) -> i128 {
238 self.as_f32() as i128
239 }
240
241 #[inline(always)]
242 fn as_isize(self) -> isize {
243 self.as_f32() as isize
244 }
245
246 #[inline(always)]
247 fn as_f32(self) -> f32 {
248 self.as_f32() as f32
249 }
250
251 #[inline(always)]
252 fn as_f64(self) -> f64 {
253 self.as_f32() as f64
254 }
255
256 #[inline(always)]
257 #[allow(clippy::as_underscore)] fn from_u32(value: u32) -> Self {
259 Self::from_f32(value as _)
260 }
261
262 #[inline(always)]
263 fn from_u64(value: u64) -> Self {
264 _ = value;
265 unimplemented!()
266 }
267
268 #[inline(always)]
269 fn as_f16(self) -> f16 {
270 f16::from_f32(self.as_f32())
271 }
272
273 #[inline(always)]
274 fn as_bf16(self) -> bf16 {
275 bf16::from_f32(self.as_f32())
276 }
277 }
278 )*)
279}
280
281#[cfg(feature = "f16")]
282half_as_primitive! { f16 bf16 }
283
284pub trait AsCast: AsPrimitive {
293 fn as_cast<N: AsPrimitive>(n: N) -> Self;
304}
305
306#[inline(always)]
316pub fn as_cast<U: AsCast, T: AsCast>(t: T) -> U {
317 U::as_cast(t)
318}
319
320macro_rules! as_cast {
321 ($($t:ty, $meth:ident ; )*) => ($(
322 impl AsCast for $t {
323 #[inline(always)]
324 #[allow(clippy::as_underscore)] fn as_cast<N: AsPrimitive>(n: N) -> $t {
326 n.$meth() as _
327 }
328 }
329 )*);
330}
331
332as_cast!(
333 u8, as_u8 ;
334 u16, as_u16 ;
335 u32, as_u32 ;
336 u64, as_u64 ;
337 u128, as_u128 ;
338 usize, as_usize ;
339 i8, as_i8 ;
340 i16, as_i16 ;
341 i32, as_i32 ;
342 i64, as_i64 ;
343 i128, as_i128 ;
344 isize, as_isize ;
345 f32, as_f32 ;
346 f64, as_f64 ;
347);
348
349#[cfg(feature = "f16")]
350as_cast!(
351 f16, as_f16 ;
352 bf16, as_bf16 ;
353);
354
355pub trait Primitive: 'static + fmt::Debug + fmt::Display + AsCast {}
362
363macro_rules! primitive {
364 ($($t:ty)*) => ($(
365 impl Primitive for $t {}
366 )*)
367}
368
369primitive! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64 }
370
371#[cfg(feature = "f16")]
372primitive! { f16 bf16 }
373
374pub trait Number:
379 Default +
380 Primitive +
381 ops::Add<Output=Self> +
383 ops::AddAssign +
384 ops::Div<Output=Self> +
385 ops::DivAssign +
386 ops::Mul<Output=Self> +
387 ops::MulAssign +
388 ops::Rem<Output=Self> +
389 ops::RemAssign +
390 ops::Sub<Output=Self> +
391 ops::SubAssign
392{
393 const IS_SIGNED: bool;
395}
396
397macro_rules! number_impl {
398 ($($t:tt $is_signed:literal ; )*) => ($(
399 impl Number for $t {
400 const IS_SIGNED: bool = $is_signed;
401 }
402 )*)
403}
404
405number_impl! {
406 u8 false ;
407 u16 false ;
408 u32 false ;
409 u64 false ;
410 u128 false ;
411 usize false ;
412 i8 true ;
413 i16 true ;
414 i32 true ;
415 i64 true ;
416 i128 true ;
417 isize true ;
418 f32 true ;
419 f64 true ;
420 }
422
423#[cfg(feature = "f16")]
424number_impl! {
425 f16 true ;
426 bf16 true ;
427}
428
429pub trait Integer:
436 Number + Eq + Ord +
438 ops::BitAnd<Output=Self> +
440 ops::BitAndAssign +
441 ops::BitOr<Output=Self> +
442 ops::BitOrAssign +
443 ops::BitXor<Output=Self> +
444 ops::BitXorAssign +
445 ops::Not<Output=Self> +
446 ops::Shl<Self, Output=Self> +
447 ops::Shl<i32, Output=Self> +
448 ops::ShlAssign<i32> +
449 ops::Shr<i32, Output=Self> +
450 ops::ShrAssign<i32> +
451{
452 const ZERO: Self;
455
456 const ONE: Self;
458
459 const TWO: Self;
461
462 const MAX: Self;
466
467 const MIN: Self;
471
472 const BITS: usize;
476
477 fn leading_zeros(self) -> u32;
483
484 fn trailing_zeros(self) -> u32;
489
490 fn pow(self, exp: u32) -> Self;
494
495 fn checked_pow(self, exp: u32) -> Option<Self>;
500
501 fn overflowing_pow(self, exp: u32) -> (Self, bool);
508
509 fn checked_add(self, i: Self) -> Option<Self>;
514
515 fn checked_sub(self, i: Self) -> Option<Self>;
520
521 fn checked_mul(self, i: Self) -> Option<Self>;
526
527 fn overflowing_add(self, i: Self) -> (Self, bool);
533
534 fn overflowing_sub(self, i: Self) -> (Self, bool);
540
541 fn overflowing_mul(self, i: Self) -> (Self, bool);
547
548 fn wrapping_add(self, i: Self) -> Self;
553
554 fn wrapping_sub(self, i: Self) -> Self;
559
560 fn wrapping_mul(self, i: Self) -> Self;
565
566 fn wrapping_neg(self) -> Self;
571
572 fn saturating_add(self, i: Self) -> Self;
577
578 fn saturating_sub(self, i: Self) -> Self;
583
584 fn saturating_mul(self, i: Self) -> Self;
589
590 #[inline(always)]
608 fn ceil_divmod(self, y: Self) -> (Self, i32) {
609 let q = self / y;
610 let r = self % y;
611 match r == Self::ZERO {
612 true => (q, i32::as_cast(r)),
613 false => (q + Self::ONE, i32::as_cast(r) - i32::as_cast(y))
614 }
615 }
616
617 #[inline(always)]
632 fn ceil_div(self, y: Self) -> Self {
633 self.ceil_divmod(y).0
634 }
635
636 #[inline(always)]
654 fn ceil_mod(self, y: Self) -> i32 {
655 self.ceil_divmod(y).1
656 }
657
658 #[inline(always)]
673 fn bit_length(self) -> u32 {
674 Self::BITS as u32 - self.leading_zeros()
675 }
676
677 #[inline(always)]
679 fn is_odd(self) -> bool {
680 self & Self::ONE == Self::ONE
681 }
682
683 #[inline(always)]
685 fn is_even(self) -> bool {
686 !self.is_odd()
687 }
688
689 #[inline(always)]
694 fn overflow_digits(radix: u32) -> usize {
695 if radix <= 16 {
698 mem::size_of::<Self>() * 2 - Self::IS_SIGNED as usize
699 } else {
700 mem::size_of::<Self>()
702 }
703 }
704}
705
706macro_rules! integer_impl {
707($($t:tt)*) => ($(
708 impl Integer for $t {
709 const ZERO: $t = 0;
710 const ONE: $t = 1;
711 const TWO: $t = 2;
712 const MAX: $t = $t::MAX;
713 const MIN: $t = $t::MIN;
714 const BITS: usize = $t::BITS as usize;
715
716 #[inline(always)]
717 fn leading_zeros(self) -> u32 {
718 $t::leading_zeros(self)
719 }
720
721 #[inline(always)]
722 fn trailing_zeros(self) -> u32 {
723 $t::trailing_zeros(self)
724 }
725
726 #[inline(always)]
727 fn checked_add(self, i: Self) -> Option<Self> {
728 $t::checked_add(self, i)
729 }
730
731 #[inline(always)]
732 fn checked_sub(self, i: Self) -> Option<Self> {
733 $t::checked_sub(self, i)
734 }
735
736 #[inline(always)]
737 fn checked_mul(self, i: Self) -> Option<Self> {
738 $t::checked_mul(self, i)
739 }
740
741 #[inline(always)]
742 fn overflowing_add(self, i: Self) -> (Self, bool) {
743 $t::overflowing_add(self, i)
744 }
745
746 #[inline(always)]
747 fn overflowing_sub(self, i: Self) -> (Self, bool) {
748 $t::overflowing_sub(self, i)
749 }
750
751 #[inline(always)]
752 fn overflowing_mul(self, i: Self) -> (Self, bool) {
753 $t::overflowing_mul(self, i)
754 }
755
756 #[inline(always)]
757 fn wrapping_add(self, i: Self) -> Self {
758 $t::wrapping_add(self, i)
759 }
760
761 #[inline(always)]
762 fn wrapping_sub(self, i: Self) -> Self {
763 $t::wrapping_sub(self, i)
764 }
765
766 #[inline(always)]
767 fn wrapping_mul(self, i: Self) -> Self {
768 $t::wrapping_mul(self, i)
769 }
770
771 #[inline(always)]
772 fn wrapping_neg(self) -> Self {
773 $t::wrapping_neg(self)
774 }
775
776 #[inline(always)]
777 fn pow(self, exp: u32) -> Self {
778 Self::pow(self, exp)
779 }
780
781 #[inline(always)]
782 fn checked_pow(self, exp: u32) -> Option<Self> {
783 Self::checked_pow(self, exp)
784 }
785
786 #[inline(always)]
787 fn overflowing_pow(self, exp: u32) -> (Self, bool) {
788 Self::overflowing_pow(self, exp)
789 }
790
791 #[inline(always)]
792 fn saturating_add(self, i: Self) -> Self {
793 $t::saturating_add(self, i)
794 }
795
796 #[inline(always)]
797 fn saturating_sub(self, i: Self) -> Self {
798 $t::saturating_sub(self, i)
799 }
800
801 #[inline(always)]
802 fn saturating_mul(self, i: Self) -> Self {
803 $t::saturating_mul(self, i)
804 }
805 }
806)*)
807}
808
809integer_impl! { u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 usize isize }
810
811pub trait SignedInteger: Integer + ops::Neg<Output = Self> {}
819
820macro_rules! signed_integer_impl {
821($($t:tt)*) => ($(
822 impl SignedInteger for $t {}
823)*)
824}
825
826signed_integer_impl! { i8 i16 i32 i64 i128 isize }
827
828pub trait UnsignedInteger: Integer {}
836
837macro_rules! unsigned_integer_impl {
838($($t:ty)*) => ($(
839 impl UnsignedInteger for $t {}
840)*)
841}
842
843unsigned_integer_impl! { u8 u16 u32 u64 u128 usize }
844
845#[cfg(any(feature = "parse-floats", feature = "write-floats"))]
856pub trait Float: Number + ops::Neg<Output = Self> {
857 type Unsigned: UnsignedInteger;
859
860 const ZERO: Self;
864
865 const ONE: Self;
867
868 const TWO: Self;
870
871 const MAX: Self;
875
876 const MIN: Self;
880
881 const INFINITY: Self;
885
886 const NEG_INFINITY: Self;
890
891 const NAN: Self;
895
896 const BITS: usize;
900
901 const SIGN_MASK: Self::Unsigned;
903
904 const EXPONENT_MASK: Self::Unsigned;
906
907 const HIDDEN_BIT_MASK: Self::Unsigned;
910
911 const MANTISSA_MASK: Self::Unsigned;
914
915 const CARRY_MASK: Self::Unsigned;
917
918 const INFINITY_BITS: Self::Unsigned;
929
930 const NEGATIVE_INFINITY_BITS: Self::Unsigned;
932
933 const EXPONENT_SIZE: i32;
935
936 const MANTISSA_SIZE: i32;
938
939 const EXPONENT_BIAS: i32;
943
944 const DENORMAL_EXPONENT: i32;
948
949 const MAX_EXPONENT: i32;
951
952 fn to_bits(self) -> Self::Unsigned;
960
961 fn from_bits(u: Self::Unsigned) -> Self;
965
966 fn ln(self) -> Self;
970
971 fn floor(self) -> Self;
975
976 fn is_sign_positive(self) -> bool;
981
982 fn is_sign_negative(self) -> bool;
987
988 #[inline(always)]
996 fn is_denormal(self) -> bool {
997 self.to_bits() & Self::EXPONENT_MASK == Self::Unsigned::ZERO
998 }
999
1000 #[inline(always)]
1003 fn is_special(self) -> bool {
1004 self.to_bits() & Self::EXPONENT_MASK == Self::EXPONENT_MASK
1005 }
1006
1007 #[inline(always)]
1009 fn is_nan(self) -> bool {
1010 self.is_special() && (self.to_bits() & Self::MANTISSA_MASK) != Self::Unsigned::ZERO
1011 }
1012
1013 #[inline(always)]
1015 fn is_inf(self) -> bool {
1016 self.is_special() && (self.to_bits() & Self::MANTISSA_MASK) == Self::Unsigned::ZERO
1017 }
1018
1019 #[inline(always)]
1021 fn is_odd(self) -> bool {
1022 self.to_bits().is_odd()
1023 }
1024
1025 #[inline(always)]
1027 fn is_even(self) -> bool {
1028 !self.is_odd()
1029 }
1030
1031 #[inline(always)]
1036 fn needs_negative_sign(self) -> bool {
1037 self.is_sign_negative() && !self.is_nan()
1038 }
1039
1040 #[inline(always)]
1042 fn exponent(self) -> i32 {
1043 if self.is_denormal() {
1044 return Self::DENORMAL_EXPONENT;
1045 }
1046
1047 let bits = self.to_bits();
1048 let biased_e = i32::as_cast((bits & Self::EXPONENT_MASK) >> Self::MANTISSA_SIZE).as_i32();
1049 biased_e - Self::EXPONENT_BIAS
1050 }
1051
1052 #[inline(always)]
1054 fn mantissa(self) -> Self::Unsigned {
1055 let bits = self.to_bits();
1056 let s = bits & Self::MANTISSA_MASK;
1057 if !self.is_denormal() {
1058 s + Self::HIDDEN_BIT_MASK
1059 } else {
1060 s
1061 }
1062 }
1063
1064 #[inline(always)]
1076 fn next(self) -> Self {
1077 let bits = self.to_bits();
1078 if self.is_sign_negative() && self == Self::ZERO {
1079 Self::ZERO
1081 } else if bits == Self::INFINITY_BITS {
1082 Self::from_bits(Self::INFINITY_BITS)
1083 } else if self.is_sign_negative() {
1084 Self::from_bits(bits.saturating_sub(Self::Unsigned::ONE))
1085 } else {
1086 Self::from_bits(bits.saturating_add(Self::Unsigned::ONE))
1087 }
1088 }
1089
1090 #[inline(always)]
1094 fn next_positive(self) -> Self {
1095 debug_assert!(self.is_sign_positive() && !self.is_inf());
1096 Self::from_bits(self.to_bits() + Self::Unsigned::ONE)
1097 }
1098
1099 #[inline(always)]
1111 fn prev(self) -> Self {
1112 let bits = self.to_bits();
1113 if self.is_sign_positive() && self == Self::ZERO {
1114 -Self::ZERO
1116 } else if bits == Self::NEGATIVE_INFINITY_BITS {
1117 Self::from_bits(Self::NEGATIVE_INFINITY_BITS)
1118 } else if self.is_sign_negative() {
1119 Self::from_bits(bits.saturating_add(Self::Unsigned::ONE))
1120 } else {
1121 Self::from_bits(bits.saturating_sub(Self::Unsigned::ONE))
1122 }
1123 }
1124
1125 #[inline(always)]
1128 fn prev_positive(self) -> Self {
1129 debug_assert!(self.is_sign_positive() && self != Self::ZERO);
1130 Self::from_bits(self.to_bits() - Self::Unsigned::ONE)
1131 }
1132
1133 #[inline(always)]
1135 fn round_positive_even(self) -> Self {
1136 if self.mantissa().is_odd() {
1137 self.next_positive()
1138 } else {
1139 self
1140 }
1141 }
1142
1143 #[inline(always)]
1153 fn max_finite(self, f: Self) -> Self {
1154 debug_assert!(!self.is_special() && !f.is_special(), "max_finite self={} f={}", self, f);
1155 if self < f {
1156 f
1157 } else {
1158 self
1159 }
1160 }
1161
1162 #[inline(always)]
1172 fn min_finite(self, f: Self) -> Self {
1173 debug_assert!(!self.is_special() && !f.is_special(), "min_finite self={} f={}", self, f);
1174 if self < f {
1175 self
1176 } else {
1177 f
1178 }
1179 }
1180}
1181
1182#[cfg(any(feature = "parse-floats", feature = "write-floats"))]
1184macro_rules! float_literals {
1185 ($float:ty) => {
1186 const ZERO: $float = 0.0;
1187 const ONE: $float = 1.0;
1188 const TWO: $float = 2.0;
1189 const MAX: $float = <$float>::MAX;
1190 const MIN: $float = <$float>::MIN;
1191 const INFINITY: $float = <$float>::INFINITY;
1192 const NEG_INFINITY: $float = <$float>::NEG_INFINITY;
1193 const NAN: $float = <$float>::NAN;
1194 const BITS: usize = mem::size_of::<$float>() * 8;
1195 };
1196}
1197
1198#[cfg(any(feature = "parse-floats", feature = "write-floats"))]
1200macro_rules! float_masks {
1201 (
1202 float =>
1203 $float:ty,sign_mask =>
1204 $sign:literal,exponent_mask =>
1205 $exponent:literal,hidden_bit_mask =>
1206 $hidden:literal,mantissa_mask =>
1207 $mantissa:literal,
1208 ) => {
1209 const SIGN_MASK: <$float>::Unsigned = $sign;
1210 const EXPONENT_MASK: <$float>::Unsigned = $exponent;
1211 const HIDDEN_BIT_MASK: <$float>::Unsigned = $hidden;
1212 const MANTISSA_MASK: <$float>::Unsigned = $mantissa;
1213 const CARRY_MASK: <$float>::Unsigned = $hidden << 1;
1215 const INFINITY_BITS: <$float>::Unsigned = $exponent;
1217 const NEGATIVE_INFINITY_BITS: <$float>::Unsigned = $exponent | $sign;
1219 };
1220}
1221
1222#[cfg(feature = "f16")]
1227macro_rules! float_one {
1228 ($f:ident) => {
1229 (($f::EXPONENT_BIAS - $f::MANTISSA_SIZE) as u16) << $f::MANTISSA_SIZE
1230 };
1231}
1232
1233#[cfg(feature = "f16")]
1234macro_rules! float_two {
1235 ($f:ident) => {
1236 (($f::EXPONENT_BIAS - $f::MANTISSA_SIZE + 1) as u16) << $f::MANTISSA_SIZE
1237 };
1238}
1239
1240#[cfg(feature = "f16")]
1241macro_rules! float_max {
1242 ($f:ident) => {
1243 ($f::EXPONENT_MASK ^ $f::HIDDEN_BIT_MASK) | $f::MANTISSA_MASK
1244 };
1245}
1246
1247#[cfg(feature = "f16")]
1248macro_rules! float_min {
1249 ($f:ident) => {
1250 $f::MAX.to_bits() | $f::SIGN_MASK
1251 };
1252}
1253
1254#[cfg(feature = "f16")]
1255macro_rules! float_nan {
1256 ($f:ident) => {
1257 $f::EXPONENT_MASK | ($f::HIDDEN_BIT_MASK >> 1)
1258 };
1259}
1260
1261#[cfg(feature = "f16")]
1262impl Float for f16 {
1263 type Unsigned = u16;
1264
1265 const ZERO: Self = Self::from_bits(0);
1266 const ONE: Self = Self::from_bits(float_one!(Self));
1267 const TWO: Self = Self::from_bits(float_two!(Self));
1268 const MAX: Self = Self::from_bits(float_max!(Self));
1269 const MIN: Self = Self::from_bits(float_min!(Self));
1270 const INFINITY: Self = Self::from_bits(Self::INFINITY_BITS);
1271 const NEG_INFINITY: Self = Self::from_bits(Self::NEGATIVE_INFINITY_BITS);
1272 const NAN: Self = Self::from_bits(float_nan!(Self));
1273 const BITS: usize = mem::size_of::<Self>() * 8;
1274
1275 float_masks!(
1276 float => Self,
1277 sign_mask => 0x8000,
1278 exponent_mask => 0x7C00,
1279 hidden_bit_mask => 0x0400,
1280 mantissa_mask => 0x03FF,
1281 );
1282 const EXPONENT_SIZE: i32 = 5;
1283 const MANTISSA_SIZE: i32 = 10;
1284 const EXPONENT_BIAS: i32 = 15 + Self::MANTISSA_SIZE;
1285 const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
1286 const MAX_EXPONENT: i32 = 0x1F - Self::EXPONENT_BIAS;
1287
1288 #[inline(always)]
1289 fn to_bits(self) -> u16 {
1290 f16::to_bits(self)
1291 }
1292
1293 #[inline(always)]
1294 fn from_bits(u: u16) -> f16 {
1295 f16::from_bits(u)
1296 }
1297
1298 #[inline(always)]
1299 fn ln(self) -> f16 {
1300 f16::from_f32(self.as_f32().ln())
1301 }
1302
1303 #[inline(always)]
1304 fn floor(self) -> f16 {
1305 f16::from_f32(self.as_f32().floor())
1306 }
1307
1308 #[inline(always)]
1309 fn is_sign_positive(self) -> bool {
1310 self.to_bits() & Self::SIGN_MASK == 0
1311 }
1312
1313 #[inline(always)]
1314 fn is_sign_negative(self) -> bool {
1315 !self.is_sign_positive()
1316 }
1317}
1318
1319#[cfg(feature = "f16")]
1320impl Float for bf16 {
1321 type Unsigned = u16;
1322
1323 const ZERO: Self = Self::from_bits(0);
1324 const ONE: Self = Self::from_bits(float_one!(Self));
1325 const TWO: Self = Self::from_bits(float_two!(Self));
1326 const MAX: Self = Self::from_bits(float_max!(Self));
1327 const MIN: Self = Self::from_bits(float_min!(Self));
1328 const INFINITY: Self = Self::from_bits(Self::INFINITY_BITS);
1329 const NEG_INFINITY: Self = Self::from_bits(Self::NEGATIVE_INFINITY_BITS);
1330 const NAN: Self = Self::from_bits(float_nan!(Self));
1331 const BITS: usize = mem::size_of::<Self>() * 8;
1332
1333 float_masks!(
1334 float => Self,
1335 sign_mask => 0x8000,
1336 exponent_mask => 0x7F80,
1337 hidden_bit_mask => 0x0080,
1338 mantissa_mask => 0x007F,
1339 );
1340 const EXPONENT_SIZE: i32 = 8;
1341 const MANTISSA_SIZE: i32 = 7;
1342 const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE;
1343 const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
1344 const MAX_EXPONENT: i32 = 0xFF - Self::EXPONENT_BIAS;
1345
1346 #[inline(always)]
1347 fn to_bits(self) -> u16 {
1348 bf16::to_bits(self)
1349 }
1350
1351 #[inline(always)]
1352 fn from_bits(u: u16) -> bf16 {
1353 bf16::from_bits(u)
1354 }
1355
1356 #[inline(always)]
1357 fn ln(self) -> bf16 {
1358 bf16::from_f32(self.as_f32().ln())
1359 }
1360
1361 #[inline(always)]
1362 fn floor(self) -> bf16 {
1363 bf16::from_f32(self.as_f32().floor())
1364 }
1365
1366 #[inline(always)]
1367 fn is_sign_positive(self) -> bool {
1368 self.to_bits() & Self::SIGN_MASK == 0
1369 }
1370
1371 #[inline(always)]
1372 fn is_sign_negative(self) -> bool {
1373 !self.is_sign_positive()
1374 }
1375}
1376
1377#[cfg(any(feature = "parse-floats", feature = "write-floats"))]
1378impl Float for f32 {
1379 type Unsigned = u32;
1380 float_literals!(f32);
1381 float_masks!(
1382 float => Self,
1383 sign_mask => 0x80000000,
1384 exponent_mask => 0x7F800000,
1385 hidden_bit_mask => 0x00800000,
1386 mantissa_mask => 0x007FFFFF,
1387 );
1388 const EXPONENT_SIZE: i32 = 8;
1389 const MANTISSA_SIZE: i32 = 23;
1390 const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE;
1391 const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
1392 const MAX_EXPONENT: i32 = 0xFF - Self::EXPONENT_BIAS;
1393
1394 #[inline(always)]
1395 fn to_bits(self) -> u32 {
1396 f32::to_bits(self)
1397 }
1398
1399 #[inline(always)]
1400 fn from_bits(u: u32) -> f32 {
1401 f32::from_bits(u)
1402 }
1403
1404 #[inline(always)]
1405 fn ln(self) -> f32 {
1406 #[cfg(feature = "std")]
1407 return f32::ln(self);
1408
1409 #[cfg(not(feature = "std"))]
1410 return libm::logf(self);
1411 }
1412
1413 #[inline(always)]
1414 fn floor(self) -> f32 {
1415 #[cfg(feature = "std")]
1416 return f32::floor(self);
1417
1418 #[cfg(not(feature = "std"))]
1419 return libm::floorf(self);
1420 }
1421
1422 #[inline(always)]
1423 fn is_sign_positive(self) -> bool {
1424 f32::is_sign_positive(self)
1425 }
1426
1427 #[inline(always)]
1428 fn is_sign_negative(self) -> bool {
1429 f32::is_sign_negative(self)
1430 }
1431}
1432
1433#[cfg(any(feature = "parse-floats", feature = "write-floats"))]
1434impl Float for f64 {
1435 type Unsigned = u64;
1436 float_literals!(f64);
1437 float_masks!(
1438 float => Self,
1439 sign_mask => 0x8000000000000000,
1440 exponent_mask => 0x7FF0000000000000,
1441 hidden_bit_mask => 0x0010000000000000,
1442 mantissa_mask => 0x000FFFFFFFFFFFFF,
1443 );
1444 const EXPONENT_SIZE: i32 = 11;
1445 const MANTISSA_SIZE: i32 = 52;
1446 const EXPONENT_BIAS: i32 = 1023 + Self::MANTISSA_SIZE;
1447 const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
1448 const MAX_EXPONENT: i32 = 0x7FF - Self::EXPONENT_BIAS;
1449
1450 #[inline(always)]
1451 fn to_bits(self) -> u64 {
1452 f64::to_bits(self)
1453 }
1454
1455 #[inline(always)]
1456 fn from_bits(u: u64) -> f64 {
1457 f64::from_bits(u)
1458 }
1459
1460 #[inline(always)]
1461 fn ln(self) -> f64 {
1462 #[cfg(feature = "std")]
1463 return f64::ln(self);
1464
1465 #[cfg(not(feature = "std"))]
1466 return libm::logd(self);
1467 }
1468
1469 #[inline(always)]
1470 fn floor(self) -> f64 {
1471 #[cfg(feature = "std")]
1472 return f64::floor(self);
1473
1474 #[cfg(not(feature = "std"))]
1475 return libm::floord(self);
1476 }
1477
1478 #[inline(always)]
1479 fn is_sign_positive(self) -> bool {
1480 f64::is_sign_positive(self)
1481 }
1482
1483 #[inline(always)]
1484 fn is_sign_negative(self) -> bool {
1485 f64::is_sign_negative(self)
1486 }
1487}
1488
1489