Skip to content

Commit

Permalink
Return Err(()) when trying to convert sNaN representation to float
Browse files Browse the repository at this point in the history
  • Loading branch information
est31 committed Apr 18, 2017
1 parent 32a43da commit 82eead0
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 14 deletions.
24 changes: 17 additions & 7 deletions src/libstd/f32.rs
Expand Up @@ -1254,16 +1254,26 @@ impl f32 {
///
/// Note that this function is distinct from casting.
///
/// Returns `Err(())` if the representation of a signaling NaN "sNaN"
/// float, is passed to the function.
///
/// ```
/// #![feature(float_bits_conv)]
/// use std::f32;
/// let difference = (f32::from_bits(0x41480000) - 12.5).abs();
/// let v = f32::from_bits(0x41480000).unwrap();
/// let difference = (v - 12.5).abs();
/// assert!(difference <= 1e-5);
/// // Example for a signaling NaN value:
/// assert_eq!(f32::from_bits(0x7F800001), Err(()));
/// ```
#[unstable(feature = "float_bits_conv", reason = "recently added", issue = "0")]
#[inline]
pub fn from_bits(v: u32) -> Self {
unsafe { ::mem::transmute(v) }
pub fn from_bits(v: u32) -> Result<Self, ()> {
match v {
0x7F800001 ... 0x7FBFFFFF |
0xFF800001 ... 0xFFBFFFFF => Err(()),
_ => Ok(unsafe { ::mem::transmute(v) }),
}
}
}

Expand Down Expand Up @@ -1916,9 +1926,9 @@ mod tests {
assert_eq!((12.5f32).to_bits(), 0x41480000);
assert_eq!((1337f32).to_bits(), 0x44a72000);
assert_eq!((-14.25f32).to_bits(), 0xc1640000);
assert_approx_eq!(f32::from_bits(0x3f800000), 1.0);
assert_approx_eq!(f32::from_bits(0x41480000), 12.5);
assert_approx_eq!(f32::from_bits(0x44a72000), 1337.0);
assert_approx_eq!(f32::from_bits(0xc1640000), -14.25);
assert_approx_eq!(f32::from_bits(0x3f800000).unwrap(), 1.0);
assert_approx_eq!(f32::from_bits(0x41480000).unwrap(), 12.5);
assert_approx_eq!(f32::from_bits(0x44a72000).unwrap(), 1337.0);
assert_approx_eq!(f32::from_bits(0xc1640000).unwrap(), -14.25);
}
}
24 changes: 17 additions & 7 deletions src/libstd/f64.rs
Expand Up @@ -1146,16 +1146,26 @@ impl f64 {
///
/// Note that this function is distinct from casting.
///
/// Returns `Err(())` if the representation of a signaling NaN "sNaN"
/// float, is passed to the function.
///
/// ```
/// #![feature(float_bits_conv)]
/// use std::f64;
/// let difference = (f64::from_bits(0x4029000000000000) - 12.5).abs();
/// let v = f64::from_bits(0x4029000000000000).unwrap();
/// let difference = (v - 12.5).abs();
/// assert!(difference <= 1e-5);
/// // Example for a signaling NaN value:
/// assert_eq!(f64::from_bits(0x7FF0000000000001), Err(()));
/// ```
#[unstable(feature = "float_bits_conv", reason = "recently added", issue = "0")]
#[inline]
pub fn from_bits(v: u64) -> Self {
unsafe { ::mem::transmute(v) }
pub fn from_bits(v: u64) -> Result<Self, ()> {
match v {
0x7FF0000000000001 ... 0x7FF7FFFFFFFFFFFF |
0xFFF0000000000001 ... 0xFFF7FFFFFFFFFFFF => Err(()),
_ => Ok(unsafe { ::mem::transmute(v) }),
}
}
}

Expand Down Expand Up @@ -1801,9 +1811,9 @@ mod tests {
assert_eq!((12.5f64).to_bits(), 0x4029000000000000);
assert_eq!((1337f64).to_bits(), 0x4094e40000000000);
assert_eq!((-14.25f64).to_bits(), 0xc02c800000000000);
assert_approx_eq!(f64::from_bits(0x3ff0000000000000), 1.0);
assert_approx_eq!(f64::from_bits(0x4029000000000000), 12.5);
assert_approx_eq!(f64::from_bits(0x4094e40000000000), 1337.0);
assert_approx_eq!(f64::from_bits(0xc02c800000000000), -14.25);
assert_approx_eq!(f64::from_bits(0x3ff0000000000000).unwrap(), 1.0);
assert_approx_eq!(f64::from_bits(0x4029000000000000).unwrap(), 12.5);
assert_approx_eq!(f64::from_bits(0x4094e40000000000).unwrap(), 1337.0);
assert_approx_eq!(f64::from_bits(0xc02c800000000000).unwrap(), -14.25);
}
}

0 comments on commit 82eead0

Please sign in to comment.