From 105acbae1f96453aacae008222483b59ede7c952 Mon Sep 17 00:00:00 2001
From: Huo Yaoyuan <huoyaoyuan@hotmail.com>
Date: Sat, 24 Sep 2022 16:59:11 +0800
Subject: [PATCH 1/2] Use BigMul(ulong)

---
 .../src/System/Decimal.DecCalc.cs                 | 15 +--------------
 1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/src/libraries/System.Private.CoreLib/src/System/Decimal.DecCalc.cs b/src/libraries/System.Private.CoreLib/src/System/Decimal.DecCalc.cs
index 1a5834c08d42fb..22896526aa56e6 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Decimal.DecCalc.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Decimal.DecCalc.cs
@@ -181,20 +181,7 @@ private static ulong UInt32x32To64(uint a, uint b)
 
             private static void UInt64x64To128(ulong a, ulong b, ref DecCalc result)
             {
-                ulong low = UInt32x32To64((uint)a, (uint)b); // lo partial prod
-                ulong mid = UInt32x32To64((uint)a, (uint)(b >> 32)); // mid 1 partial prod
-                ulong high = UInt32x32To64((uint)(a >> 32), (uint)(b >> 32));
-                high += mid >> 32;
-                low += mid <<= 32;
-                if (low < mid)  // test for carry
-                    high++;
-
-                mid = UInt32x32To64((uint)(a >> 32), (uint)b);
-                high += mid >> 32;
-                low += mid <<= 32;
-                if (low < mid)  // test for carry
-                    high++;
-
+                ulong high = Math.BigMul(a, b, out ulong low);
                 if (high > uint.MaxValue)
                     Number.ThrowOverflowException(TypeCode.Decimal);
                 result.Low64 = low;

From 87b9021d3e11232e0edc0e387d6bcf096ecb249a Mon Sep 17 00:00:00 2001
From: Huo Yaoyuan <huoyaoyuan@hotmail.com>
Date: Sat, 24 Sep 2022 17:09:56 +0800
Subject: [PATCH 2/2] Use float.Exponent and double.Exponent

---
 .../src/System/Decimal.DecCalc.cs             | 29 ++-----------------
 1 file changed, 2 insertions(+), 27 deletions(-)

diff --git a/src/libraries/System.Private.CoreLib/src/System/Decimal.DecCalc.cs b/src/libraries/System.Private.CoreLib/src/System/Decimal.DecCalc.cs
index 22896526aa56e6..50e2ff562ea004 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Decimal.DecCalc.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Decimal.DecCalc.cs
@@ -151,29 +151,6 @@ private ulong Low64
 
 #region Decimal Math Helpers
 
-            private static unsafe uint GetExponent(float f)
-            {
-                // Based on pulling out the exp from this single struct layout
-                // typedef struct {
-                //    ULONG mant:23;
-                //    ULONG exp:8;
-                //    ULONG sign:1;
-                // } SNGSTRUCT;
-
-                return (byte)(*(uint*)&f >> 23);
-            }
-
-            private static unsafe uint GetExponent(double d)
-            {
-                // Based on pulling out the exp from this double struct layout
-                // typedef struct {
-                //   DWORDLONG mant:52;
-                //   DWORDLONG signexp:12;
-                // } DBLSTRUCT;
-
-                return (uint)(*(ulong*)&d >> 52) & 0x7FFu;
-            }
-
             private static ulong UInt32x32To64(uint a, uint b)
             {
                 return (ulong)a * (ulong)b;
@@ -1515,8 +1492,7 @@ internal static void VarDecFromR4(float input, out DecCalc result)
                 // than 2^93.  So a float with an exponent of -94 could just
                 // barely reach 0.5, but smaller exponents will always round to zero.
                 //
-                const uint SNGBIAS = 126;
-                int exp = (int)(GetExponent(input) - SNGBIAS);
+                int exp = input.Exponent + 1;
                 if (exp < -94)
                     return; // result should be zeroed out
 
@@ -1682,8 +1658,7 @@ internal static void VarDecFromR8(double input, out DecCalc result)
                 // than 2^93.  So a float with an exponent of -94 could just
                 // barely reach 0.5, but smaller exponents will always round to zero.
                 //
-                const uint DBLBIAS = 1022;
-                int exp = (int)(GetExponent(input) - DBLBIAS);
+                int exp = input.Exponent + 1;
                 if (exp < -94)
                     return; // result should be zeroed out
 
