about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-07-08 08:39:56 +0000
committerbors <bors@rust-lang.org>2019-07-08 08:39:56 +0000
commit10840b8ae2182128f2e1c84b8aaf41452728de07 (patch)
tree1bcf36cef776e86f7210f273eaa7fc989362ff23
parentdb592f4627251cfd8571a05cf8e06a56be9470c2 (diff)
parentdf53a3fd55a233cc04ce20d448f64ec70b937b06 (diff)
downloadrust-10840b8ae2182128f2e1c84b8aaf41452728de07.tar.gz
rust-10840b8ae2182128f2e1c84b8aaf41452728de07.zip
Auto merge of #62366 - lzutao:feature/float-from-to-bytes, r=SimonSapin
Add float conversions to and from bytes

Rework of #58756. Address https://github.com/rust-lang/rust/pull/58756#issuecomment-488385889.

Fixes #57492.

r? @SimonSapin
-rw-r--r--src/libcore/num/f32.rs121
-rw-r--r--src/libcore/num/f64.rs121
2 files changed, 236 insertions, 6 deletions
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 0bcd371b528..fc2c431ca0f 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -450,10 +450,8 @@ 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]
@@ -461,4 +459,121 @@ impl f32 {
         // 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))
+    }
 }
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 4d4a2c9c5a9..6bd0b6e5c7f 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -463,10 +463,8 @@ 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]
@@ -474,4 +472,121 @@ impl f64 {
         // 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))
+    }
 }