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