1+ use core:: ops;
2+
3+ use crate :: int:: { DInt , Int , MinInt } ;
4+
15pub mod add;
26pub mod cmp;
37pub mod conv;
@@ -6,11 +10,187 @@ pub mod extend;
610pub mod mul;
711pub mod pow;
812pub mod sub;
9- pub ( crate ) mod traits;
1013pub mod trunc;
1114
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+ }
14190
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