compiler_builtins/float/
traits.rs1use core::ops;
2
3use crate::int::{DInt, Int, MinInt};
4
5pub type HalfRep<F> = <<F as Float>::Int as DInt>::H;
7
8#[allow(dead_code)]
10pub trait Float:
11 Copy
12 + core::fmt::Debug
13 + PartialEq
14 + PartialOrd
15 + ops::AddAssign
16 + ops::MulAssign
17 + ops::Add<Output = Self>
18 + ops::Sub<Output = Self>
19 + ops::Div<Output = Self>
20 + ops::Rem<Output = Self>
21{
22 type Int: Int<OtherSign = Self::SignedInt, UnsignedInt = Self::Int>;
24
25 type SignedInt: Int + MinInt<OtherSign = Self::Int, UnsignedInt = Self::Int>;
27
28 type ExpInt: Int;
30
31 const ZERO: Self;
32 const ONE: Self;
33
34 const BITS: u32;
36
37 const SIG_BITS: u32;
39
40 const EXP_BITS: u32 = Self::BITS - Self::SIG_BITS - 1;
42
43 const EXP_SAT: u32 = (1 << Self::EXP_BITS) - 1;
48
49 const EXP_BIAS: u32 = Self::EXP_SAT >> 1;
51
52 const SIGN_MASK: Self::Int;
54
55 const SIG_MASK: Self::Int;
57
58 const IMPLICIT_BIT: Self::Int;
60
61 const EXP_MASK: Self::Int;
63
64 fn to_bits(self) -> Self::Int;
66
67 fn to_bits_signed(self) -> Self::SignedInt;
69
70 fn eq_repr(self, rhs: Self) -> bool;
74
75 fn is_sign_negative(self) -> bool;
77
78 fn exp(self) -> Self::ExpInt;
80
81 fn frac(self) -> Self::Int;
83
84 fn imp_frac(self) -> Self::Int;
86
87 fn from_bits(a: Self::Int) -> Self;
89
90 fn from_parts(negative: bool, exponent: Self::Int, significand: Self::Int) -> Self;
92
93 fn abs(self) -> Self {
94 let abs_mask = !Self::SIGN_MASK;
95 Self::from_bits(self.to_bits() & abs_mask)
96 }
97
98 fn normalize(significand: Self::Int) -> (i32, Self::Int);
100
101 fn is_subnormal(self) -> bool;
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 SIG_BITS: u32 = $significand_bits;
117
118 const SIGN_MASK: Self::Int = 1 << (Self::BITS - 1);
119 const SIG_MASK: Self::Int = (1 << Self::SIG_BITS) - 1;
120 const IMPLICIT_BIT: Self::Int = 1 << Self::SIG_BITS;
121 const EXP_MASK: Self::Int = !(Self::SIGN_MASK | Self::SIG_MASK);
122
123 fn to_bits(self) -> Self::Int {
124 self.to_bits()
125 }
126 fn to_bits_signed(self) -> Self::SignedInt {
127 self.to_bits() as Self::SignedInt
128 }
129 fn eq_repr(self, rhs: Self) -> bool {
130 #[cfg(feature = "mangled-names")]
131 fn is_nan(x: $ty) -> bool {
132 x.to_bits() & $ty::EXP_MASK == $ty::EXP_MASK && x.to_bits() & $ty::SIG_MASK != 0
137 }
138 #[cfg(not(feature = "mangled-names"))]
139 fn is_nan(x: $ty) -> bool {
140 x.is_nan()
141 }
142 if is_nan(self) && is_nan(rhs) {
143 true
144 } else {
145 self.to_bits() == rhs.to_bits()
146 }
147 }
148 fn is_sign_negative(self) -> bool {
149 self.is_sign_negative()
150 }
151 fn exp(self) -> Self::ExpInt {
152 ((self.to_bits() & Self::EXP_MASK) >> Self::SIG_BITS) as Self::ExpInt
153 }
154 fn frac(self) -> Self::Int {
155 self.to_bits() & Self::SIG_MASK
156 }
157 fn imp_frac(self) -> Self::Int {
158 self.frac() | Self::IMPLICIT_BIT
159 }
160 fn from_bits(a: Self::Int) -> Self {
161 Self::from_bits(a)
162 }
163 fn from_parts(negative: bool, exponent: Self::Int, significand: Self::Int) -> Self {
164 Self::from_bits(
165 ((negative as Self::Int) << (Self::BITS - 1))
166 | ((exponent << Self::SIG_BITS) & Self::EXP_MASK)
167 | (significand & Self::SIG_MASK),
168 )
169 }
170 fn normalize(significand: Self::Int) -> (i32, Self::Int) {
171 let shift = significand.leading_zeros().wrapping_sub(Self::EXP_BITS);
172 (
173 1i32.wrapping_sub(shift as i32),
174 significand << shift as Self::Int,
175 )
176 }
177 fn is_subnormal(self) -> bool {
178 (self.to_bits() & Self::EXP_MASK) == Self::Int::ZERO
179 }
180 }
181 };
182}
183
184#[cfg(f16_enabled)]
185float_impl!(f16, u16, i16, i8, 16, 10);
186float_impl!(f32, u32, i32, i16, 32, 23);
187float_impl!(f64, u64, i64, i16, 64, 52);
188#[cfg(f128_enabled)]
189float_impl!(f128, u128, i128, i16, 128, 112);