1
- use core:: ops;
1
+ use core:: { fmt , ops} ;
2
2
3
3
use super :: int_traits:: { Int , MinInt } ;
4
4
5
5
/// Trait for some basic operations on floats
6
6
#[ allow( dead_code) ]
7
7
pub trait Float :
8
8
Copy
9
- + core:: fmt:: Debug
9
+ + fmt:: Debug
10
+ + fmt:: Display
10
11
+ PartialEq
11
12
+ PartialOrd
12
13
+ ops:: AddAssign
@@ -17,16 +18,17 @@ pub trait Float:
17
18
+ ops:: Rem < Output = Self >
18
19
{
19
20
/// A uint of the same width as the float
20
- type Int : Int < OtherSign = Self :: SignedInt , UnsignedInt = Self :: Int > ;
21
+ type Int : Int < OtherSign = Self :: SignedInt , Unsigned = Self :: Int > ;
21
22
22
23
/// A int of the same width as the float
23
- type SignedInt : Int + MinInt < OtherSign = Self :: Int , UnsignedInt = Self :: Int > ;
24
+ type SignedInt : Int + MinInt < OtherSign = Self :: Int , Unsigned = Self :: Int > ;
24
25
25
26
/// An int capable of containing the exponent bits plus a sign bit. This is signed.
26
27
type ExpInt : Int ;
27
28
28
29
const ZERO : Self ;
29
30
const ONE : Self ;
31
+ const NEG_ONE : Self ;
30
32
const INFINITY : Self ;
31
33
const NEG_INFINITY : Self ;
32
34
const NAN : Self ;
@@ -69,9 +71,18 @@ pub trait Float:
69
71
/// compared.
70
72
fn eq_repr ( self , rhs : Self ) -> bool ;
71
73
72
- /// Returns true if the sign is negative
74
+ /// Returns true if the value is NaN.
75
+ fn is_nan ( self ) -> bool ;
76
+
77
+ /// Returns true if the value is +inf or -inf.
78
+ fn is_infinite ( self ) -> bool ;
79
+
80
+ /// Returns true if the sign is negative.
73
81
fn is_sign_negative ( self ) -> bool ;
74
82
83
+ /// Returns if `self` is subnormal
84
+ fn is_subnormal ( self ) -> bool ;
85
+
75
86
/// Returns the exponent, not adjusting for bias.
76
87
fn exp ( self ) -> Self :: ExpInt ;
77
88
@@ -95,8 +106,11 @@ pub trait Float:
95
106
/// Returns (normalized exponent, normalized significand)
96
107
fn normalize ( significand : Self :: Int ) -> ( i32 , Self :: Int ) ;
97
108
98
- /// Returns if `self` is subnormal
99
- fn is_subnormal ( self ) -> bool ;
109
+ /// Returns a number composed of the magnitude of self and the sign of sign.
110
+ fn copysign ( self , other : Self ) -> Self ;
111
+
112
+ /// Returns a number that represents the sign of self.
113
+ fn signum ( self ) -> Self ;
100
114
}
101
115
102
116
macro_rules! float_impl {
@@ -108,6 +122,7 @@ macro_rules! float_impl {
108
122
109
123
const ZERO : Self = 0.0 ;
110
124
const ONE : Self = 1.0 ;
125
+ const NEG_ONE : Self = -1.0 ;
111
126
const INFINITY : Self = Self :: INFINITY ;
112
127
const NEG_INFINITY : Self = Self :: NEG_INFINITY ;
113
128
const NAN : Self = Self :: NAN ;
@@ -136,9 +151,18 @@ macro_rules! float_impl {
136
151
}
137
152
if is_nan( self ) && is_nan( rhs) { true } else { self . to_bits( ) == rhs. to_bits( ) }
138
153
}
154
+ fn is_nan( self ) -> bool {
155
+ self . is_nan( )
156
+ }
157
+ fn is_infinite( self ) -> bool {
158
+ self . is_infinite( )
159
+ }
139
160
fn is_sign_negative( self ) -> bool {
140
161
self . is_sign_negative( )
141
162
}
163
+ fn is_subnormal( self ) -> bool {
164
+ ( self . to_bits( ) & Self :: EXP_MASK ) == Self :: Int :: ZERO
165
+ }
142
166
fn exp( self ) -> Self :: ExpInt {
143
167
( ( self . to_bits( ) & Self :: EXP_MASK ) >> Self :: SIG_BITS ) as Self :: ExpInt
144
168
}
@@ -162,8 +186,16 @@ macro_rules! float_impl {
162
186
let shift = significand. leading_zeros( ) . wrapping_sub( Self :: EXP_BITS ) ;
163
187
( 1i32 . wrapping_sub( shift as i32 ) , significand << shift as Self :: Int )
164
188
}
165
- fn is_subnormal( self ) -> bool {
166
- ( self . to_bits( ) & Self :: EXP_MASK ) == Self :: Int :: ZERO
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 ) }
167
199
}
168
200
}
169
201
} ;
0 commit comments