1
+ use core:: mem;
1
2
use core:: num:: FpCategory ;
2
3
use core:: ops:: { Add , Div , Neg } ;
3
4
4
5
use core:: f32;
5
6
use core:: f64;
6
7
7
- use crate :: { Num , NumCast , ToPrimitive } ;
8
+ use { Num , NumCast , ToPrimitive } ;
9
+
10
+ #[ cfg( all( not( feature = "std" ) , feature = "libm" ) ) ]
11
+ use libm;
8
12
9
13
/// Generic trait for floating point numbers that works with `no_std`.
10
14
///
@@ -166,7 +170,6 @@ pub trait FloatCore: Num + NumCast + Neg<Output = Self> + PartialOrd + Copy {
166
170
/// check(0.0f64, false);
167
171
/// ```
168
172
#[ inline]
169
- #[ allow( clippy:: eq_op) ]
170
173
fn is_nan ( self ) -> bool {
171
174
self != self
172
175
}
@@ -367,10 +370,12 @@ pub trait FloatCore: Num + NumCast + Neg<Output = Self> + PartialOrd + Copy {
367
370
} else {
368
371
self - f + one
369
372
}
370
- } else if -f < h {
371
- self - f
372
373
} else {
373
- self - f - one
374
+ if -f < h {
375
+ self - f
376
+ } else {
377
+ self - f - one
378
+ }
374
379
}
375
380
}
376
381
@@ -503,7 +508,8 @@ pub trait FloatCore: Num + NumCast + Neg<Output = Self> + PartialOrd + Copy {
503
508
}
504
509
505
510
/// Returns `true` if `self` is positive, including `+0.0` and
506
- /// `FloatCore::infinity()`, and `FloatCore::nan()`.
511
+ /// `FloatCore::infinity()`, and since Rust 1.20 also
512
+ /// `FloatCore::nan()`.
507
513
///
508
514
/// # Examples
509
515
///
@@ -521,7 +527,6 @@ pub trait FloatCore: Num + NumCast + Neg<Output = Self> + PartialOrd + Copy {
521
527
/// check(-0.0f64, false);
522
528
/// check(f64::NEG_INFINITY, false);
523
529
/// check(f64::MIN_POSITIVE, true);
524
- /// check(f64::NAN, true);
525
530
/// check(-f64::NAN, false);
526
531
/// ```
527
532
#[ inline]
@@ -530,7 +535,8 @@ pub trait FloatCore: Num + NumCast + Neg<Output = Self> + PartialOrd + Copy {
530
535
}
531
536
532
537
/// Returns `true` if `self` is negative, including `-0.0` and
533
- /// `FloatCore::neg_infinity()`, and `-FloatCore::nan()`.
538
+ /// `FloatCore::neg_infinity()`, and since Rust 1.20 also
539
+ /// `-FloatCore::nan()`.
534
540
///
535
541
/// # Examples
536
542
///
@@ -549,7 +555,6 @@ pub trait FloatCore: Num + NumCast + Neg<Output = Self> + PartialOrd + Copy {
549
555
/// check(f64::NEG_INFINITY, true);
550
556
/// check(f64::MIN_POSITIVE, false);
551
557
/// check(f64::NAN, false);
552
- /// check(-f64::NAN, true);
553
558
/// ```
554
559
#[ inline]
555
560
fn is_sign_negative ( self ) -> bool {
@@ -764,7 +769,9 @@ impl FloatCore for f32 {
764
769
const EXP_MASK : u32 = 0x7f800000 ;
765
770
const MAN_MASK : u32 = 0x007fffff ;
766
771
767
- let bits: u32 = self . to_bits ( ) ;
772
+ // Safety: this identical to the implementation of f32::to_bits(),
773
+ // which is only available starting at Rust 1.20
774
+ let bits: u32 = unsafe { mem:: transmute ( self ) } ;
768
775
match ( bits & MAN_MASK , bits & EXP_MASK ) {
769
776
( 0 , 0 ) => FpCategory :: Zero ,
770
777
( _, 0 ) => FpCategory :: Subnormal ,
@@ -779,7 +786,10 @@ impl FloatCore for f32 {
779
786
fn is_sign_negative ( self ) -> bool {
780
787
const SIGN_MASK : u32 = 0x80000000 ;
781
788
782
- self . to_bits ( ) & SIGN_MASK != 0
789
+ // Safety: this identical to the implementation of f32::to_bits(),
790
+ // which is only available starting at Rust 1.20
791
+ let bits: u32 = unsafe { mem:: transmute ( self ) } ;
792
+ bits & SIGN_MASK != 0
783
793
}
784
794
785
795
#[ inline]
@@ -861,7 +871,9 @@ impl FloatCore for f64 {
861
871
const EXP_MASK : u64 = 0x7ff0000000000000 ;
862
872
const MAN_MASK : u64 = 0x000fffffffffffff ;
863
873
864
- let bits: u64 = self . to_bits ( ) ;
874
+ // Safety: this identical to the implementation of f64::to_bits(),
875
+ // which is only available starting at Rust 1.20
876
+ let bits: u64 = unsafe { mem:: transmute ( self ) } ;
865
877
match ( bits & MAN_MASK , bits & EXP_MASK ) {
866
878
( 0 , 0 ) => FpCategory :: Zero ,
867
879
( _, 0 ) => FpCategory :: Subnormal ,
@@ -876,7 +888,10 @@ impl FloatCore for f64 {
876
888
fn is_sign_negative ( self ) -> bool {
877
889
const SIGN_MASK : u64 = 0x8000000000000000 ;
878
890
879
- self . to_bits ( ) & SIGN_MASK != 0
891
+ // Safety: this identical to the implementation of f64::to_bits(),
892
+ // which is only available starting at Rust 1.20
893
+ let bits: u64 = unsafe { mem:: transmute ( self ) } ;
894
+ bits & SIGN_MASK != 0
880
895
}
881
896
882
897
#[ inline]
@@ -1251,42 +1266,38 @@ pub trait Float: Num + Copy + NumCast + PartialOrd + Neg<Output = Self> {
1251
1266
fn signum ( self ) -> Self ;
1252
1267
1253
1268
/// Returns `true` if `self` is positive, including `+0.0`,
1254
- /// `Float::infinity()`, and `Float::nan()`.
1269
+ /// `Float::infinity()`, and since Rust 1.20 also `Float::nan()`.
1255
1270
///
1256
1271
/// ```
1257
1272
/// use num_traits::Float;
1258
1273
/// use std::f64;
1259
1274
///
1260
- /// let nan: f64 = f64::NAN;
1261
1275
/// let neg_nan: f64 = -f64::NAN;
1262
1276
///
1263
1277
/// let f = 7.0;
1264
1278
/// let g = -7.0;
1265
1279
///
1266
1280
/// assert!(f.is_sign_positive());
1267
1281
/// assert!(!g.is_sign_positive());
1268
- /// assert!(nan.is_sign_positive());
1269
1282
/// assert!(!neg_nan.is_sign_positive());
1270
1283
/// ```
1271
1284
fn is_sign_positive ( self ) -> bool ;
1272
1285
1273
1286
/// Returns `true` if `self` is negative, including `-0.0`,
1274
- /// `Float::neg_infinity()`, and `-Float::nan()`.
1287
+ /// `Float::neg_infinity()`, and since Rust 1.20 also `-Float::nan()`.
1275
1288
///
1276
1289
/// ```
1277
1290
/// use num_traits::Float;
1278
1291
/// use std::f64;
1279
1292
///
1280
1293
/// let nan: f64 = f64::NAN;
1281
- /// let neg_nan: f64 = -f64::NAN;
1282
1294
///
1283
1295
/// let f = 7.0;
1284
1296
/// let g = -7.0;
1285
1297
///
1286
1298
/// assert!(!f.is_sign_negative());
1287
1299
/// assert!(g.is_sign_negative());
1288
1300
/// assert!(!nan.is_sign_negative());
1289
- /// assert!(neg_nan.is_sign_negative());
1290
1301
/// ```
1291
1302
fn is_sign_negative ( self ) -> bool ;
1292
1303
@@ -2014,7 +2025,9 @@ macro_rules! float_impl_libm {
2014
2025
}
2015
2026
2016
2027
fn integer_decode_f32 ( f : f32 ) -> ( u64 , i16 , i8 ) {
2017
- let bits: u32 = f. to_bits ( ) ;
2028
+ // Safety: this identical to the implementation of f32::to_bits(),
2029
+ // which is only available starting at Rust 1.20
2030
+ let bits: u32 = unsafe { mem:: transmute ( f) } ;
2018
2031
let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 } ;
2019
2032
let mut exponent: i16 = ( ( bits >> 23 ) & 0xff ) as i16 ;
2020
2033
let mantissa = if exponent == 0 {
@@ -2028,7 +2041,9 @@ fn integer_decode_f32(f: f32) -> (u64, i16, i8) {
2028
2041
}
2029
2042
2030
2043
fn integer_decode_f64 ( f : f64 ) -> ( u64 , i16 , i8 ) {
2031
- let bits: u64 = f. to_bits ( ) ;
2044
+ // Safety: this identical to the implementation of f64::to_bits(),
2045
+ // which is only available starting at Rust 1.20
2046
+ let bits: u64 = unsafe { mem:: transmute ( f) } ;
2032
2047
let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 } ;
2033
2048
let mut exponent: i16 = ( ( bits >> 52 ) & 0x7ff ) as i16 ;
2034
2049
let mantissa = if exponent == 0 {
@@ -2229,7 +2244,7 @@ mod tests {
2229
2244
2230
2245
#[ test]
2231
2246
fn convert_deg_rad ( ) {
2232
- use crate :: float:: FloatCore ;
2247
+ use float:: FloatCore ;
2233
2248
2234
2249
for & ( deg, rad) in & DEG_RAD_PAIRS {
2235
2250
assert ! ( ( FloatCore :: to_degrees( rad) - deg) . abs( ) < 1e-6 ) ;
@@ -2245,7 +2260,7 @@ mod tests {
2245
2260
#[ test]
2246
2261
fn convert_deg_rad_std ( ) {
2247
2262
for & ( deg, rad) in & DEG_RAD_PAIRS {
2248
- use crate :: Float ;
2263
+ use Float ;
2249
2264
2250
2265
assert ! ( ( Float :: to_degrees( rad) - deg) . abs( ) < 1e-6 ) ;
2251
2266
assert ! ( ( Float :: to_radians( deg) - rad) . abs( ) < 1e-6 ) ;
@@ -2257,8 +2272,11 @@ mod tests {
2257
2272
}
2258
2273
2259
2274
#[ test]
2275
+ // This fails with the forwarded `std` implementation in Rust 1.8.
2276
+ // To avoid the failure, the test is limited to `no_std` builds.
2277
+ #[ cfg( not( feature = "std" ) ) ]
2260
2278
fn to_degrees_rounding ( ) {
2261
- use crate :: float:: FloatCore ;
2279
+ use float:: FloatCore ;
2262
2280
2263
2281
assert_eq ! (
2264
2282
FloatCore :: to_degrees( 1_f32 ) ,
@@ -2269,7 +2287,7 @@ mod tests {
2269
2287
#[ test]
2270
2288
#[ cfg( any( feature = "std" , feature = "libm" ) ) ]
2271
2289
fn extra_logs ( ) {
2272
- use crate :: float:: { Float , FloatConst } ;
2290
+ use float:: { Float , FloatConst } ;
2273
2291
2274
2292
fn check < F : Float + FloatConst > ( diff : F ) {
2275
2293
let _2 = F :: from ( 2.0 ) . unwrap ( ) ;
@@ -2288,33 +2306,33 @@ mod tests {
2288
2306
#[ test]
2289
2307
#[ cfg( any( feature = "std" , feature = "libm" ) ) ]
2290
2308
fn copysign ( ) {
2291
- use crate :: float:: Float ;
2309
+ use float:: Float ;
2292
2310
test_copysign_generic ( 2.0_f32 , -2.0_f32 , f32:: nan ( ) ) ;
2293
2311
test_copysign_generic ( 2.0_f64 , -2.0_f64 , f64:: nan ( ) ) ;
2294
2312
test_copysignf ( 2.0_f32 , -2.0_f32 , f32:: nan ( ) ) ;
2295
2313
}
2296
2314
2297
2315
#[ cfg( any( feature = "std" , feature = "libm" ) ) ]
2298
2316
fn test_copysignf ( p : f32 , n : f32 , nan : f32 ) {
2299
- use crate :: float:: Float ;
2317
+ use float:: Float ;
2300
2318
use core:: ops:: Neg ;
2301
2319
2302
2320
assert ! ( p. is_sign_positive( ) ) ;
2303
2321
assert ! ( n. is_sign_negative( ) ) ;
2304
2322
assert ! ( nan. is_nan( ) ) ;
2305
2323
2306
- assert_eq ! ( p, Float :: copysign( p , p) ) ;
2307
- assert_eq ! ( p. neg( ) , Float :: copysign( p , n) ) ;
2324
+ assert_eq ! ( p, p . copysign( p) ) ;
2325
+ assert_eq ! ( p. neg( ) , p . copysign( n) ) ;
2308
2326
2309
- assert_eq ! ( n, Float :: copysign( n , n) ) ;
2310
- assert_eq ! ( n. neg( ) , Float :: copysign( n , p) ) ;
2327
+ assert_eq ! ( n, n . copysign( n) ) ;
2328
+ assert_eq ! ( n. neg( ) , n . copysign( p) ) ;
2311
2329
2312
- assert ! ( Float :: copysign( nan , p) . is_sign_positive( ) ) ;
2313
- assert ! ( Float :: copysign( nan , n) . is_sign_negative( ) ) ;
2330
+ assert ! ( nan . copysign( p) . is_sign_positive( ) ) ;
2331
+ assert ! ( nan . copysign( n) . is_sign_negative( ) ) ;
2314
2332
}
2315
2333
2316
2334
#[ cfg( any( feature = "std" , feature = "libm" ) ) ]
2317
- fn test_copysign_generic < F : crate :: float:: Float + :: core:: fmt:: Debug > ( p : F , n : F , nan : F ) {
2335
+ fn test_copysign_generic < F : :: float:: Float + core:: fmt:: Debug > ( p : F , n : F , nan : F ) {
2318
2336
assert ! ( p. is_sign_positive( ) ) ;
2319
2337
assert ! ( n. is_sign_negative( ) ) ;
2320
2338
assert ! ( nan. is_nan( ) ) ;
0 commit comments