Skip to content

Commit

Permalink
Auto merge of #62366 - lzutao:feature/float-from-to-bytes, r=SimonSapin
Browse files Browse the repository at this point in the history
Add float conversions to and from bytes

Rework of #58756. Address #58756 (comment).

Fixes #57492.

r? @SimonSapin
  • Loading branch information
bors committed Jul 8, 2019
2 parents db592f4 + df53a3f commit 10840b8
Show file tree
Hide file tree
Showing 2 changed files with 236 additions and 6 deletions.
121 changes: 118 additions & 3 deletions src/libcore/num/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,15 +450,130 @@ impl f32 {
/// # Examples
///
/// ```
/// use std::f32;
/// let v = f32::from_bits(0x41480000);
/// let difference = (v - 12.5).abs();
/// assert!(difference <= 1e-5);
/// assert_eq!(v, 12.5);
/// ```
#[stable(feature = "float_bits_conv", since = "1.20.0")]
#[inline]
pub fn from_bits(v: u32) -> Self {
// It turns out the safety issues with sNaN were overblown! Hooray!
unsafe { mem::transmute(v) }
}

/// Return the memory representation of this floating point number as a byte array in
/// big-endian (network) byte order.
///
/// # Examples
///
/// ```
/// #![feature(float_to_from_bytes)]
/// let bytes = 12.5f32.to_be_bytes();
/// assert_eq!(bytes, [0x41, 0x48, 0x00, 0x00]);
/// ```
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
#[inline]
pub fn to_be_bytes(self) -> [u8; 4] {
self.to_bits().to_be_bytes()
}

/// Return the memory representation of this floating point number as a byte array in
/// little-endian byte order.
///
/// # Examples
///
/// ```
/// #![feature(float_to_from_bytes)]
/// let bytes = 12.5f32.to_le_bytes();
/// assert_eq!(bytes, [0x00, 0x00, 0x48, 0x41]);
/// ```
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
#[inline]
pub fn to_le_bytes(self) -> [u8; 4] {
self.to_bits().to_le_bytes()
}

/// Return the memory representation of this floating point number as a byte array in
/// native byte order.
///
/// As the target platform's native endianness is used, portable code
/// should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, instead.
///
/// [`to_be_bytes`]: #method.to_be_bytes
/// [`to_le_bytes`]: #method.to_le_bytes
///
/// # Examples
///
/// ```
/// #![feature(float_to_from_bytes)]
/// let bytes = 12.5f32.to_ne_bytes();
/// assert_eq!(
/// bytes,
/// if cfg!(target_endian = "big") {
/// [0x41, 0x48, 0x00, 0x00]
/// } else {
/// [0x00, 0x00, 0x48, 0x41]
/// }
/// );
/// ```
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
#[inline]
pub fn to_ne_bytes(self) -> [u8; 4] {
self.to_bits().to_ne_bytes()
}

/// Create a floating point value from its representation as a byte array in big endian.
///
/// # Examples
///
/// ```
/// #![feature(float_to_from_bytes)]
/// let value = f32::from_be_bytes([0x41, 0x48, 0x00, 0x00]);
/// assert_eq!(value, 12.5);
/// ```
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
#[inline]
pub fn from_be_bytes(bytes: [u8; 4]) -> Self {
Self::from_bits(u32::from_be_bytes(bytes))
}

/// Create a floating point value from its representation as a byte array in big endian.
///
/// # Examples
///
/// ```
/// #![feature(float_to_from_bytes)]
/// let value = f32::from_le_bytes([0x00, 0x00, 0x48, 0x41]);
/// assert_eq!(value, 12.5);
/// ```
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
#[inline]
pub fn from_le_bytes(bytes: [u8; 4]) -> Self {
Self::from_bits(u32::from_le_bytes(bytes))
}

/// Create a floating point value from its representation as a byte array in big endian.
///
/// As the target platform's native endianness is used, portable code
/// likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as
/// appropriate instead.
///
/// [`from_be_bytes`]: #method.from_be_bytes
/// [`from_le_bytes`]: #method.from_le_bytes
///
/// # Examples
///
/// ```
/// #![feature(float_to_from_bytes)]
/// let value = f32::from_ne_bytes(if cfg!(target_endian = "big") {
/// [0x41, 0x48, 0x00, 0x00]
/// } else {
/// [0x00, 0x00, 0x48, 0x41]
/// });
/// assert_eq!(value, 12.5);
/// ```
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
#[inline]
pub fn from_ne_bytes(bytes: [u8; 4]) -> Self {
Self::from_bits(u32::from_ne_bytes(bytes))
}
}
121 changes: 118 additions & 3 deletions src/libcore/num/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,15 +463,130 @@ impl f64 {
/// # Examples
///
/// ```
/// use std::f64;
/// let v = f64::from_bits(0x4029000000000000);
/// let difference = (v - 12.5).abs();
/// assert!(difference <= 1e-5);
/// assert_eq!(v, 12.5);
/// ```
#[stable(feature = "float_bits_conv", since = "1.20.0")]
#[inline]
pub fn from_bits(v: u64) -> Self {
// It turns out the safety issues with sNaN were overblown! Hooray!
unsafe { mem::transmute(v) }
}

/// Return the memory representation of this floating point number as a byte array in
/// big-endian (network) byte order.
///
/// # Examples
///
/// ```
/// #![feature(float_to_from_bytes)]
/// let bytes = 12.5f64.to_be_bytes();
/// assert_eq!(bytes, [0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
/// ```
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
#[inline]
pub fn to_be_bytes(self) -> [u8; 8] {
self.to_bits().to_be_bytes()
}

/// Return the memory representation of this floating point number as a byte array in
/// little-endian byte order.
///
/// # Examples
///
/// ```
/// #![feature(float_to_from_bytes)]
/// let bytes = 12.5f64.to_le_bytes();
/// assert_eq!(bytes, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]);
/// ```
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
#[inline]
pub fn to_le_bytes(self) -> [u8; 8] {
self.to_bits().to_le_bytes()
}

/// Return the memory representation of this floating point number as a byte array in
/// native byte order.
///
/// As the target platform's native endianness is used, portable code
/// should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, instead.
///
/// [`to_be_bytes`]: #method.to_be_bytes
/// [`to_le_bytes`]: #method.to_le_bytes
///
/// # Examples
///
/// ```
/// #![feature(float_to_from_bytes)]
/// let bytes = 12.5f64.to_ne_bytes();
/// assert_eq!(
/// bytes,
/// if cfg!(target_endian = "big") {
/// [0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
/// } else {
/// [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]
/// }
/// );
/// ```
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
#[inline]
pub fn to_ne_bytes(self) -> [u8; 8] {
self.to_bits().to_ne_bytes()
}

/// Create a floating point value from its representation as a byte array in big endian.
///
/// # Examples
///
/// ```
/// #![feature(float_to_from_bytes)]
/// let value = f64::from_be_bytes([0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
/// assert_eq!(value, 12.5);
/// ```
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
#[inline]
pub fn from_be_bytes(bytes: [u8; 8]) -> Self {
Self::from_bits(u64::from_be_bytes(bytes))
}

/// Create a floating point value from its representation as a byte array in big endian.
///
/// # Examples
///
/// ```
/// #![feature(float_to_from_bytes)]
/// let value = f64::from_le_bytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]);
/// assert_eq!(value, 12.5);
/// ```
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
#[inline]
pub fn from_le_bytes(bytes: [u8; 8]) -> Self {
Self::from_bits(u64::from_le_bytes(bytes))
}

/// Create a floating point value from its representation as a byte array in big endian.
///
/// As the target platform's native endianness is used, portable code
/// likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as
/// appropriate instead.
///
/// [`from_be_bytes`]: #method.from_be_bytes
/// [`from_le_bytes`]: #method.from_le_bytes
///
/// # Examples
///
/// ```
/// #![feature(float_to_from_bytes)]
/// let value = f64::from_ne_bytes(if cfg!(target_endian = "big") {
/// [0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
/// } else {
/// [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]
/// });
/// assert_eq!(value, 12.5);
/// ```
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
#[inline]
pub fn from_ne_bytes(bytes: [u8; 8]) -> Self {
Self::from_bits(u64::from_ne_bytes(bytes))
}
}

0 comments on commit 10840b8

Please sign in to comment.