1use core::ops;
2
3use super::int::Int;
4
5pub mod add;
6pub mod cmp;
7pub mod conv;
8pub mod div;
9pub mod extend;
10pub mod mul;
11pub mod pow;
12pub mod sub;
13pub mod trunc;
14
15public_test_dep! {
16/// Trait for some basic operations on floats
17pub(crate) trait Float:
18 Copy
19 + core::fmt::Debug
20 + PartialEq
21 + PartialOrd
22 + ops::AddAssign
23 + ops::MulAssign
24 + ops::Add<Output = Self>
25 + ops::Sub<Output = Self>
26 + ops::Div<Output = Self>
27 + ops::Rem<Output = Self>
28{
29 /// A uint of the same width as the float
30 type Int: Int;
31
32 /// A int of the same width as the float
33 type SignedInt: Int;
34
35 /// An int capable of containing the exponent bits plus a sign bit. This is signed.
36 type ExpInt: Int;
37
38 const ZERO: Self;
39 const ONE: Self;
40
41 /// The bitwidth of the float type
42 const BITS: u32;
43
44 /// The bitwidth of the significand
45 const SIGNIFICAND_BITS: u32;
46
47 /// The bitwidth of the exponent
48 const EXPONENT_BITS: u32 = Self::BITS - Self::SIGNIFICAND_BITS - 1;
49
50 /// The maximum value of the exponent
51 const EXPONENT_MAX: u32 = (1 << Self::EXPONENT_BITS) - 1;
52
53 /// The exponent bias value
54 const EXPONENT_BIAS: u32 = Self::EXPONENT_MAX >> 1;
55
56 /// A mask for the sign bit
57 const SIGN_MASK: Self::Int;
58
59 /// A mask for the significand
60 const SIGNIFICAND_MASK: Self::Int;
61
62 // The implicit bit of the float format
63 const IMPLICIT_BIT: Self::Int;
64
65 /// A mask for the exponent
66 const EXPONENT_MASK: Self::Int;
67
68 /// Returns `self` transmuted to `Self::Int`
69 fn repr(self) -> Self::Int;
70
71 /// Returns `self` transmuted to `Self::SignedInt`
72 fn signed_repr(self) -> Self::SignedInt;
73
74 /// Checks if two floats have the same bit representation. *Except* for NaNs! NaN can be
75 /// represented in multiple different ways. This method returns `true` if two NaNs are
76 /// compared.
77 fn eq_repr(self, rhs: Self) -> bool;
78
79 /// Returns the sign bit
80 fn sign(self) -> bool;
81
82 /// Returns the exponent with bias
83 fn exp(self) -> Self::ExpInt;
84
85 /// Returns the significand with no implicit bit (or the "fractional" part)
86 fn frac(self) -> Self::Int;
87
88 /// Returns the significand with implicit bit
89 fn imp_frac(self) -> Self::Int;
90
91 /// Returns a `Self::Int` transmuted back to `Self`
92 fn from_repr(a: Self::Int) -> Self;
93
94 /// Constructs a `Self` from its parts. Inputs are treated as bits and shifted into position.
95 fn from_parts(sign: bool, exponent: Self::Int, significand: Self::Int) -> Self;
96
97 /// Returns (normalized exponent, normalized significand)
98 fn normalize(significand: Self::Int) -> (i32, Self::Int);
99
100 /// Returns if `self` is subnormal
101 fn is_subnormal(self) -> bool;
102}
103}
104
105macro_rules! float_impl {
106 ($ty:ident, $ity:ident, $sity:ident, $expty:ident, $bits:expr, $significand_bits:expr) => {
107 impl Float for $ty {
108 type Int = $ity;
109 type SignedInt = $sity;
110 type ExpInt = $expty;
111
112 const ZERO: Self = 0.0;
113 const ONE: Self = 1.0;
114
115 const BITS: u32 = $bits;
116 const SIGNIFICAND_BITS: u32 = $significand_bits;
117
118 const SIGN_MASK: Self::Int = 1 << (Self::BITS - 1);
119 const SIGNIFICAND_MASK: Self::Int = (1 << Self::SIGNIFICAND_BITS) - 1;
120 const IMPLICIT_BIT: Self::Int = 1 << Self::SIGNIFICAND_BITS;
121 const EXPONENT_MASK: Self::Int = !(Self::SIGN_MASK | Self::SIGNIFICAND_MASK);
122
123 fn repr(self) -> Self::Int {
124 self.to_bits()
125 }
126 fn signed_repr(self) -> Self::SignedInt {
127 self.to_bits() as Self::SignedInt
128 }
129 fn eq_repr(self, rhs: Self) -> bool {
130 if self.is_nan() && rhs.is_nan() {
131 true
132 } else {
133 self.repr() == rhs.repr()
134 }
135 }
136 fn sign(self) -> bool {
137 self.signed_repr() < Self::SignedInt::ZERO
138 }
139 fn exp(self) -> Self::ExpInt {
140 ((self.to_bits() & Self::EXPONENT_MASK) >> Self::SIGNIFICAND_BITS) as Self::ExpInt
141 }
142 fn frac(self) -> Self::Int {
143 self.to_bits() & Self::SIGNIFICAND_MASK
144 }
145 fn imp_frac(self) -> Self::Int {
146 self.frac() | Self::IMPLICIT_BIT
147 }
148 fn from_repr(a: Self::Int) -> Self {
149 Self::from_bits(a)
150 }
151 fn from_parts(sign: bool, exponent: Self::Int, significand: Self::Int) -> Self {
152 Self::from_repr(
153 ((sign as Self::Int) << (Self::BITS - 1))
154 | ((exponent << Self::SIGNIFICAND_BITS) & Self::EXPONENT_MASK)
155 | (significand & Self::SIGNIFICAND_MASK),
156 )
157 }
158 fn normalize(significand: Self::Int) -> (i32, Self::Int) {
159 let shift = significand
160 .leading_zeros()
161 .wrapping_sub((Self::Int::ONE << Self::SIGNIFICAND_BITS).leading_zeros());
162 (
163 1i32.wrapping_sub(shift as i32),
164 significand << shift as Self::Int,
165 )
166 }
167 fn is_subnormal(self) -> bool {
168 (self.repr() & Self::EXPONENT_MASK) == Self::Int::ZERO
169 }
170 }
171 };
172}
173
174float_impl!(f32, u32, i32, i16, 32, 23);
175float_impl!(f64, u64, i64, i16, 64, 52);
176