From 211230daf334deccc8313693a5cbebc1532fa1a7 Mon Sep 17 00:00:00 2001
From: lilinus <linus.hamlin@outlook.com>
Date: Fri, 12 Apr 2024 13:21:08 +0200
Subject: [PATCH 1/3] Add some TODO #5213 comments for

---
 .../System.Private.CoreLib/src/System/DateTime.cs          | 3 +++
 .../System.Private.CoreLib/src/System/Decimal.DecCalc.cs   | 7 +++++++
 .../src/System/Numerics/BigIntegerCalculator.DivRem.cs     | 2 ++
 3 files changed, 12 insertions(+)

diff --git a/src/libraries/System.Private.CoreLib/src/System/DateTime.cs b/src/libraries/System.Private.CoreLib/src/System/DateTime.cs
index 3eeaaabbd358a4..3956fe73a88242 100644
--- a/src/libraries/System.Private.CoreLib/src/System/DateTime.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/DateTime.cs
@@ -1405,6 +1405,7 @@ internal void GetDate(out int year, out int month, out int day)
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         internal void GetTime(out int hour, out int minute, out int second)
         {
+            // TODO: https://github.com/dotnet/runtime/issues/5213
             ulong seconds = UTicks / TicksPerSecond;
             ulong minutes = seconds / 60;
             second = (int)(seconds - (minutes * 60));
@@ -1416,6 +1417,7 @@ internal void GetTime(out int hour, out int minute, out int second)
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         internal void GetTime(out int hour, out int minute, out int second, out int millisecond)
         {
+            // TODO: https://github.com/dotnet/runtime/issues/5213
             ulong milliseconds = UTicks / TicksPerMillisecond;
             ulong seconds = milliseconds / 1000;
             millisecond = (int)(milliseconds - (seconds * 1000));
@@ -1429,6 +1431,7 @@ internal void GetTime(out int hour, out int minute, out int second, out int mill
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         internal void GetTimePrecise(out int hour, out int minute, out int second, out int tick)
         {
+            // TODO: https://github.com/dotnet/runtime/issues/5213
             ulong ticks = UTicks;
             ulong seconds = ticks / TicksPerSecond;
             tick = (int)(ticks - (seconds * TicksPerSecond));
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 ca15b1df6ea407..d367fb66b09dc3 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Decimal.DecCalc.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Decimal.DecCalc.cs
@@ -221,6 +221,7 @@ private static uint Div96By32(ref Buf12 bufNum, uint den)
             private static bool Div96ByConst(ref ulong high64, ref uint low, uint pow)
             {
 #if TARGET_64BIT
+                // TODO: https://github.com/dotnet/runtime/issues/5213
                 ulong div64 = high64 / pow;
                 uint div = (uint)((((high64 - div64 * pow) << 32) + low) / pow);
                 if (low == div * pow)
@@ -675,6 +676,7 @@ private static unsafe uint DivByConst(uint* result, uint hiRes, out uint quotien
                 for (uint i = hiRes - 1; (int)i >= 0; i--)
                 {
 #if TARGET_64BIT
+                    // TODO: https://github.com/dotnet/runtime/issues/5213
                     ulong num = result[i] + ((ulong)remainder << 32);
                     remainder = (uint)num - (result[i] = (uint)(num / power)) * power;
 #else
@@ -710,6 +712,7 @@ private static int OverflowUnscale(ref Buf12 bufQuo, int scale, bool sticky)
                 Debug.Assert(bufQuo.U2 == 0);
 
                 // We have overflown, so load the high bit with a one.
+                // TODO: https://github.com/dotnet/runtime/issues/5213
                 const ulong highbit = 1UL << 32;
                 bufQuo.U2 = (uint)(highbit / 10);
                 ulong tmp = ((highbit % 10) << 32) + bufQuo.U1;
@@ -1090,6 +1093,7 @@ internal static unsafe void DecAddSub(ref DecCalc d1, ref DecCalc d2, bool sign)
                         Number.ThrowOverflowException(SR.Overflow_Decimal);
                     flags -= 1 << ScaleShift;
 
+                    // TODO: https://github.com/dotnet/runtime/issues/5213
                     const uint den = 10;
                     ulong num = high + (1UL << 32);
                     high = (uint)(num / den);
@@ -1776,6 +1780,7 @@ internal static void VarDecFromR8(double input, out DecCalc result)
                     if (lmax > 14)
                         lmax = 14;
 
+                    // TODO: https://github.com/dotnet/runtime/issues/5213
                     if ((byte)mant == 0 && lmax >= 8)
                     {
                         const uint den = 100000000;
@@ -2349,6 +2354,7 @@ internal static void InternalRound(ref DecCalc d, uint scale, MidpointRounding m
                 {
                     scale -= MaxInt32Scale;
 
+                    // TODO: https://github.com/dotnet/runtime/issues/5213
                     const uint divisor = TenToPowerNine;
                     uint n = d.uhi;
                     if (n == 0)
@@ -2463,6 +2469,7 @@ internal static uint DecDivMod1E9(ref DecCalc value)
                 value.uhi = (uint)(div64 >> 32);
                 value.umid = (uint)div64;
 
+                // TODO: https://github.com/dotnet/runtime/issues/5213
                 ulong num = ((high64 - (uint)div64 * TenToPowerNine) << 32) + value.ulo;
                 uint div = (uint)(num / TenToPowerNine);
                 value.ulo = div;
diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.DivRem.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.DivRem.cs
index bddeb75298f481..2d12846cf30718 100644
--- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.DivRem.cs
+++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.DivRem.cs
@@ -21,6 +21,7 @@ public static void Divide(ReadOnlySpan<uint> left, uint right, Span<uint> quotie
 
             for (int i = left.Length - 1; i >= 0; i--)
             {
+                // TODO: https://github.com/dotnet/runtime/issues/5213
                 ulong value = (carry << 32) | left[i];
                 ulong digit = value / right;
                 quotient[i] = (uint)digit;
@@ -39,6 +40,7 @@ public static void Divide(ReadOnlySpan<uint> left, uint right, Span<uint> quotie
             ulong carry = 0UL;
             for (int i = left.Length - 1; i >= 0; i--)
             {
+                // TODO: https://github.com/dotnet/runtime/issues/5213
                 ulong value = (carry << 32) | left[i];
                 ulong digit = value / right;
                 quotient[i] = (uint)digit;

From 5f1896b32d823d830b728c04c57c587bedfacc55 Mon Sep 17 00:00:00 2001
From: lilinus <linus.hamlin@outlook.com>
Date: Fri, 26 Apr 2024 10:07:17 +0200
Subject: [PATCH 2/3] Switch some TODOs to Math.DivRem

---
 .../src/System/DateTime.cs                    | 36 +++++++++----------
 .../Numerics/BigIntegerCalculator.DivRem.cs   |  4 +--
 2 files changed, 17 insertions(+), 23 deletions(-)

diff --git a/src/libraries/System.Private.CoreLib/src/System/DateTime.cs b/src/libraries/System.Private.CoreLib/src/System/DateTime.cs
index 3956fe73a88242..9970a9f1a7fa5f 100644
--- a/src/libraries/System.Private.CoreLib/src/System/DateTime.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/DateTime.cs
@@ -1405,40 +1405,36 @@ internal void GetDate(out int year, out int month, out int day)
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         internal void GetTime(out int hour, out int minute, out int second)
         {
-            // TODO: https://github.com/dotnet/runtime/issues/5213
             ulong seconds = UTicks / TicksPerSecond;
-            ulong minutes = seconds / 60;
-            second = (int)(seconds - (minutes * 60));
-            ulong hours = minutes / 60;
-            minute = (int)(minutes - (hours * 60));
+            (ulong minutes, ulong uSecond) = Math.DivRem(seconds, 60);
+            second = (int)uSecond;
+            (ulong hours, ulong uMinute) = Math.DivRem(minutes, 60);
+            minute = (int)uMinute;
             hour = (int)((uint)hours % 24);
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         internal void GetTime(out int hour, out int minute, out int second, out int millisecond)
         {
-            // TODO: https://github.com/dotnet/runtime/issues/5213
             ulong milliseconds = UTicks / TicksPerMillisecond;
-            ulong seconds = milliseconds / 1000;
-            millisecond = (int)(milliseconds - (seconds * 1000));
-            ulong minutes = seconds / 60;
-            second = (int)(seconds - (minutes * 60));
-            ulong hours = minutes / 60;
-            minute = (int)(minutes - (hours * 60));
+            (ulong seconds, ulong uMillisecond) = Math.DivRem(milliseconds, 1000);
+            millisecond = (int)uMillisecond;
+            (ulong minutes, ulong uSecond) = Math.DivRem(seconds, 60);
+            second = (int)uSecond;
+            (ulong hours, ulong uMinute) = Math.DivRem(minutes, 60);
+            minute = (int)uMinute;
             hour = (int)((uint)hours % 24);
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         internal void GetTimePrecise(out int hour, out int minute, out int second, out int tick)
         {
-            // TODO: https://github.com/dotnet/runtime/issues/5213
-            ulong ticks = UTicks;
-            ulong seconds = ticks / TicksPerSecond;
-            tick = (int)(ticks - (seconds * TicksPerSecond));
-            ulong minutes = seconds / 60;
-            second = (int)(seconds - (minutes * 60));
-            ulong hours = minutes / 60;
-            minute = (int)(minutes - (hours * 60));
+            (ulong seconds, ulong uTick) = Math.DivRem(UTicks, TicksPerSecond);
+            tick = (int)uTick;
+            (ulong minutes, ulong uSecond) = Math.DivRem(seconds, 60);
+            second = (int)uSecond;
+            (ulong hours, ulong uMinute) = Math.DivRem(minutes, 60);
+            minute = (int)uMinute;
             hour = (int)((uint)hours % 24);
         }
 
diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.DivRem.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.DivRem.cs
index 2d12846cf30718..e6c3fb1c1fa7c4 100644
--- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.DivRem.cs
+++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.DivRem.cs
@@ -21,11 +21,9 @@ public static void Divide(ReadOnlySpan<uint> left, uint right, Span<uint> quotie
 
             for (int i = left.Length - 1; i >= 0; i--)
             {
-                // TODO: https://github.com/dotnet/runtime/issues/5213
                 ulong value = (carry << 32) | left[i];
-                ulong digit = value / right;
+                (ulong digit, carry) = Math.DivRem(value, right);
                 quotient[i] = (uint)digit;
-                carry = value - digit * right;
             }
             remainder = (uint)carry;
         }

From 249cff3c29f2c1dae050b2646007c272adb32a5a Mon Sep 17 00:00:00 2001
From: lilinus <linus.hamlin@outlook.com>
Date: Fri, 26 Apr 2024 10:09:00 +0200
Subject: [PATCH 3/3] Missed one switch to DivRem

---
 .../src/System/Numerics/BigIntegerCalculator.DivRem.cs        | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.DivRem.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.DivRem.cs
index e6c3fb1c1fa7c4..1b45842a7d7ca8 100644
--- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.DivRem.cs
+++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.DivRem.cs
@@ -38,11 +38,9 @@ public static void Divide(ReadOnlySpan<uint> left, uint right, Span<uint> quotie
             ulong carry = 0UL;
             for (int i = left.Length - 1; i >= 0; i--)
             {
-                // TODO: https://github.com/dotnet/runtime/issues/5213
                 ulong value = (carry << 32) | left[i];
-                ulong digit = value / right;
+                (ulong digit, carry) = Math.DivRem(value, right);
                 quotient[i] = (uint)digit;
-                carry = value - digit * right;
             }
         }