Skip to content

Commit 4d11db6

Browse files
committed
Auto merge of #29129 - cuviper:impl-from-for-floats, r=alexcrichton
This is a spiritual successor to #28921, completing the "upcast" idea from rust-num/num#97.
2 parents a18e0b2 + 1a19f98 commit 4d11db6

File tree

2 files changed

+81
-3
lines changed

2 files changed

+81
-3
lines changed

src/libcore/num/mod.rs

+24-3
Original file line numberDiff line numberDiff line change
@@ -1473,14 +1473,14 @@ impl fmt::Display for ParseIntError {
14731473

14741474
pub use num::dec2flt::ParseFloatError;
14751475

1476-
// Conversion traits for primitive integer types
1476+
// Conversion traits for primitive integer and float types
14771477
// Conversions T -> T are covered by a blanket impl and therefore excluded
14781478
// Some conversions from and to usize/isize are not implemented due to portability concerns
14791479
macro_rules! impl_from {
14801480
($Small: ty, $Large: ty) => {
1481-
#[stable(feature = "lossless_int_conv", since = "1.5.0")]
1481+
#[stable(feature = "lossless_prim_conv", since = "1.5.0")]
14821482
impl From<$Small> for $Large {
1483-
#[stable(feature = "lossless_int_conv", since = "1.5.0")]
1483+
#[stable(feature = "lossless_prim_conv", since = "1.5.0")]
14841484
#[inline]
14851485
fn from(small: $Small) -> $Large {
14861486
small as $Large
@@ -1514,3 +1514,24 @@ impl_from! { u8, i64 }
15141514
impl_from! { u16, i32 }
15151515
impl_from! { u16, i64 }
15161516
impl_from! { u32, i64 }
1517+
1518+
// Note: integers can only be represented with full precision in a float if
1519+
// they fit in the significand, which is 24 bits in f32 and 53 bits in f64.
1520+
// Lossy float conversions are not implemented at this time.
1521+
1522+
// Signed -> Float
1523+
impl_from! { i8, f32 }
1524+
impl_from! { i8, f64 }
1525+
impl_from! { i16, f32 }
1526+
impl_from! { i16, f64 }
1527+
impl_from! { i32, f64 }
1528+
1529+
// Unsigned -> Float
1530+
impl_from! { u8, f32 }
1531+
impl_from! { u8, f64 }
1532+
impl_from! { u16, f32 }
1533+
impl_from! { u16, f64 }
1534+
impl_from! { u32, f64 }
1535+
1536+
// Float -> Float
1537+
impl_from! { f32, f64 }

src/libcoretest/num/mod.rs

+57
Original file line numberDiff line numberDiff line change
@@ -177,4 +177,61 @@ mod tests {
177177
test_impl_from! { test_u16i32, u16, i32 }
178178
test_impl_from! { test_u16i64, u16, i64 }
179179
test_impl_from! { test_u32i64, u32, i64 }
180+
181+
// Signed -> Float
182+
test_impl_from! { test_i8f32, i8, f32 }
183+
test_impl_from! { test_i8f64, i8, f64 }
184+
test_impl_from! { test_i16f32, i16, f32 }
185+
test_impl_from! { test_i16f64, i16, f64 }
186+
test_impl_from! { test_i32f64, i32, f64 }
187+
188+
// Unsigned -> Float
189+
test_impl_from! { test_u8f32, u8, f32 }
190+
test_impl_from! { test_u8f64, u8, f64 }
191+
test_impl_from! { test_u16f32, u16, f32 }
192+
test_impl_from! { test_u16f64, u16, f64 }
193+
test_impl_from! { test_u32f64, u32, f64 }
194+
195+
// Float -> Float
196+
#[test]
197+
fn test_f32f64() {
198+
use core::f32;
199+
200+
let max: f64 = f32::MAX.into();
201+
assert_eq!(max as f32, f32::MAX);
202+
assert!(max.is_normal());
203+
204+
let min: f64 = f32::MIN.into();
205+
assert_eq!(min as f32, f32::MIN);
206+
assert!(min.is_normal());
207+
208+
let min_positive: f64 = f32::MIN_POSITIVE.into();
209+
assert_eq!(min_positive as f32, f32::MIN_POSITIVE);
210+
assert!(min_positive.is_normal());
211+
212+
let epsilon: f64 = f32::EPSILON.into();
213+
assert_eq!(epsilon as f32, f32::EPSILON);
214+
assert!(epsilon.is_normal());
215+
216+
let zero: f64 = (0.0f32).into();
217+
assert_eq!(zero as f32, 0.0f32);
218+
assert!(zero.is_sign_positive());
219+
220+
let neg_zero: f64 = (-0.0f32).into();
221+
assert_eq!(neg_zero as f32, -0.0f32);
222+
assert!(neg_zero.is_sign_negative());
223+
224+
let infinity: f64 = f32::INFINITY.into();
225+
assert_eq!(infinity as f32, f32::INFINITY);
226+
assert!(infinity.is_infinite());
227+
assert!(infinity.is_sign_positive());
228+
229+
let neg_infinity: f64 = f32::NEG_INFINITY.into();
230+
assert_eq!(neg_infinity as f32, f32::NEG_INFINITY);
231+
assert!(neg_infinity.is_infinite());
232+
assert!(neg_infinity.is_sign_negative());
233+
234+
let nan: f64 = f32::NAN.into();
235+
assert!(nan.is_nan());
236+
}
180237
}

0 commit comments

Comments
 (0)