From 8d4addf5fdee79a7efba356f46f9eebd207e41bf Mon Sep 17 00:00:00 2001
From: xtqqczze <45661989+xtqqczze@users.noreply.github.com>
Date: Mon, 23 Dec 2024 11:27:28 +0000
Subject: [PATCH] Refactor `double` Read/Write implementations
---
.../Binary/BinaryPrimitives.ReadBigEndian.cs | 21 +----
.../BinaryPrimitives.ReadLittleEndian.cs | 21 +----
.../Binary/BinaryPrimitives.WriteBigEndian.cs | 26 +----
.../BinaryPrimitives.WriteLittleEndian.cs | 26 +----
.../src/System/Double.cs | 94 +++++++++++++++++++
5 files changed, 102 insertions(+), 86 deletions(-)
diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.ReadBigEndian.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.ReadBigEndian.cs
index 4065daf862150..eb92db4477b41 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.ReadBigEndian.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.ReadBigEndian.cs
@@ -17,13 +17,7 @@ public static partial class BinaryPrimitives
///
/// is too small to contain a .
///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double ReadDoubleBigEndian(ReadOnlySpan source)
- {
- return BitConverter.IsLittleEndian ?
- BitConverter.Int64BitsToDouble(ReverseEndianness(MemoryMarshal.Read(source))) :
- MemoryMarshal.Read(source);
- }
+ public static double ReadDoubleBigEndian(ReadOnlySpan source) => double.ReadBigEndian(source);
///
/// Reads a from the beginning of a read-only span of bytes, as big endian.
@@ -243,18 +237,7 @@ public static nuint ReadUIntPtrBigEndian(ReadOnlySpan source)
/// if the span is large enough to contain a ; otherwise, .
///
/// Reads exactly 8 bytes from the beginning of the span.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool TryReadDoubleBigEndian(ReadOnlySpan source, out double value)
- {
- if (BitConverter.IsLittleEndian)
- {
- bool success = MemoryMarshal.TryRead(source, out long tmp);
- value = BitConverter.Int64BitsToDouble(ReverseEndianness(tmp));
- return success;
- }
-
- return MemoryMarshal.TryRead(source, out value);
- }
+ public static bool TryReadDoubleBigEndian(ReadOnlySpan source, out double value) => double.TryReadBigEndian(out value, source);
///
/// Reads a from the beginning of a read-only span of bytes, as big endian.
diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.ReadLittleEndian.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.ReadLittleEndian.cs
index c21624da2aafc..a12a89b3ea862 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.ReadLittleEndian.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.ReadLittleEndian.cs
@@ -17,13 +17,7 @@ public static partial class BinaryPrimitives
///
/// is too small to contain a .
///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double ReadDoubleLittleEndian(ReadOnlySpan source)
- {
- return !BitConverter.IsLittleEndian ?
- BitConverter.Int64BitsToDouble(ReverseEndianness(MemoryMarshal.Read(source))) :
- MemoryMarshal.Read(source);
- }
+ public static double ReadDoubleLittleEndian(ReadOnlySpan source) => double.ReadLittleEndian(source);
///
/// Reads a from the beginning of a read-only span of bytes, as little endian.
@@ -243,18 +237,7 @@ public static nuint ReadUIntPtrLittleEndian(ReadOnlySpan source)
/// if the span is large enough to contain a ; otherwise, .
///
/// Reads exactly 8 bytes from the beginning of the span.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool TryReadDoubleLittleEndian(ReadOnlySpan source, out double value)
- {
- if (!BitConverter.IsLittleEndian)
- {
- bool success = MemoryMarshal.TryRead(source, out long tmp);
- value = BitConverter.Int64BitsToDouble(ReverseEndianness(tmp));
- return success;
- }
-
- return MemoryMarshal.TryRead(source, out value);
- }
+ public static bool TryReadDoubleLittleEndian(ReadOnlySpan source, out double value) => double.TryReadLittleEndian(out value, source);
///
/// Reads a from the beginning of a read-only span of bytes, as little endian.
diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteBigEndian.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteBigEndian.cs
index 159ade3dbdf6f..e091a2a27ba8e 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteBigEndian.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteBigEndian.cs
@@ -17,19 +17,7 @@ public static partial class BinaryPrimitives
///
/// is too small to contain a .
///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void WriteDoubleBigEndian(Span destination, double value)
- {
- if (BitConverter.IsLittleEndian)
- {
- long tmp = ReverseEndianness(BitConverter.DoubleToInt64Bits(value));
- MemoryMarshal.Write(destination, in tmp);
- }
- else
- {
- MemoryMarshal.Write(destination, in value);
- }
- }
+ public static void WriteDoubleBigEndian(Span destination, double value) => double.WriteBigEndian(in value, destination);
///
/// Writes a into a span of bytes, as big endian.
@@ -321,17 +309,7 @@ public static void WriteUIntPtrBigEndian(Span destination, nuint value)
/// if the span is large enough to contain a ; otherwise, .
///
/// Writes exactly 8 bytes to the beginning of the span.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool TryWriteDoubleBigEndian(Span destination, double value)
- {
- if (BitConverter.IsLittleEndian)
- {
- long tmp = ReverseEndianness(BitConverter.DoubleToInt64Bits(value));
- return MemoryMarshal.TryWrite(destination, in tmp);
- }
-
- return MemoryMarshal.TryWrite(destination, in value);
- }
+ public static bool TryWriteDoubleBigEndian(Span destination, double value) => double.TryWriteBigEndian(in value, destination);
///
/// Writes a into a span of bytes, as big endian.
diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteLittleEndian.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteLittleEndian.cs
index 5da64da58368a..0c207c0a47d21 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteLittleEndian.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Binary/BinaryPrimitives.WriteLittleEndian.cs
@@ -17,19 +17,7 @@ public static partial class BinaryPrimitives
///
/// is too small to contain a .
///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void WriteDoubleLittleEndian(Span destination, double value)
- {
- if (!BitConverter.IsLittleEndian)
- {
- long tmp = ReverseEndianness(BitConverter.DoubleToInt64Bits(value));
- MemoryMarshal.Write(destination, in tmp);
- }
- else
- {
- MemoryMarshal.Write(destination, in value);
- }
- }
+ public static void WriteDoubleLittleEndian(Span destination, double value) => value.WriteLittleEndian(in value, destination);
///
/// Writes a into a span of bytes, as little endian.
@@ -321,17 +309,7 @@ public static void WriteUIntPtrLittleEndian(Span destination, nuint value)
/// if the span is large enough to contain a ; otherwise, .
///
/// Writes exactly 8 bytes to the beginning of the span.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool TryWriteDoubleLittleEndian(Span destination, double value)
- {
- if (!BitConverter.IsLittleEndian)
- {
- long tmp = ReverseEndianness(BitConverter.DoubleToInt64Bits(value));
- return MemoryMarshal.TryWrite(destination, in tmp);
- }
-
- return MemoryMarshal.TryWrite(destination, in value);
- }
+ public static bool TryWriteDoubleLittleEndian(Span destination, double value) => double.TryWriteLittleEndian(in value, destination);
///
/// Writes a into a span of bytes, as little endian.
diff --git a/src/libraries/System.Private.CoreLib/src/System/Double.cs b/src/libraries/System.Private.CoreLib/src/System/Double.cs
index d38c67b916b18..1887c16b8b443 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Double.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Double.cs
@@ -152,6 +152,100 @@ internal ulong TrailingSignificand
}
}
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static double ReadBigEndian(ReadOnlySpan source)
+ {
+ return BitConverter.IsLittleEndian ?
+ BitConverter.Int64BitsToDouble(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read(source))) :
+ MemoryMarshal.Read(source);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static double ReadLittleEndian(ReadOnlySpan source)
+ {
+ return !BitConverter.IsLittleEndian ?
+ BitConverter.Int64BitsToDouble(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read(source))) :
+ MemoryMarshal.Read(source);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static bool TryReadBigEndian(out double value, ReadOnlySpan source)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ bool success = MemoryMarshal.TryRead(source, out long tmp);
+ value = BitConverter.Int64BitsToDouble(BinaryPrimitives.ReverseEndianness(tmp));
+ return success;
+ }
+
+ return MemoryMarshal.TryRead(source, out value);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static bool TryWriteBigEndian(in double value, Span destination)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ long tmp = BinaryPrimitives.ReverseEndianness(BitConverter.DoubleToInt64Bits(value));
+ return MemoryMarshal.TryWrite(destination, in tmp);
+ }
+
+ return MemoryMarshal.TryWrite(destination, in value);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static bool TryReadLittleEndian(out double value, ReadOnlySpan source)
+ {
+ if (!BitConverter.IsLittleEndian)
+ {
+ bool success = MemoryMarshal.TryRead(source, out long tmp);
+ value = BitConverter.Int64BitsToDouble(BinaryPrimitives.ReverseEndianness(tmp));
+ return success;
+ }
+
+ return MemoryMarshal.TryRead(source, out value);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static bool TryWriteLittleEndian(in double value, Span destination)
+ {
+ if (!BitConverter.IsLittleEndian)
+ {
+ long tmp = BinaryPrimitives.ReverseEndianness(BitConverter.DoubleToInt64Bits(value));
+ return MemoryMarshal.TryWrite(destination, in tmp);
+ }
+
+ return MemoryMarshal.TryWrite(destination, in value);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static void WriteBigEndian(in double value, Span destination)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ long tmp = BinaryPrimitives.ReverseEndianness(BitConverter.DoubleToInt64Bits(value));
+ MemoryMarshal.Write(destination, in tmp);
+ }
+ else
+ {
+ MemoryMarshal.Write(destination, in value);
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal void WriteLittleEndian(Span destination)
+ {
+ if (!BitConverter.IsLittleEndian)
+ {
+ long tmp = BinaryPrimitives.ReverseEndianness(BitConverter.DoubleToInt64Bits(m_value));
+ MemoryMarshal.Write(destination, in tmp);
+ }
+ else
+ {
+ MemoryMarshal.Write(destination, in m_value);
+ }
+ }
+
internal static ushort ExtractBiasedExponentFromBits(ulong bits)
{
return (ushort)((bits >> BiasedExponentShift) & ShiftedExponentMask);