Skip to content

Commit 82eead0

Browse files
committed
Return Err(()) when trying to convert sNaN representation to float
1 parent 32a43da commit 82eead0

File tree

2 files changed

+34
-14
lines changed

2 files changed

+34
-14
lines changed

src/libstd/f32.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,16 +1254,26 @@ impl f32 {
12541254
///
12551255
/// Note that this function is distinct from casting.
12561256
///
1257+
/// Returns `Err(())` if the representation of a signaling NaN "sNaN"
1258+
/// float, is passed to the function.
1259+
///
12571260
/// ```
12581261
/// #![feature(float_bits_conv)]
12591262
/// use std::f32;
1260-
/// let difference = (f32::from_bits(0x41480000) - 12.5).abs();
1263+
/// let v = f32::from_bits(0x41480000).unwrap();
1264+
/// let difference = (v - 12.5).abs();
12611265
/// assert!(difference <= 1e-5);
1266+
/// // Example for a signaling NaN value:
1267+
/// assert_eq!(f32::from_bits(0x7F800001), Err(()));
12621268
/// ```
12631269
#[unstable(feature = "float_bits_conv", reason = "recently added", issue = "0")]
12641270
#[inline]
1265-
pub fn from_bits(v: u32) -> Self {
1266-
unsafe { ::mem::transmute(v) }
1271+
pub fn from_bits(v: u32) -> Result<Self, ()> {
1272+
match v {
1273+
0x7F800001 ... 0x7FBFFFFF |
1274+
0xFF800001 ... 0xFFBFFFFF => Err(()),
1275+
_ => Ok(unsafe { ::mem::transmute(v) }),
1276+
}
12671277
}
12681278
}
12691279

@@ -1916,9 +1926,9 @@ mod tests {
19161926
assert_eq!((12.5f32).to_bits(), 0x41480000);
19171927
assert_eq!((1337f32).to_bits(), 0x44a72000);
19181928
assert_eq!((-14.25f32).to_bits(), 0xc1640000);
1919-
assert_approx_eq!(f32::from_bits(0x3f800000), 1.0);
1920-
assert_approx_eq!(f32::from_bits(0x41480000), 12.5);
1921-
assert_approx_eq!(f32::from_bits(0x44a72000), 1337.0);
1922-
assert_approx_eq!(f32::from_bits(0xc1640000), -14.25);
1929+
assert_approx_eq!(f32::from_bits(0x3f800000).unwrap(), 1.0);
1930+
assert_approx_eq!(f32::from_bits(0x41480000).unwrap(), 12.5);
1931+
assert_approx_eq!(f32::from_bits(0x44a72000).unwrap(), 1337.0);
1932+
assert_approx_eq!(f32::from_bits(0xc1640000).unwrap(), -14.25);
19231933
}
19241934
}

src/libstd/f64.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,16 +1146,26 @@ impl f64 {
11461146
///
11471147
/// Note that this function is distinct from casting.
11481148
///
1149+
/// Returns `Err(())` if the representation of a signaling NaN "sNaN"
1150+
/// float, is passed to the function.
1151+
///
11491152
/// ```
11501153
/// #![feature(float_bits_conv)]
11511154
/// use std::f64;
1152-
/// let difference = (f64::from_bits(0x4029000000000000) - 12.5).abs();
1155+
/// let v = f64::from_bits(0x4029000000000000).unwrap();
1156+
/// let difference = (v - 12.5).abs();
11531157
/// assert!(difference <= 1e-5);
1158+
/// // Example for a signaling NaN value:
1159+
/// assert_eq!(f64::from_bits(0x7FF0000000000001), Err(()));
11541160
/// ```
11551161
#[unstable(feature = "float_bits_conv", reason = "recently added", issue = "0")]
11561162
#[inline]
1157-
pub fn from_bits(v: u64) -> Self {
1158-
unsafe { ::mem::transmute(v) }
1163+
pub fn from_bits(v: u64) -> Result<Self, ()> {
1164+
match v {
1165+
0x7FF0000000000001 ... 0x7FF7FFFFFFFFFFFF |
1166+
0xFFF0000000000001 ... 0xFFF7FFFFFFFFFFFF => Err(()),
1167+
_ => Ok(unsafe { ::mem::transmute(v) }),
1168+
}
11591169
}
11601170
}
11611171

@@ -1801,9 +1811,9 @@ mod tests {
18011811
assert_eq!((12.5f64).to_bits(), 0x4029000000000000);
18021812
assert_eq!((1337f64).to_bits(), 0x4094e40000000000);
18031813
assert_eq!((-14.25f64).to_bits(), 0xc02c800000000000);
1804-
assert_approx_eq!(f64::from_bits(0x3ff0000000000000), 1.0);
1805-
assert_approx_eq!(f64::from_bits(0x4029000000000000), 12.5);
1806-
assert_approx_eq!(f64::from_bits(0x4094e40000000000), 1337.0);
1807-
assert_approx_eq!(f64::from_bits(0xc02c800000000000), -14.25);
1814+
assert_approx_eq!(f64::from_bits(0x3ff0000000000000).unwrap(), 1.0);
1815+
assert_approx_eq!(f64::from_bits(0x4029000000000000).unwrap(), 12.5);
1816+
assert_approx_eq!(f64::from_bits(0x4094e40000000000).unwrap(), 1337.0);
1817+
assert_approx_eq!(f64::from_bits(0xc02c800000000000).unwrap(), -14.25);
18081818
}
18091819
}

0 commit comments

Comments
 (0)