Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ private static unsafe int IPv4AddressToStringHelper(uint address, char* addressS
{
int offset = 0;

FormatIPv4AddressNumber((int)(address & 0xFF), addressString, ref offset);
FormatIPv4AddressNumber((byte)address, addressString, ref offset);
addressString[offset++] = '.';
FormatIPv4AddressNumber((int)((address >> 8) & 0xFF), addressString, ref offset);
FormatIPv4AddressNumber((byte)(address >> 8), addressString, ref offset);
addressString[offset++] = '.';
FormatIPv4AddressNumber((int)((address >> 16) & 0xFF), addressString, ref offset);
FormatIPv4AddressNumber((byte)(address >> 16), addressString, ref offset);
addressString[offset++] = '.';
FormatIPv4AddressNumber((int)((address >> 24) & 0xFF), addressString, ref offset);
FormatIPv4AddressNumber((byte)(address >> 24), addressString, ref offset);

return offset;
}
Expand Down Expand Up @@ -153,17 +153,15 @@ internal static StringBuilder IPv6AddressToStringHelper(ushort[] address, uint s
return buffer;
}

private static unsafe void FormatIPv4AddressNumber(int number, char* addressString, ref int offset)
private static unsafe void FormatIPv4AddressNumber(byte number, char* addressString, ref int offset)
{
// Math.DivRem has no overload for byte, assert here for safety
Debug.Assert(number < 256);

offset += number > 99 ? 3 : number > 9 ? 2 : 1;

int i = offset;
do
{
number = Math.DivRem(number, 10, out int rem);
byte rem;
(number, rem) = Math.DivRem(number, (byte)10);
addressString[--i] = (char)('0' + rem);
} while (number != 0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ internal int Format(Span<char> destination)

if (precision >= 10)
{
uint div = Math.DivRem(precision, 10, out precision);
uint div;
(div, precision) = Math.DivRem(precision, 10);
destination[1] = (char)('0' + div % 10);
count = 2;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ private static bool TryFormatStandard(TimeSpan value, StandardFormat format, str
}
}

totalSecondsRemaining = Math.DivRem((ulong)ticks, TimeSpan.TicksPerSecond, out ulong fraction64);
ulong fraction64;
(totalSecondsRemaining, fraction64) = Math.DivRem((ulong)ticks, TimeSpan.TicksPerSecond);
fraction = (uint)fraction64;
}

Expand Down Expand Up @@ -170,15 +171,15 @@ private static bool TryFormatStandard(TimeSpan value, StandardFormat format, str
if (totalSecondsRemaining > 0)
{
// Only compute minutes if the TimeSpan has an absolute value of >= 1 minute.
totalMinutesRemaining = Math.DivRem(totalSecondsRemaining, 60 /* seconds per minute */, out seconds);
(totalMinutesRemaining, seconds) = Math.DivRem(totalSecondsRemaining, 60 /* seconds per minute */);
Debug.Assert(seconds < 60);
}

ulong totalHoursRemaining = 0, minutes = 0;
if (totalMinutesRemaining > 0)
{
// Only compute hours if the TimeSpan has an absolute value of >= 1 hour.
totalHoursRemaining = Math.DivRem(totalMinutesRemaining, 60 /* minutes per hour */, out minutes);
(totalHoursRemaining, minutes) = Math.DivRem(totalMinutesRemaining, 60 /* minutes per hour */);
Debug.Assert(minutes < 60);
}

Expand All @@ -189,7 +190,7 @@ private static bool TryFormatStandard(TimeSpan value, StandardFormat format, str
if (totalHoursRemaining > 0)
{
// Only compute days if the TimeSpan has an absolute value of >= 1 day.
days = Math.DivRem((uint)totalHoursRemaining, 24 /* hours per day */, out hours);
(days, hours) = Math.DivRem((uint)totalHoursRemaining, 24 /* hours per day */);
Debug.Assert(hours < 24);
}

Expand Down
67 changes: 59 additions & 8 deletions src/libraries/System.Private.CoreLib/src/System/Math.cs
Original file line number Diff line number Diff line change
Expand Up @@ -271,18 +271,69 @@ public static long DivRem(long a, long b, out long result)
return div;
}

internal static uint DivRem(uint a, uint b, out uint result)
[CLSCompliant(false)]
public static (sbyte Quotient, sbyte Remainder) DivRem(sbyte left, sbyte right)
{
uint div = a / b;
result = a - (div * b);
return div;
sbyte quotient = (sbyte)(left / right);
return (quotient, (sbyte)(left - (quotient * right)));
}

internal static ulong DivRem(ulong a, ulong b, out ulong result)
public static (byte Quotient, byte Remainder) DivRem(byte left, byte right)
{
ulong div = a / b;
result = a - (div * b);
return div;
byte quotient = (byte)(left / right);
return (quotient, (byte)(left - (quotient * right)));
}

public static (short Quotient, short Remainder) DivRem(short left, short right)
{
short quotient = (short)(left / right);
return (quotient, (short)(left - (quotient * right)));
}

[CLSCompliant(false)]
public static (ushort Quotient, ushort Remainder) DivRem(ushort left, ushort right)
{
ushort quotient = (ushort)(left / right);
return (quotient, (ushort)(left - (quotient * right)));
}

public static (int Quotient, int Remainder) DivRem(int left, int right)
{
int quotient = left / right;
return (quotient, left - (quotient * right));
}

[CLSCompliant(false)]
public static (uint Quotient, uint Remainder) DivRem(uint left, uint right)
{
uint quotient = left / right;
return (quotient, left - (quotient * right));
}

public static (long Quotient, long Remainder) DivRem(long left, long right)
{
long quotient = left / right;
return (quotient, left - (quotient * right));
}

[CLSCompliant(false)]
public static (ulong Quotient, ulong Remainder) DivRem(ulong left, ulong right)
{
ulong quotient = left / right;
return (quotient, left - (quotient * right));
}

public static (nint Quotient, nint Remainder) DivRem(nint left, nint right)
{
nint quotient = left / right;
return (quotient, left - (quotient * right));
}

[CLSCompliant(false)]
public static (nuint Quotient, nuint Remainder) DivRem(nuint left, nuint right)
{
nuint quotient = left / right;
return (quotient, left - (quotient * right));
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ public static void DivRem(ref BigInteger lhs, ref BigInteger rhs, out BigInteger

if ((lhsLength == 1) && (rhsLength == 1))
{
uint quotient = Math.DivRem(lhs._blocks[0], rhs._blocks[0], out uint remainder);
var (quotient, remainder) = Math.DivRem(lhs._blocks[0], rhs._blocks[0]);
SetUInt32(out quo, quotient);
SetUInt32(out rem, remainder);
return;
Expand All @@ -464,7 +464,8 @@ public static void DivRem(ref BigInteger lhs, ref BigInteger rhs, out BigInteger
for (int i = quoLength - 1; i >= 0; i--)
{
ulong value = (carry << 32) | lhs._blocks[i];
ulong digit = Math.DivRem(value, rhsValue, out carry);
ulong digit;
(digit, carry) = Math.DivRem(value, rhsValue);

if ((digit == 0) && (i == (quoLength - 1)))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1334,7 +1334,8 @@ private static unsafe void UInt32ToNumber(uint value, ref NumberBuffer number)
{
while (--digits >= 0 || value != 0)
{
value = Math.DivRem(value, 10, out uint remainder);
uint remainder;
(value, remainder) = Math.DivRem(value, 10);
*(--bufferEnd) = (byte)(remainder + '0');
}
return bufferEnd;
Expand All @@ -1344,7 +1345,8 @@ private static unsafe void UInt32ToNumber(uint value, ref NumberBuffer number)
{
while (--digits >= 0 || value != 0)
{
value = Math.DivRem(value, 10, out uint remainder);
uint remainder;
(value, remainder) = Math.DivRem(value, 10);
*(--bufferEnd) = (char)(remainder + '0');
}
return bufferEnd;
Expand All @@ -1367,7 +1369,8 @@ internal static unsafe string UInt32ToDecStr(uint value)
char* p = buffer + bufferLength;
do
{
value = Math.DivRem(value, 10, out uint remainder);
uint remainder;
(value, remainder) = Math.DivRem(value, 10);
*(--p) = (char)(remainder + '0');
}
while (value != 0);
Expand Down Expand Up @@ -1409,7 +1412,8 @@ private static unsafe bool TryUInt32ToDecStr(uint value, int digits, Span<char>
{
do
{
value = Math.DivRem(value, 10, out uint remainder);
uint remainder;
(value, remainder) = Math.DivRem(value, 10);
*(--p) = (char)(remainder + '0');
}
while (value != 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,8 @@ private static bool TryDigitGenCounted(in DiyFp w, int requestedDigits, Span<byt
// The divisor is the biggest power of ten that is smaller than integrals
while (kappa > 0)
{
uint digit = Math.DivRem(integrals, divisor, out integrals);
uint digit;
(digit, integrals) = Math.DivRem(integrals, divisor);
Debug.Assert(digit <= 9);
buffer[length] = (byte)('0' + digit);

Expand Down Expand Up @@ -802,7 +803,8 @@ private static bool TryDigitGenShortest(in DiyFp low, in DiyFp w, in DiyFp high,
// The divisor is the biggest power of ten that is smaller than integrals
while (kappa > 0)
{
uint digit = Math.DivRem(integrals, divisor, out integrals);
uint digit;
(digit, integrals) = Math.DivRem(integrals, divisor);
Debug.Assert(digit <= 9);
buffer[length] = (byte)('0' + digit);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ private static ulong ConvertBigIntegerToFloatingPointBits(ref BigInteger value,
return AssembleFloatingPointBits(in info, value.ToUInt64(), baseExponent, !hasNonZeroFractionalPart);
}

uint topBlockIndex = Math.DivRem(integerBitsOfPrecision, 32, out uint topBlockBits);
var (topBlockIndex, topBlockBits) = Math.DivRem(integerBitsOfPrecision, 32);
uint middleBlockIndex = topBlockIndex - 1;
uint bottomBlockIndex = middleBlockIndex - 1;

Expand Down
Loading