]>
git.proxmox.com Git - rustc.git/blob - vendor/compiler_builtins/src/float/mod.rs
15 /// Trait for some basic operations on floats
16 pub(crate) trait Float
:
23 + ops
::Add
<Output
= Self>
24 + ops
::Sub
<Output
= Self>
25 + ops
::Div
<Output
= Self>
26 + ops
::Rem
<Output
= Self>
28 /// A uint of the same with as the float
31 /// A int of the same with as the float
34 /// An int capable of containing the exponent bits plus a sign bit. This is signed.
40 /// The bitwidth of the float type
43 /// The bitwidth of the significand
44 const SIGNIFICAND_BITS
: u32;
46 /// The bitwidth of the exponent
47 const EXPONENT_BITS
: u32 = Self::BITS
- Self::SIGNIFICAND_BITS
- 1;
49 /// The maximum value of the exponent
50 const EXPONENT_MAX
: u32 = (1 << Self::EXPONENT_BITS
) - 1;
52 /// The exponent bias value
53 const EXPONENT_BIAS
: u32 = Self::EXPONENT_MAX
>> 1;
55 /// A mask for the sign bit
56 const SIGN_MASK
: Self::Int
;
58 /// A mask for the significand
59 const SIGNIFICAND_MASK
: Self::Int
;
61 // The implicit bit of the float format
62 const IMPLICIT_BIT
: Self::Int
;
64 /// A mask for the exponent
65 const EXPONENT_MASK
: Self::Int
;
67 /// Returns `self` transmuted to `Self::Int`
68 fn repr(self) -> Self::Int
;
70 /// Returns `self` transmuted to `Self::SignedInt`
71 fn signed_repr(self) -> Self::SignedInt
;
73 /// Checks if two floats have the same bit representation. *Except* for NaNs! NaN can be
74 /// represented in multiple different ways. This method returns `true` if two NaNs are
76 fn eq_repr(self, rhs
: Self) -> bool
;
78 /// Returns the sign bit
79 fn sign(self) -> bool
;
81 /// Returns the exponent with bias
82 fn exp(self) -> Self::ExpInt
;
84 /// Returns the significand with no implicit bit (or the "fractional" part)
85 fn frac(self) -> Self::Int
;
87 /// Returns the significand with implicit bit
88 fn imp_frac(self) -> Self::Int
;
90 /// Returns a `Self::Int` transmuted back to `Self`
91 fn from_repr(a
: Self::Int
) -> Self;
93 /// Constructs a `Self` from its parts. Inputs are treated as bits and shifted into position.
94 fn from_parts(sign
: bool
, exponent
: Self::Int
, significand
: Self::Int
) -> Self;
96 /// Returns (normalized exponent, normalized significand)
97 fn normalize(significand
: Self::Int
) -> (i32, Self::Int
);
99 /// Returns if `self` is subnormal
100 fn is_subnormal(self) -> bool
;
104 macro_rules
! float_impl
{
105 ($ty
:ident
, $ity
:ident
, $sity
:ident
, $expty
:ident
, $bits
:expr
, $significand_bits
:expr
) => {
108 type SignedInt
= $sity
;
109 type ExpInt
= $expty
;
111 const ZERO
: Self = 0.0;
112 const ONE
: Self = 1.0;
114 const BITS
: u32 = $bits
;
115 const SIGNIFICAND_BITS
: u32 = $significand_bits
;
117 const SIGN_MASK
: Self::Int
= 1 << (Self::BITS
- 1);
118 const SIGNIFICAND_MASK
: Self::Int
= (1 << Self::SIGNIFICAND_BITS
) - 1;
119 const IMPLICIT_BIT
: Self::Int
= 1 << Self::SIGNIFICAND_BITS
;
120 const EXPONENT_MASK
: Self::Int
= !(Self::SIGN_MASK
| Self::SIGNIFICAND_MASK
);
122 fn repr(self) -> Self::Int
{
125 fn signed_repr(self) -> Self::SignedInt
{
126 self.to_bits() as Self::SignedInt
128 fn eq_repr(self, rhs
: Self) -> bool
{
129 if self.is_nan() && rhs
.is_nan() {
132 self.repr() == rhs
.repr()
135 fn sign(self) -> bool
{
136 self.signed_repr() < Self::SignedInt
::ZERO
138 fn exp(self) -> Self::ExpInt
{
139 ((self.to_bits() & Self::EXPONENT_MASK
) >> Self::SIGNIFICAND_BITS
) as Self::ExpInt
141 fn frac(self) -> Self::Int
{
142 self.to_bits() & Self::SIGNIFICAND_MASK
144 fn imp_frac(self) -> Self::Int
{
145 self.frac() | Self::IMPLICIT_BIT
147 fn from_repr(a
: Self::Int
) -> Self {
150 fn from_parts(sign
: bool
, exponent
: Self::Int
, significand
: Self::Int
) -> Self {
152 ((sign
as Self::Int
) << (Self::BITS
- 1))
153 | ((exponent
<< Self::SIGNIFICAND_BITS
) & Self::EXPONENT_MASK
)
154 | (significand
& Self::SIGNIFICAND_MASK
),
157 fn normalize(significand
: Self::Int
) -> (i32, Self::Int
) {
158 let shift
= significand
160 .wrapping_sub((Self::Int
::ONE
<< Self::SIGNIFICAND_BITS
).leading_zeros());
162 1i32.wrapping_sub(shift
as i32),
163 significand
<< shift
as Self::Int
,
166 fn is_subnormal(self) -> bool
{
167 (self.repr() & Self::EXPONENT_MASK
) == Self::Int
::ZERO
173 float_impl
!(f32, u32, i32, i16, 32, 23);
174 float_impl
!(f64, u64, i64, i16, 64, 52);