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,192 @@ 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 <OtherSign = Self :: SignedInt , UnsignedInt = Self :: Int >;
35+
36+ /// A int of the same width as the float
37+ type SignedInt : Int + MinInt <OtherSign = Self :: Int , UnsignedInt = Self :: 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 SIG_BITS : u32 ;
50+
51+ /// The bitwidth of the exponent.
52+ const EXP_BITS : u32 = Self :: BITS - Self :: SIG_BITS - 1 ;
53+
54+ /// The saturated (maximum bitpattern) value of the exponent, i.e. the infinite
55+ /// representation.
56+ ///
57+ /// This is in the rightmost position, use `EXP_MASK` for the shifted value.
58+ const EXP_SAT : u32 = ( 1 << Self :: EXP_BITS ) - 1 ;
59+
60+ /// The exponent bias value.
61+ const EXP_BIAS : u32 = Self :: EXP_SAT >> 1 ;
62+
63+ /// A mask for the sign bit.
64+ const SIGN_MASK : Self :: Int ;
65+
66+ /// A mask for the significand.
67+ const SIG_MASK : Self :: Int ;
68+
69+ /// The implicit bit of the float format.
70+ const IMPLICIT_BIT : Self :: Int ;
71+
72+ /// A mask for the exponent.
73+ const EXP_MASK : Self :: Int ;
74+
75+ /// Returns `self` transmuted to `Self::Int`
76+ fn to_bits( self ) -> Self :: Int ;
77+
78+ /// Returns `self` transmuted to `Self::SignedInt`
79+ fn to_bits_signed( self ) -> Self :: SignedInt ;
80+
81+ /// Checks if two floats have the same bit representation. *Except* for NaNs! NaN can be
82+ /// represented in multiple different ways. This method returns `true` if two NaNs are
83+ /// compared.
84+ fn eq_repr( self , rhs: Self ) -> bool ;
85+
86+ /// Returns true if the sign is negative
87+ fn is_sign_negative( self ) -> bool ;
88+
89+ /// Returns the exponent, not adjusting for bias.
90+ fn exp( self ) -> Self :: ExpInt ;
91+
92+ /// Returns the significand with no implicit bit (or the "fractional" part)
93+ fn frac( self ) -> Self :: Int ;
94+
95+ /// Returns the significand with implicit bit
96+ fn imp_frac( self ) -> Self :: Int ;
97+
98+ /// Returns a `Self::Int` transmuted back to `Self`
99+ fn from_bits( a: Self :: Int ) -> Self ;
100+
101+ /// Constructs a `Self` from its parts. Inputs are treated as bits and shifted into position.
102+ fn from_parts( negative: bool , exponent: Self :: Int , significand: Self :: Int ) -> Self ;
103+
104+ fn abs( self ) -> Self {
105+ let abs_mask = !Self :: SIGN_MASK ;
106+ Self :: from_bits( self . to_bits( ) & abs_mask)
107+ }
108+
109+ /// Returns (normalized exponent, normalized significand)
110+ fn normalize( significand: Self :: Int ) -> ( i32 , Self :: Int ) ;
111+
112+ /// Returns if `self` is subnormal
113+ fn is_subnormal( self ) -> bool ;
114+ }
115+ }
116+
117+ macro_rules! float_impl {
118+ ( $ty: ident, $ity: ident, $sity: ident, $expty: ident, $bits: expr, $significand_bits: expr) => {
119+ impl Float for $ty {
120+ type Int = $ity;
121+ type SignedInt = $sity;
122+ type ExpInt = $expty;
123+
124+ const ZERO : Self = 0.0 ;
125+ const ONE : Self = 1.0 ;
126+
127+ const BITS : u32 = $bits;
128+ const SIG_BITS : u32 = $significand_bits;
129+
130+ const SIGN_MASK : Self :: Int = 1 << ( Self :: BITS - 1 ) ;
131+ const SIG_MASK : Self :: Int = ( 1 << Self :: SIG_BITS ) - 1 ;
132+ const IMPLICIT_BIT : Self :: Int = 1 << Self :: SIG_BITS ;
133+ const EXP_MASK : Self :: Int = !( Self :: SIGN_MASK | Self :: SIG_MASK ) ;
134+
135+ fn to_bits( self ) -> Self :: Int {
136+ self . to_bits( )
137+ }
138+ fn to_bits_signed( self ) -> Self :: SignedInt {
139+ self . to_bits( ) as Self :: SignedInt
140+ }
141+ fn eq_repr( self , rhs: Self ) -> bool {
142+ #[ cfg( feature = "mangled-names" ) ]
143+ fn is_nan( x: $ty) -> bool {
144+ // When using mangled-names, the "real" compiler-builtins might not have the
145+ // necessary builtin (__unordtf2) to test whether `f128` is NaN.
146+ // FIXME(f16_f128): Remove once the nightly toolchain has the __unordtf2 builtin
147+ // x is NaN if all the bits of the exponent are set and the significand is non-0
148+ x. to_bits( ) & $ty:: EXP_MASK == $ty:: EXP_MASK && x. to_bits( ) & $ty:: SIG_MASK != 0
149+ }
150+ #[ cfg( not( feature = "mangled-names" ) ) ]
151+ fn is_nan( x: $ty) -> bool {
152+ x. is_nan( )
153+ }
154+ if is_nan( self ) && is_nan( rhs) {
155+ true
156+ } else {
157+ self . to_bits( ) == rhs. to_bits( )
158+ }
159+ }
160+ fn is_sign_negative( self ) -> bool {
161+ self . is_sign_negative( )
162+ }
163+ fn exp( self ) -> Self :: ExpInt {
164+ ( ( self . to_bits( ) & Self :: EXP_MASK ) >> Self :: SIG_BITS ) as Self :: ExpInt
165+ }
166+ fn frac( self ) -> Self :: Int {
167+ self . to_bits( ) & Self :: SIG_MASK
168+ }
169+ fn imp_frac( self ) -> Self :: Int {
170+ self . frac( ) | Self :: IMPLICIT_BIT
171+ }
172+ fn from_bits( a: Self :: Int ) -> Self {
173+ Self :: from_bits( a)
174+ }
175+ fn from_parts( negative: bool , exponent: Self :: Int , significand: Self :: Int ) -> Self {
176+ Self :: from_bits(
177+ ( ( negative as Self :: Int ) << ( Self :: BITS - 1 ) )
178+ | ( ( exponent << Self :: SIG_BITS ) & Self :: EXP_MASK )
179+ | ( significand & Self :: SIG_MASK ) ,
180+ )
181+ }
182+ fn normalize( significand: Self :: Int ) -> ( i32 , Self :: Int ) {
183+ let shift = significand. leading_zeros( ) . wrapping_sub( Self :: EXP_BITS ) ;
184+ (
185+ 1i32 . wrapping_sub( shift as i32 ) ,
186+ significand << shift as Self :: Int ,
187+ )
188+ }
189+ fn is_subnormal( self ) -> bool {
190+ ( self . to_bits( ) & Self :: EXP_MASK ) == Self :: Int :: ZERO
191+ }
192+ }
193+ } ;
194+ }
14195
15- #[ cfg( feature = "public-test-deps" ) ]
16- pub use traits:: { Float , HalfRep } ;
196+ #[ cfg( f16_enabled) ]
197+ float_impl ! ( f16, u16 , i16 , i8 , 16 , 10 ) ;
198+ float_impl ! ( f32 , u32 , i32 , i16 , 32 , 23 ) ;
199+ float_impl ! ( f64 , u64 , i64 , i16 , 64 , 52 ) ;
200+ #[ cfg( f128_enabled) ]
201+ float_impl ! ( f128, u128 , i128 , i16 , 128 , 112 ) ;
0 commit comments