Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Prev Previous commit
Next Next commit
Use UInt32ToDecChars
  • Loading branch information
huoyaoyuan committed Mar 23, 2024
commit cdbe4159d3afe2d168a204781f3933ac33bb4e5d
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,7 @@ internal static bool TryFormatBigInteger(BigInteger value, ReadOnlySpan<char> fo
sNegative?.CopyTo(destination);
fixed (char* ptr = &MemoryMarshal.GetReference(destination))
{
BigIntegerToDecChars(ptr + strLength, base1E9Value, digits);
BigIntegerToDecChars((Utf16Char*)ptr + strLength, base1E9Value, digits);
}
charsWritten = strLength;
spanSuccess = true;
Expand All @@ -970,7 +970,7 @@ internal static bool TryFormatBigInteger(BigInteger value, ReadOnlySpan<char> fo
state.sNegative?.CopyTo(span);
fixed (char* ptr = &MemoryMarshal.GetReference(span))
{
BigIntegerToDecChars(ptr + span.Length, new ReadOnlySpan<uint>((void*)state.ptr, state.Length), state.digits);
BigIntegerToDecChars((Utf16Char*)ptr + span.Length, new ReadOnlySpan<uint>((void*)state.ptr, state.Length), state.digits);
}
});
}
Expand All @@ -985,7 +985,7 @@ internal static bool TryFormatBigInteger(BigInteger value, ReadOnlySpan<char> fo
fixed (byte* ptr = numberBuffer) // NumberBuffer expects pinned Digits
{
scoped NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, ptr, valueDigits + 1);
BigIntegerToDecChars(ptr + valueDigits, base1E9Value, valueDigits);
BigIntegerToDecChars((Utf8Char*)ptr + valueDigits, base1E9Value, valueDigits);
number.Digits[^1] = 0;
number.DigitsCount = valueDigits;
number.Scale = valueDigits;
Expand Down Expand Up @@ -1031,33 +1031,19 @@ internal static bool TryFormatBigInteger(BigInteger value, ReadOnlySpan<char> fo
}

private static unsafe TChar* BigIntegerToDecChars<TChar>(TChar* bufferEnd, ReadOnlySpan<uint> base1E9Value, int digits)
where TChar : unmanaged, IBinaryInteger<TChar> // CoreLib uses IUtfChar<TChar>
where TChar : unmanaged, IUtfChar<TChar>
{
Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte));
Debug.Assert(base1E9Value[^1] != 0, "Leading zeros should be trimmed by caller.");

// The base 10^9 value is in reverse order
for (int i = 0; i < base1E9Value.Length - 1; i++)
{
// TODO: is it worthy to introduce optimized UInt32ToDecChars from CoreLib?
bufferEnd = UInt32ToDecChars(bufferEnd, base1E9Value[i], kcchBase);
digits -= kcchBase;
uint value = base1E9Value[i];
for (int j = 0; j < kcchBase; j++)
{
(value, uint digit) = Math.DivRem(value, 10);
*(--bufferEnd) = TChar.CreateTruncating('0' + digit);
}
}

Debug.Assert(digits >= FormattingHelpers.CountDigits(base1E9Value[^1]));
for (uint value = base1E9Value[^1]; value > 0 || digits > 0;)
{
digits--;
(value, uint digit) = Math.DivRem(value, 10);
*(--bufferEnd) = TChar.CreateTruncating('0' + digit);
}

return bufferEnd;
return UInt32ToDecChars(bufferEnd, base1E9Value[^1], digits);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,21 @@ internal readonly struct Utf16Char(char ch) : IUtfChar<Utf16Char>
public bool Equals(Utf16Char other) => value == other.value;
}

#pragma warning disable CA1067 // Polyfill only type
internal readonly struct Utf8Char(byte ch) : IUtfChar<Utf8Char>
#pragma warning restore CA1067
{
private readonly byte value = ch;

public static Utf8Char CastFrom(byte value) => new(value);
public static Utf8Char CastFrom(char value) => new((byte)value);
public static Utf8Char CastFrom(int value) => new((byte)value);
public static Utf8Char CastFrom(uint value) => new((byte)value);
public static Utf8Char CastFrom(ulong value) => new((byte)value);
public static uint CastToUInt32(Utf8Char value) => value.value;
public bool Equals(Utf8Char other) => value == other.value;
}

internal static partial class Number
{
internal static bool AllowHyphenDuringParsing(this NumberFormatInfo info)
Expand Down