@@ -6,17 +6,16 @@ use core::{i128, u128};
6
6
use core:: { i16, i32, i64, i8, isize} ;
7
7
use core:: { u16, u32, u64, u8, usize} ;
8
8
9
- use float:: FloatCore ;
10
-
11
9
/// A generic trait for converting a value to a number.
12
10
///
13
11
/// A value can be represented by the target type when it lies within
14
12
/// the range of scalars supported by the target type.
15
13
/// For example, a negative integer cannot be represented by an unsigned
16
- /// integer type, and an `f64 ` with a very high magnitude might not be
17
- /// convertible to an `f32 `.
14
+ /// integer type, and an `i64 ` with a very high magnitude might not be
15
+ /// convertible to an `i32 `.
18
16
/// On the other hand, conversions with possible precision loss or truncation
19
- /// (e.g. an `f32` with a decimal part to an integer type) are admitted.
17
+ /// are admitted, like an `f32` with a decimal part to an integer type, or
18
+ /// even a large `f64` saturating to `f32` infinity.
20
19
pub trait ToPrimitive {
21
20
/// Converts the value of `self` to an `isize`. If the value cannot be
22
21
/// represented by an `isize`, then `None` is returned.
@@ -102,23 +101,29 @@ pub trait ToPrimitive {
102
101
///
103
102
/// This method is only available with feature `i128` enabled on Rust >= 1.26.
104
103
///
105
- /// The default implementation converts through `to_u64()`. Types implementing
104
+ /// The default implementation converts through `to_u64()`. Types implementing
106
105
/// this trait should override this method if they can represent a greater range.
107
106
#[ inline]
108
107
#[ cfg( has_i128) ]
109
108
fn to_u128 ( & self ) -> Option < u128 > {
110
109
self . to_u64 ( ) . map ( From :: from)
111
110
}
112
111
113
- /// Converts the value of `self` to an `f32`. If the value cannot be
114
- /// represented by an `f32`, then `None` is returned.
112
+ /// Converts the value of `self` to an `f32`. Overflows may map to positive
113
+ /// or negative inifinity, otherwise `None` is returned if the value cannot
114
+ /// be represented by an `f32`.
115
115
#[ inline]
116
116
fn to_f32 ( & self ) -> Option < f32 > {
117
117
self . to_f64 ( ) . as_ref ( ) . and_then ( ToPrimitive :: to_f32)
118
118
}
119
119
120
- /// Converts the value of `self` to an `f64`. If the value cannot be
121
- /// represented by an `f64`, then `None` is returned.
120
+ /// Converts the value of `self` to an `f64`. Overflows may map to positive
121
+ /// or negative inifinity, otherwise `None` is returned if the value cannot
122
+ /// be represented by an `f64`.
123
+ ///
124
+ /// The default implementation tries to convert through `to_i64()`, and
125
+ /// failing that through `to_u64()`. Types implementing this trait should
126
+ /// override this method if they can represent a greater range.
122
127
#[ inline]
123
128
fn to_f64 ( & self ) -> Option < f64 > {
124
129
match self . to_i64 ( ) {
@@ -279,14 +284,8 @@ macro_rules! impl_to_primitive_float_to_float {
279
284
( $SrcT: ident : $( fn $method: ident -> $DstT: ident ; ) * ) => { $(
280
285
#[ inline]
281
286
fn $method( & self ) -> Option <$DstT> {
282
- // Only finite values that are reducing size need to worry about overflow.
283
- if size_of:: <$SrcT>( ) > size_of:: <$DstT>( ) && FloatCore :: is_finite( * self ) {
284
- let n = * self as f64 ;
285
- if n < $DstT:: MIN as f64 || n > $DstT:: MAX as f64 {
286
- return None ;
287
- }
288
- }
289
- // We can safely cast NaN, +-inf, and finite values in range.
287
+ // We can safely cast all values, whether NaN, +-inf, or finite.
288
+ // Finite values that are reducing size may saturate to +-inf.
290
289
Some ( * self as $DstT)
291
290
}
292
291
) * }
@@ -404,10 +403,11 @@ impl_to_primitive_float!(f64);
404
403
/// A value can be represented by the target type when it lies within
405
404
/// the range of scalars supported by the target type.
406
405
/// For example, a negative integer cannot be represented by an unsigned
407
- /// integer type, and an `f64 ` with a very high magnitude might not be
408
- /// convertible to an `f32 `.
406
+ /// integer type, and an `i64 ` with a very high magnitude might not be
407
+ /// convertible to an `i32 `.
409
408
/// On the other hand, conversions with possible precision loss or truncation
410
- /// (e.g. an `f32` with a decimal part to an integer type) are admitted.
409
+ /// are admitted, like an `f32` with a decimal part to an integer type, or
410
+ /// even a large `f64` saturating to `f32` infinity.
411
411
pub trait FromPrimitive : Sized {
412
412
/// Converts an `isize` to return an optional value of this type. If the
413
413
/// value cannot be represented by this type, then `None` is returned.
@@ -508,6 +508,10 @@ pub trait FromPrimitive: Sized {
508
508
509
509
/// Converts a `f64` to return an optional value of this type. If the
510
510
/// value cannot be represented by this type, then `None` is returned.
511
+ ///
512
+ /// The default implementation tries to convert through `from_i64()`, and
513
+ /// failing that through `from_u64()`. Types implementing this trait should
514
+ /// override this method if they can represent a greater range.
511
515
#[ inline]
512
516
fn from_f64 ( n : f64 ) -> Option < Self > {
513
517
match n. to_i64 ( ) {
@@ -692,10 +696,11 @@ pub trait NumCast: Sized + ToPrimitive {
692
696
/// A value can be represented by the target type when it lies within
693
697
/// the range of scalars supported by the target type.
694
698
/// For example, a negative integer cannot be represented by an unsigned
695
- /// integer type, and an `f64 ` with a very high magnitude might not be
696
- /// convertible to an `f32 `.
699
+ /// integer type, and an `i64 ` with a very high magnitude might not be
700
+ /// convertible to an `i32 `.
697
701
/// On the other hand, conversions with possible precision loss or truncation
698
- /// (e.g. an `f32` with a decimal part to an integer type) are admitted.
702
+ /// are admitted, like an `f32` with a decimal part to an integer type, or
703
+ /// even a large `f64` saturating to `f32` infinity.
699
704
fn from < T : ToPrimitive > ( n : T ) -> Option < Self > ;
700
705
}
701
706
0 commit comments