Skip to content

Commit 10840b8

Browse files
committed
Auto merge of #62366 - lzutao:feature/float-from-to-bytes, r=SimonSapin
Add float conversions to and from bytes Rework of #58756. Address #58756 (comment). Fixes #57492. r? @SimonSapin
2 parents db592f4 + df53a3f commit 10840b8

File tree

2 files changed

+236
-6
lines changed

2 files changed

+236
-6
lines changed

src/libcore/num/f32.rs

+118-3
Original file line numberDiff line numberDiff line change
@@ -450,15 +450,130 @@ impl f32 {
450450
/// # Examples
451451
///
452452
/// ```
453-
/// use std::f32;
454453
/// let v = f32::from_bits(0x41480000);
455-
/// let difference = (v - 12.5).abs();
456-
/// assert!(difference <= 1e-5);
454+
/// assert_eq!(v, 12.5);
457455
/// ```
458456
#[stable(feature = "float_bits_conv", since = "1.20.0")]
459457
#[inline]
460458
pub fn from_bits(v: u32) -> Self {
461459
// It turns out the safety issues with sNaN were overblown! Hooray!
462460
unsafe { mem::transmute(v) }
463461
}
462+
463+
/// Return the memory representation of this floating point number as a byte array in
464+
/// big-endian (network) byte order.
465+
///
466+
/// # Examples
467+
///
468+
/// ```
469+
/// #![feature(float_to_from_bytes)]
470+
/// let bytes = 12.5f32.to_be_bytes();
471+
/// assert_eq!(bytes, [0x41, 0x48, 0x00, 0x00]);
472+
/// ```
473+
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
474+
#[inline]
475+
pub fn to_be_bytes(self) -> [u8; 4] {
476+
self.to_bits().to_be_bytes()
477+
}
478+
479+
/// Return the memory representation of this floating point number as a byte array in
480+
/// little-endian byte order.
481+
///
482+
/// # Examples
483+
///
484+
/// ```
485+
/// #![feature(float_to_from_bytes)]
486+
/// let bytes = 12.5f32.to_le_bytes();
487+
/// assert_eq!(bytes, [0x00, 0x00, 0x48, 0x41]);
488+
/// ```
489+
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
490+
#[inline]
491+
pub fn to_le_bytes(self) -> [u8; 4] {
492+
self.to_bits().to_le_bytes()
493+
}
494+
495+
/// Return the memory representation of this floating point number as a byte array in
496+
/// native byte order.
497+
///
498+
/// As the target platform's native endianness is used, portable code
499+
/// should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, instead.
500+
///
501+
/// [`to_be_bytes`]: #method.to_be_bytes
502+
/// [`to_le_bytes`]: #method.to_le_bytes
503+
///
504+
/// # Examples
505+
///
506+
/// ```
507+
/// #![feature(float_to_from_bytes)]
508+
/// let bytes = 12.5f32.to_ne_bytes();
509+
/// assert_eq!(
510+
/// bytes,
511+
/// if cfg!(target_endian = "big") {
512+
/// [0x41, 0x48, 0x00, 0x00]
513+
/// } else {
514+
/// [0x00, 0x00, 0x48, 0x41]
515+
/// }
516+
/// );
517+
/// ```
518+
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
519+
#[inline]
520+
pub fn to_ne_bytes(self) -> [u8; 4] {
521+
self.to_bits().to_ne_bytes()
522+
}
523+
524+
/// Create a floating point value from its representation as a byte array in big endian.
525+
///
526+
/// # Examples
527+
///
528+
/// ```
529+
/// #![feature(float_to_from_bytes)]
530+
/// let value = f32::from_be_bytes([0x41, 0x48, 0x00, 0x00]);
531+
/// assert_eq!(value, 12.5);
532+
/// ```
533+
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
534+
#[inline]
535+
pub fn from_be_bytes(bytes: [u8; 4]) -> Self {
536+
Self::from_bits(u32::from_be_bytes(bytes))
537+
}
538+
539+
/// Create a floating point value from its representation as a byte array in big endian.
540+
///
541+
/// # Examples
542+
///
543+
/// ```
544+
/// #![feature(float_to_from_bytes)]
545+
/// let value = f32::from_le_bytes([0x00, 0x00, 0x48, 0x41]);
546+
/// assert_eq!(value, 12.5);
547+
/// ```
548+
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
549+
#[inline]
550+
pub fn from_le_bytes(bytes: [u8; 4]) -> Self {
551+
Self::from_bits(u32::from_le_bytes(bytes))
552+
}
553+
554+
/// Create a floating point value from its representation as a byte array in big endian.
555+
///
556+
/// As the target platform's native endianness is used, portable code
557+
/// likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as
558+
/// appropriate instead.
559+
///
560+
/// [`from_be_bytes`]: #method.from_be_bytes
561+
/// [`from_le_bytes`]: #method.from_le_bytes
562+
///
563+
/// # Examples
564+
///
565+
/// ```
566+
/// #![feature(float_to_from_bytes)]
567+
/// let value = f32::from_ne_bytes(if cfg!(target_endian = "big") {
568+
/// [0x41, 0x48, 0x00, 0x00]
569+
/// } else {
570+
/// [0x00, 0x00, 0x48, 0x41]
571+
/// });
572+
/// assert_eq!(value, 12.5);
573+
/// ```
574+
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
575+
#[inline]
576+
pub fn from_ne_bytes(bytes: [u8; 4]) -> Self {
577+
Self::from_bits(u32::from_ne_bytes(bytes))
578+
}
464579
}

src/libcore/num/f64.rs

+118-3
Original file line numberDiff line numberDiff line change
@@ -463,15 +463,130 @@ impl f64 {
463463
/// # Examples
464464
///
465465
/// ```
466-
/// use std::f64;
467466
/// let v = f64::from_bits(0x4029000000000000);
468-
/// let difference = (v - 12.5).abs();
469-
/// assert!(difference <= 1e-5);
467+
/// assert_eq!(v, 12.5);
470468
/// ```
471469
#[stable(feature = "float_bits_conv", since = "1.20.0")]
472470
#[inline]
473471
pub fn from_bits(v: u64) -> Self {
474472
// It turns out the safety issues with sNaN were overblown! Hooray!
475473
unsafe { mem::transmute(v) }
476474
}
475+
476+
/// Return the memory representation of this floating point number as a byte array in
477+
/// big-endian (network) byte order.
478+
///
479+
/// # Examples
480+
///
481+
/// ```
482+
/// #![feature(float_to_from_bytes)]
483+
/// let bytes = 12.5f64.to_be_bytes();
484+
/// assert_eq!(bytes, [0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
485+
/// ```
486+
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
487+
#[inline]
488+
pub fn to_be_bytes(self) -> [u8; 8] {
489+
self.to_bits().to_be_bytes()
490+
}
491+
492+
/// Return the memory representation of this floating point number as a byte array in
493+
/// little-endian byte order.
494+
///
495+
/// # Examples
496+
///
497+
/// ```
498+
/// #![feature(float_to_from_bytes)]
499+
/// let bytes = 12.5f64.to_le_bytes();
500+
/// assert_eq!(bytes, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]);
501+
/// ```
502+
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
503+
#[inline]
504+
pub fn to_le_bytes(self) -> [u8; 8] {
505+
self.to_bits().to_le_bytes()
506+
}
507+
508+
/// Return the memory representation of this floating point number as a byte array in
509+
/// native byte order.
510+
///
511+
/// As the target platform's native endianness is used, portable code
512+
/// should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, instead.
513+
///
514+
/// [`to_be_bytes`]: #method.to_be_bytes
515+
/// [`to_le_bytes`]: #method.to_le_bytes
516+
///
517+
/// # Examples
518+
///
519+
/// ```
520+
/// #![feature(float_to_from_bytes)]
521+
/// let bytes = 12.5f64.to_ne_bytes();
522+
/// assert_eq!(
523+
/// bytes,
524+
/// if cfg!(target_endian = "big") {
525+
/// [0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
526+
/// } else {
527+
/// [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]
528+
/// }
529+
/// );
530+
/// ```
531+
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
532+
#[inline]
533+
pub fn to_ne_bytes(self) -> [u8; 8] {
534+
self.to_bits().to_ne_bytes()
535+
}
536+
537+
/// Create a floating point value from its representation as a byte array in big endian.
538+
///
539+
/// # Examples
540+
///
541+
/// ```
542+
/// #![feature(float_to_from_bytes)]
543+
/// let value = f64::from_be_bytes([0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
544+
/// assert_eq!(value, 12.5);
545+
/// ```
546+
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
547+
#[inline]
548+
pub fn from_be_bytes(bytes: [u8; 8]) -> Self {
549+
Self::from_bits(u64::from_be_bytes(bytes))
550+
}
551+
552+
/// Create a floating point value from its representation as a byte array in big endian.
553+
///
554+
/// # Examples
555+
///
556+
/// ```
557+
/// #![feature(float_to_from_bytes)]
558+
/// let value = f64::from_le_bytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]);
559+
/// assert_eq!(value, 12.5);
560+
/// ```
561+
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
562+
#[inline]
563+
pub fn from_le_bytes(bytes: [u8; 8]) -> Self {
564+
Self::from_bits(u64::from_le_bytes(bytes))
565+
}
566+
567+
/// Create a floating point value from its representation as a byte array in big endian.
568+
///
569+
/// As the target platform's native endianness is used, portable code
570+
/// likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as
571+
/// appropriate instead.
572+
///
573+
/// [`from_be_bytes`]: #method.from_be_bytes
574+
/// [`from_le_bytes`]: #method.from_le_bytes
575+
///
576+
/// # Examples
577+
///
578+
/// ```
579+
/// #![feature(float_to_from_bytes)]
580+
/// let value = f64::from_ne_bytes(if cfg!(target_endian = "big") {
581+
/// [0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
582+
/// } else {
583+
/// [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]
584+
/// });
585+
/// assert_eq!(value, 12.5);
586+
/// ```
587+
#[unstable(feature = "float_to_from_bytes", issue = "60446")]
588+
#[inline]
589+
pub fn from_ne_bytes(bytes: [u8; 8]) -> Self {
590+
Self::from_bits(u64::from_ne_bytes(bytes))
591+
}
477592
}

0 commit comments

Comments
 (0)