Skip to content

Commit

Permalink
Use BigMul in BigMul (#100918)
Browse files Browse the repository at this point in the history
* Use BigMul in BigMul

* Reverse usage of BigMul(uint, uint)

* Add aggressive inline to Math.BigMul(ulong, ulong)
  • Loading branch information
lilinus committed Jun 13, 2024
1 parent b4f750f commit f453865
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 9 deletions.
13 changes: 12 additions & 1 deletion src/libraries/System.Private.CoreLib/src/System/Math.cs
Original file line number Diff line number Diff line change
Expand Up @@ -238,13 +238,24 @@ public static long BigMul(long a, long b, out long low)
return (long)high - ((a >> 63) & b) - ((b >> 63) & a);
}

/// <summary>Produces the full product of two unsigned 64-bit numbers.</summary>
/// <param name="a">The first number to multiply.</param>
/// <param name="b">The second number to multiply.</param>
/// <returns>The full product of the specified numbers.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static UInt128 BigMul(ulong a, ulong b)
{
ulong high = BigMul(a, b, out ulong low);
return new UInt128(high, low);
}

/// <summary>Produces the full product of two 64-bit numbers.</summary>
/// <param name="a">The first number to multiply.</param>
/// <param name="b">The second number to multiply.</param>
/// <returns>The full product of the specified numbers.</returns>
internal static Int128 BigMul(long a, long b)
{
long high = Math.BigMul(a, b, out long low);
long high = BigMul(a, b, out long low);
return new Int128((ulong)high, (ulong)low);
}

Expand Down
16 changes: 8 additions & 8 deletions src/libraries/System.Private.CoreLib/src/System/UInt128.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1396,18 +1396,18 @@ internal static UInt128 BigMul(UInt128 left, UInt128 right, out UInt128 lower)
// Basically, it's an optimized version of FOIL method applied to
// low and high qwords of each operand

UInt128 al = left._lower;
UInt128 ah = left._upper;
ulong al = left._lower;
ulong ah = left._upper;

UInt128 bl = right._lower;
UInt128 bh = right._upper;
ulong bl = right._lower;
ulong bh = right._upper;

UInt128 mull = al * bl;
UInt128 t = ah * bl + mull._upper;
UInt128 tl = al * bh + t._lower;
UInt128 mull = Math.BigMul(al, bl);
UInt128 t = Math.BigMul(ah, bl) + mull._upper;
UInt128 tl = Math.BigMul(al, bh) + t._lower;

lower = new UInt128(tl._lower, mull._lower);
return ah * bh + t._upper + tl._upper;
return Math.BigMul(ah, bh) + t._upper + tl._upper;
}

//
Expand Down

0 comments on commit f453865

Please sign in to comment.