1
- use core:: { fmt, ops} ;
1
+ use core:: { fmt, mem , ops} ;
2
2
3
3
use super :: int_traits:: { Int , MinInt } ;
4
4
@@ -7,15 +7,17 @@ use super::int_traits::{Int, MinInt};
7
7
pub trait Float :
8
8
Copy
9
9
+ fmt:: Debug
10
- + fmt:: Display
11
10
+ PartialEq
12
11
+ PartialOrd
13
12
+ ops:: AddAssign
14
13
+ ops:: MulAssign
15
14
+ ops:: Add < Output = Self >
16
15
+ ops:: Sub < Output = Self >
16
+ + ops:: Mul < Output = Self >
17
17
+ ops:: Div < Output = Self >
18
18
+ ops:: Rem < Output = Self >
19
+ + ops:: Neg < Output = Self >
20
+ + ' static
19
21
{
20
22
/// A uint of the same width as the float
21
23
type Int : Int < OtherSign = Self :: SignedInt , Unsigned = Self :: Int > ;
@@ -27,11 +29,16 @@ pub trait Float:
27
29
type ExpInt : Int ;
28
30
29
31
const ZERO : Self ;
32
+ const NEG_ZERO : Self ;
30
33
const ONE : Self ;
31
34
const NEG_ONE : Self ;
32
35
const INFINITY : Self ;
33
36
const NEG_INFINITY : Self ;
34
37
const NAN : Self ;
38
+ const MAX : Self ;
39
+ const MIN : Self ;
40
+ const PI : Self ;
41
+ const FRAC_PI_2 : Self ;
35
42
36
43
/// The bitwidth of the float type
37
44
const BITS : u32 ;
@@ -69,7 +76,19 @@ pub trait Float:
69
76
/// Checks if two floats have the same bit representation. *Except* for NaNs! NaN can be
70
77
/// represented in multiple different ways. This method returns `true` if two NaNs are
71
78
/// compared.
72
- fn eq_repr ( self , rhs : Self ) -> bool ;
79
+ fn eq_repr ( self , rhs : Self ) -> bool {
80
+ let is_nan = |x : Self | -> bool {
81
+ // }
82
+ // fn is_nan(x: Self) -> bool {
83
+ // When using mangled-names, the "real" compiler-builtins might not have the
84
+ // necessary builtin (__unordtf2) to test whether `f128` is NaN.
85
+ // FIXME(f16_f128): Remove once the nightly toolchain has the __unordtf2 builtin
86
+ // x is NaN if all the bits of the exponent are set and the significand is non-0
87
+ x. to_bits ( ) & Self :: EXP_MASK == Self :: EXP_MASK
88
+ && x. to_bits ( ) & Self :: SIG_MASK != Self :: Int :: ZERO
89
+ } ;
90
+ if is_nan ( self ) && is_nan ( rhs) { true } else { self . to_bits ( ) == rhs. to_bits ( ) }
91
+ }
73
92
74
93
/// Returns true if the value is NaN.
75
94
fn is_nan ( self ) -> bool ;
@@ -81,22 +100,35 @@ pub trait Float:
81
100
fn is_sign_negative ( self ) -> bool ;
82
101
83
102
/// Returns if `self` is subnormal
84
- fn is_subnormal ( self ) -> bool ;
103
+ fn is_subnormal ( self ) -> bool {
104
+ ( self . to_bits ( ) & Self :: EXP_MASK ) == Self :: Int :: ZERO
105
+ }
85
106
86
107
/// Returns the exponent, not adjusting for bias.
87
108
fn exp ( self ) -> Self :: ExpInt ;
88
109
89
110
/// Returns the significand with no implicit bit (or the "fractional" part)
90
- fn frac ( self ) -> Self :: Int ;
111
+ fn frac ( self ) -> Self :: Int {
112
+ self . to_bits ( ) & Self :: SIG_MASK
113
+ }
91
114
92
115
/// Returns the significand with implicit bit
93
- fn imp_frac ( self ) -> Self :: Int ;
116
+ fn imp_frac ( self ) -> Self :: Int {
117
+ self . frac ( ) | Self :: IMPLICIT_BIT
118
+ }
94
119
95
120
/// Returns a `Self::Int` transmuted back to `Self`
96
121
fn from_bits ( a : Self :: Int ) -> Self ;
97
122
98
123
/// Constructs a `Self` from its parts. Inputs are treated as bits and shifted into position.
99
- fn from_parts ( negative : bool , exponent : Self :: Int , significand : Self :: Int ) -> Self ;
124
+ fn from_parts ( negative : bool , exponent : Self :: Int , significand : Self :: Int ) -> Self {
125
+ let sign = if negative { Self :: Int :: ONE } else { Self :: Int :: ZERO } ;
126
+ Self :: from_bits (
127
+ ( sign << ( Self :: BITS - 1 ) )
128
+ | ( ( exponent << Self :: SIG_BITS ) & Self :: EXP_MASK )
129
+ | ( significand & Self :: SIG_MASK ) ,
130
+ )
131
+ }
100
132
101
133
fn abs ( self ) -> Self {
102
134
let abs_mask = !Self :: SIGN_MASK ;
@@ -107,10 +139,18 @@ pub trait Float:
107
139
fn normalize ( significand : Self :: Int ) -> ( i32 , Self :: Int ) ;
108
140
109
141
/// Returns a number composed of the magnitude of self and the sign of sign.
110
- fn copysign ( self , other : Self ) -> Self ;
142
+ fn copysign ( self , other : Self ) -> Self {
143
+ let mut x = self . to_bits ( ) ;
144
+ let y = other. to_bits ( ) ;
145
+ x &= !Self :: SIGN_MASK ;
146
+ x |= y & Self :: SIGN_MASK ;
147
+ Self :: from_bits ( x)
148
+ }
111
149
112
150
/// Returns a number that represents the sign of self.
113
- fn signum ( self ) -> Self ;
151
+ fn signum ( self ) -> Self {
152
+ if self . is_nan ( ) { self } else { Self :: ONE . copysign ( self ) }
153
+ }
114
154
}
115
155
116
156
macro_rules! float_impl {
@@ -121,11 +161,22 @@ macro_rules! float_impl {
121
161
type ExpInt = $expty;
122
162
123
163
const ZERO : Self = 0.0 ;
164
+ const NEG_ZERO : Self = -0.0 ;
124
165
const ONE : Self = 1.0 ;
125
166
const NEG_ONE : Self = -1.0 ;
126
167
const INFINITY : Self = Self :: INFINITY ;
127
168
const NEG_INFINITY : Self = Self :: NEG_INFINITY ;
128
169
const NAN : Self = Self :: NAN ;
170
+ const MAX : Self = -Self :: MIN ;
171
+ // Sign bit set, saturated mantissa, saturated exponent with last bit zeroed
172
+ // FIXME(msrv): just use `from_bits` when available
173
+ // SAFETY: POD cast with no preconditions
174
+ const MIN : Self = unsafe {
175
+ mem:: transmute:: <Self :: Int , Self >( Self :: Int :: MAX & !( 1 << Self :: SIG_BITS ) )
176
+ } ;
177
+
178
+ const PI : Self = core:: $ty:: consts:: PI ;
179
+ const FRAC_PI_2 : Self = core:: $ty:: consts:: FRAC_PI_2 ;
129
180
130
181
const BITS : u32 = $bits;
131
182
const SIG_BITS : u32 = $significand_bits;
@@ -141,16 +192,6 @@ macro_rules! float_impl {
141
192
fn to_bits_signed( self ) -> Self :: SignedInt {
142
193
self . to_bits( ) as Self :: SignedInt
143
194
}
144
- fn eq_repr( self , rhs: Self ) -> bool {
145
- fn is_nan( x: $ty) -> bool {
146
- // When using mangled-names, the "real" compiler-builtins might not have the
147
- // necessary builtin (__unordtf2) to test whether `f128` is NaN.
148
- // FIXME(f16_f128): Remove once the nightly toolchain has the __unordtf2 builtin
149
- // x is NaN if all the bits of the exponent are set and the significand is non-0
150
- x. to_bits( ) & $ty:: EXP_MASK == $ty:: EXP_MASK && x. to_bits( ) & $ty:: SIG_MASK != 0
151
- }
152
- if is_nan( self ) && is_nan( rhs) { true } else { self . to_bits( ) == rhs. to_bits( ) }
153
- }
154
195
fn is_nan( self ) -> bool {
155
196
self . is_nan( )
156
197
}
@@ -160,43 +201,16 @@ macro_rules! float_impl {
160
201
fn is_sign_negative( self ) -> bool {
161
202
self . is_sign_negative( )
162
203
}
163
- fn is_subnormal( self ) -> bool {
164
- ( self . to_bits( ) & Self :: EXP_MASK ) == Self :: Int :: ZERO
165
- }
166
204
fn exp( self ) -> Self :: ExpInt {
167
205
( ( self . to_bits( ) & Self :: EXP_MASK ) >> Self :: SIG_BITS ) as Self :: ExpInt
168
206
}
169
- fn frac( self ) -> Self :: Int {
170
- self . to_bits( ) & Self :: SIG_MASK
171
- }
172
- fn imp_frac( self ) -> Self :: Int {
173
- self . frac( ) | Self :: IMPLICIT_BIT
174
- }
175
207
fn from_bits( a: Self :: Int ) -> Self {
176
208
Self :: from_bits( a)
177
209
}
178
- fn from_parts( negative: bool , exponent: Self :: Int , significand: Self :: Int ) -> Self {
179
- Self :: from_bits(
180
- ( ( negative as Self :: Int ) << ( Self :: BITS - 1 ) )
181
- | ( ( exponent << Self :: SIG_BITS ) & Self :: EXP_MASK )
182
- | ( significand & Self :: SIG_MASK ) ,
183
- )
184
- }
185
210
fn normalize( significand: Self :: Int ) -> ( i32 , Self :: Int ) {
186
211
let shift = significand. leading_zeros( ) . wrapping_sub( Self :: EXP_BITS ) ;
187
212
( 1i32 . wrapping_sub( shift as i32 ) , significand << shift as Self :: Int )
188
213
}
189
- fn copysign( self , other: Self ) -> Self {
190
- let mut x = self . to_bits( ) ;
191
- let y = other. to_bits( ) ;
192
- x &= !Self :: SIGN_MASK ;
193
- x |= y & Self :: SIGN_MASK ;
194
- Self :: from_bits( x)
195
- }
196
-
197
- fn signum( self ) -> Self {
198
- if self . is_nan( ) { self } else { Self :: ONE . copysign( self ) }
199
- }
200
214
}
201
215
} ;
202
216
}
0 commit comments