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
}
@@ -389,10 +392,12 @@ pub trait FloatCore: Num + NumCast + Neg<Output = Self> + PartialOrd + Copy {
389
392
} else {
390
393
self - f + one
391
394
}
392
- } else if -f < h {
393
- self - f
394
395
} else {
395
- self - f - one
396
+ if -f < h {
397
+ self - f
398
+ } else {
399
+ self - f - one
400
+ }
396
401
}
397
402
}
398
403
@@ -525,7 +530,8 @@ pub trait FloatCore: Num + NumCast + Neg<Output = Self> + PartialOrd + Copy {
525
530
}
526
531
527
532
/// Returns `true` if `self` is positive, including `+0.0` and
528
- /// `FloatCore::infinity()`, and `FloatCore::nan()`.
533
+ /// `FloatCore::infinity()`, and since Rust 1.20 also
534
+ /// `FloatCore::nan()`.
529
535
///
530
536
/// # Examples
531
537
///
@@ -543,7 +549,6 @@ pub trait FloatCore: Num + NumCast + Neg<Output = Self> + PartialOrd + Copy {
543
549
/// check(-0.0f64, false);
544
550
/// check(f64::NEG_INFINITY, false);
545
551
/// check(f64::MIN_POSITIVE, true);
546
- /// check(f64::NAN, true);
547
552
/// check(-f64::NAN, false);
548
553
/// ```
549
554
#[ inline]
@@ -552,7 +557,8 @@ pub trait FloatCore: Num + NumCast + Neg<Output = Self> + PartialOrd + Copy {
552
557
}
553
558
554
559
/// Returns `true` if `self` is negative, including `-0.0` and
555
- /// `FloatCore::neg_infinity()`, and `-FloatCore::nan()`.
560
+ /// `FloatCore::neg_infinity()`, and since Rust 1.20 also
561
+ /// `-FloatCore::nan()`.
556
562
///
557
563
/// # Examples
558
564
///
@@ -571,7 +577,6 @@ pub trait FloatCore: Num + NumCast + Neg<Output = Self> + PartialOrd + Copy {
571
577
/// check(f64::NEG_INFINITY, true);
572
578
/// check(f64::MIN_POSITIVE, false);
573
579
/// check(f64::NAN, false);
574
- /// check(-f64::NAN, true);
575
580
/// ```
576
581
#[ inline]
577
582
fn is_sign_negative ( self ) -> bool {
@@ -786,7 +791,9 @@ impl FloatCore for f32 {
786
791
const EXP_MASK : u32 = 0x7f800000 ;
787
792
const MAN_MASK : u32 = 0x007fffff ;
788
793
789
- let bits: u32 = self . to_bits ( ) ;
794
+ // Safety: this identical to the implementation of f32::to_bits(),
795
+ // which is only available starting at Rust 1.20
796
+ let bits: u32 = unsafe { mem:: transmute ( self ) } ;
790
797
match ( bits & MAN_MASK , bits & EXP_MASK ) {
791
798
( 0 , 0 ) => FpCategory :: Zero ,
792
799
( _, 0 ) => FpCategory :: Subnormal ,
@@ -801,7 +808,10 @@ impl FloatCore for f32 {
801
808
fn is_sign_negative ( self ) -> bool {
802
809
const SIGN_MASK : u32 = 0x80000000 ;
803
810
804
- self . to_bits ( ) & SIGN_MASK != 0
811
+ // Safety: this identical to the implementation of f32::to_bits(),
812
+ // which is only available starting at Rust 1.20
813
+ let bits: u32 = unsafe { mem:: transmute ( self ) } ;
814
+ bits & SIGN_MASK != 0
805
815
}
806
816
807
817
#[ inline]
@@ -883,7 +893,9 @@ impl FloatCore for f64 {
883
893
const EXP_MASK : u64 = 0x7ff0000000000000 ;
884
894
const MAN_MASK : u64 = 0x000fffffffffffff ;
885
895
886
- let bits: u64 = self . to_bits ( ) ;
896
+ // Safety: this identical to the implementation of f64::to_bits(),
897
+ // which is only available starting at Rust 1.20
898
+ let bits: u64 = unsafe { mem:: transmute ( self ) } ;
887
899
match ( bits & MAN_MASK , bits & EXP_MASK ) {
888
900
( 0 , 0 ) => FpCategory :: Zero ,
889
901
( _, 0 ) => FpCategory :: Subnormal ,
@@ -898,7 +910,10 @@ impl FloatCore for f64 {
898
910
fn is_sign_negative ( self ) -> bool {
899
911
const SIGN_MASK : u64 = 0x8000000000000000 ;
900
912
901
- self . to_bits ( ) & SIGN_MASK != 0
913
+ // Safety: this identical to the implementation of f64::to_bits(),
914
+ // which is only available starting at Rust 1.20
915
+ let bits: u64 = unsafe { mem:: transmute ( self ) } ;
916
+ bits & SIGN_MASK != 0
902
917
}
903
918
904
919
#[ inline]
@@ -1294,42 +1309,38 @@ pub trait Float: Num + Copy + NumCast + PartialOrd + Neg<Output = Self> {
1294
1309
fn signum ( self ) -> Self ;
1295
1310
1296
1311
/// Returns `true` if `self` is positive, including `+0.0`,
1297
- /// `Float::infinity()`, and `Float::nan()`.
1312
+ /// `Float::infinity()`, and since Rust 1.20 also `Float::nan()`.
1298
1313
///
1299
1314
/// ```
1300
1315
/// use num_traits::Float;
1301
1316
/// use std::f64;
1302
1317
///
1303
- /// let nan: f64 = f64::NAN;
1304
1318
/// let neg_nan: f64 = -f64::NAN;
1305
1319
///
1306
1320
/// let f = 7.0;
1307
1321
/// let g = -7.0;
1308
1322
///
1309
1323
/// assert!(f.is_sign_positive());
1310
1324
/// assert!(!g.is_sign_positive());
1311
- /// assert!(nan.is_sign_positive());
1312
1325
/// assert!(!neg_nan.is_sign_positive());
1313
1326
/// ```
1314
1327
fn is_sign_positive ( self ) -> bool ;
1315
1328
1316
1329
/// Returns `true` if `self` is negative, including `-0.0`,
1317
- /// `Float::neg_infinity()`, and `-Float::nan()`.
1330
+ /// `Float::neg_infinity()`, and since Rust 1.20 also `-Float::nan()`.
1318
1331
///
1319
1332
/// ```
1320
1333
/// use num_traits::Float;
1321
1334
/// use std::f64;
1322
1335
///
1323
1336
/// let nan: f64 = f64::NAN;
1324
- /// let neg_nan: f64 = -f64::NAN;
1325
1337
///
1326
1338
/// let f = 7.0;
1327
1339
/// let g = -7.0;
1328
1340
///
1329
1341
/// assert!(!f.is_sign_negative());
1330
1342
/// assert!(g.is_sign_negative());
1331
1343
/// assert!(!nan.is_sign_negative());
1332
- /// assert!(neg_nan.is_sign_negative());
1333
1344
/// ```
1334
1345
fn is_sign_negative ( self ) -> bool ;
1335
1346
@@ -2058,7 +2069,9 @@ macro_rules! float_impl_libm {
2058
2069
}
2059
2070
2060
2071
fn integer_decode_f32 ( f : f32 ) -> ( u64 , i16 , i8 ) {
2061
- let bits: u32 = f. to_bits ( ) ;
2072
+ // Safety: this identical to the implementation of f32::to_bits(),
2073
+ // which is only available starting at Rust 1.20
2074
+ let bits: u32 = unsafe { mem:: transmute ( f) } ;
2062
2075
let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 } ;
2063
2076
let mut exponent: i16 = ( ( bits >> 23 ) & 0xff ) as i16 ;
2064
2077
let mantissa = if exponent == 0 {
@@ -2072,7 +2085,9 @@ fn integer_decode_f32(f: f32) -> (u64, i16, i8) {
2072
2085
}
2073
2086
2074
2087
fn integer_decode_f64 ( f : f64 ) -> ( u64 , i16 , i8 ) {
2075
- let bits: u64 = f. to_bits ( ) ;
2088
+ // Safety: this identical to the implementation of f64::to_bits(),
2089
+ // which is only available starting at Rust 1.20
2090
+ let bits: u64 = unsafe { mem:: transmute ( f) } ;
2076
2091
let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 } ;
2077
2092
let mut exponent: i16 = ( ( bits >> 52 ) & 0x7ff ) as i16 ;
2078
2093
let mantissa = if exponent == 0 {
@@ -2273,7 +2288,7 @@ mod tests {
2273
2288
2274
2289
#[ test]
2275
2290
fn convert_deg_rad ( ) {
2276
- use crate :: float:: FloatCore ;
2291
+ use float:: FloatCore ;
2277
2292
2278
2293
for & ( deg, rad) in & DEG_RAD_PAIRS {
2279
2294
assert ! ( ( FloatCore :: to_degrees( rad) - deg) . abs( ) < 1e-6 ) ;
@@ -2289,7 +2304,7 @@ mod tests {
2289
2304
#[ test]
2290
2305
fn convert_deg_rad_std ( ) {
2291
2306
for & ( deg, rad) in & DEG_RAD_PAIRS {
2292
- use crate :: Float ;
2307
+ use Float ;
2293
2308
2294
2309
assert ! ( ( Float :: to_degrees( rad) - deg) . abs( ) < 1e-6 ) ;
2295
2310
assert ! ( ( Float :: to_radians( deg) - rad) . abs( ) < 1e-6 ) ;
@@ -2301,8 +2316,11 @@ mod tests {
2301
2316
}
2302
2317
2303
2318
#[ test]
2319
+ // This fails with the forwarded `std` implementation in Rust 1.8.
2320
+ // To avoid the failure, the test is limited to `no_std` builds.
2321
+ #[ cfg( not( feature = "std" ) ) ]
2304
2322
fn to_degrees_rounding ( ) {
2305
- use crate :: float:: FloatCore ;
2323
+ use float:: FloatCore ;
2306
2324
2307
2325
assert_eq ! (
2308
2326
FloatCore :: to_degrees( 1_f32 ) ,
@@ -2313,7 +2331,7 @@ mod tests {
2313
2331
#[ test]
2314
2332
#[ cfg( any( feature = "std" , feature = "libm" ) ) ]
2315
2333
fn extra_logs ( ) {
2316
- use crate :: float:: { Float , FloatConst } ;
2334
+ use float:: { Float , FloatConst } ;
2317
2335
2318
2336
fn check < F : Float + FloatConst > ( diff : F ) {
2319
2337
let _2 = F :: from ( 2.0 ) . unwrap ( ) ;
@@ -2332,33 +2350,33 @@ mod tests {
2332
2350
#[ test]
2333
2351
#[ cfg( any( feature = "std" , feature = "libm" ) ) ]
2334
2352
fn copysign ( ) {
2335
- use crate :: float:: Float ;
2353
+ use float:: Float ;
2336
2354
test_copysign_generic ( 2.0_f32 , -2.0_f32 , f32:: nan ( ) ) ;
2337
2355
test_copysign_generic ( 2.0_f64 , -2.0_f64 , f64:: nan ( ) ) ;
2338
2356
test_copysignf ( 2.0_f32 , -2.0_f32 , f32:: nan ( ) ) ;
2339
2357
}
2340
2358
2341
2359
#[ cfg( any( feature = "std" , feature = "libm" ) ) ]
2342
2360
fn test_copysignf ( p : f32 , n : f32 , nan : f32 ) {
2343
- use crate :: float:: Float ;
2361
+ use float:: Float ;
2344
2362
use core:: ops:: Neg ;
2345
2363
2346
2364
assert ! ( p. is_sign_positive( ) ) ;
2347
2365
assert ! ( n. is_sign_negative( ) ) ;
2348
2366
assert ! ( nan. is_nan( ) ) ;
2349
2367
2350
- assert_eq ! ( p, Float :: copysign( p , p) ) ;
2351
- assert_eq ! ( p. neg( ) , Float :: copysign( p , n) ) ;
2368
+ assert_eq ! ( p, p . copysign( p) ) ;
2369
+ assert_eq ! ( p. neg( ) , p . copysign( n) ) ;
2352
2370
2353
- assert_eq ! ( n, Float :: copysign( n , n) ) ;
2354
- assert_eq ! ( n. neg( ) , Float :: copysign( n , p) ) ;
2371
+ assert_eq ! ( n, n . copysign( n) ) ;
2372
+ assert_eq ! ( n. neg( ) , n . copysign( p) ) ;
2355
2373
2356
- assert ! ( Float :: copysign( nan , p) . is_sign_positive( ) ) ;
2357
- assert ! ( Float :: copysign( nan , n) . is_sign_negative( ) ) ;
2374
+ assert ! ( nan . copysign( p) . is_sign_positive( ) ) ;
2375
+ assert ! ( nan . copysign( n) . is_sign_negative( ) ) ;
2358
2376
}
2359
2377
2360
2378
#[ cfg( any( feature = "std" , feature = "libm" ) ) ]
2361
- fn test_copysign_generic < F : crate :: float:: Float + :: core:: fmt:: Debug > ( p : F , n : F , nan : F ) {
2379
+ fn test_copysign_generic < F : :: float:: Float + core:: fmt:: Debug > ( p : F , n : F , nan : F ) {
2362
2380
assert ! ( p. is_sign_positive( ) ) ;
2363
2381
assert ! ( n. is_sign_negative( ) ) ;
2364
2382
assert ! ( nan. is_nan( ) ) ;
0 commit comments