1- use core:: { fmt, ops} ;
1+ use core:: { fmt, mem , ops} ;
22
33use super :: int_traits:: { Int , MinInt } ;
44
@@ -7,15 +7,17 @@ use super::int_traits::{Int, MinInt};
77pub trait Float :
88 Copy
99 + fmt:: Debug
10- + fmt:: Display
1110 + PartialEq
1211 + PartialOrd
1312 + ops:: AddAssign
1413 + ops:: MulAssign
1514 + ops:: Add < Output = Self >
1615 + ops:: Sub < Output = Self >
16+ + ops:: Mul < Output = Self >
1717 + ops:: Div < Output = Self >
1818 + ops:: Rem < Output = Self >
19+ + ops:: Neg < Output = Self >
20+ + ' static
1921{
2022 /// A uint of the same width as the float
2123 type Int : Int < OtherSign = Self :: SignedInt , Unsigned = Self :: Int > ;
@@ -27,11 +29,16 @@ pub trait Float:
2729 type ExpInt : Int ;
2830
2931 const ZERO : Self ;
32+ const NEG_ZERO : Self ;
3033 const ONE : Self ;
3134 const NEG_ONE : Self ;
3235 const INFINITY : Self ;
3336 const NEG_INFINITY : Self ;
3437 const NAN : Self ;
38+ const MAX : Self ;
39+ const MIN : Self ;
40+ const PI : Self ;
41+ const FRAC_PI_2 : Self ;
3542
3643 /// The bitwidth of the float type
3744 const BITS : u32 ;
@@ -69,7 +76,19 @@ pub trait Float:
6976 /// Checks if two floats have the same bit representation. *Except* for NaNs! NaN can be
7077 /// represented in multiple different ways. This method returns `true` if two NaNs are
7178 /// 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+ }
7392
7493 /// Returns true if the value is NaN.
7594 fn is_nan ( self ) -> bool ;
@@ -81,22 +100,35 @@ pub trait Float:
81100 fn is_sign_negative ( self ) -> bool ;
82101
83102 /// 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+ }
85106
86107 /// Returns the exponent, not adjusting for bias.
87108 fn exp ( self ) -> Self :: ExpInt ;
88109
89110 /// 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+ }
91114
92115 /// 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+ }
94119
95120 /// Returns a `Self::Int` transmuted back to `Self`
96121 fn from_bits ( a : Self :: Int ) -> Self ;
97122
98123 /// 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+ }
100132
101133 fn abs ( self ) -> Self {
102134 let abs_mask = !Self :: SIGN_MASK ;
@@ -107,10 +139,18 @@ pub trait Float:
107139 fn normalize ( significand : Self :: Int ) -> ( i32 , Self :: Int ) ;
108140
109141 /// 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+ }
111149
112150 /// 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+ }
114154}
115155
116156macro_rules! float_impl {
@@ -121,11 +161,22 @@ macro_rules! float_impl {
121161 type ExpInt = $expty;
122162
123163 const ZERO : Self = 0.0 ;
164+ const NEG_ZERO : Self = -0.0 ;
124165 const ONE : Self = 1.0 ;
125166 const NEG_ONE : Self = -1.0 ;
126167 const INFINITY : Self = Self :: INFINITY ;
127168 const NEG_INFINITY : Self = Self :: NEG_INFINITY ;
128169 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 ;
129180
130181 const BITS : u32 = $bits;
131182 const SIG_BITS : u32 = $significand_bits;
@@ -141,16 +192,6 @@ macro_rules! float_impl {
141192 fn to_bits_signed( self ) -> Self :: SignedInt {
142193 self . to_bits( ) as Self :: SignedInt
143194 }
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- }
154195 fn is_nan( self ) -> bool {
155196 self . is_nan( )
156197 }
@@ -160,43 +201,16 @@ macro_rules! float_impl {
160201 fn is_sign_negative( self ) -> bool {
161202 self . is_sign_negative( )
162203 }
163- fn is_subnormal( self ) -> bool {
164- ( self . to_bits( ) & Self :: EXP_MASK ) == Self :: Int :: ZERO
165- }
166204 fn exp( self ) -> Self :: ExpInt {
167205 ( ( self . to_bits( ) & Self :: EXP_MASK ) >> Self :: SIG_BITS ) as Self :: ExpInt
168206 }
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- }
175207 fn from_bits( a: Self :: Int ) -> Self {
176208 Self :: from_bits( a)
177209 }
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- }
185210 fn normalize( significand: Self :: Int ) -> ( i32 , Self :: Int ) {
186211 let shift = significand. leading_zeros( ) . wrapping_sub( Self :: EXP_BITS ) ;
187212 ( 1i32 . wrapping_sub( shift as i32 ) , significand << shift as Self :: Int )
188213 }
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- }
200214 }
201215 } ;
202216}
0 commit comments