diff --git a/src/libraries/Common/src/System/Number.Formatting.Common.cs b/src/libraries/Common/src/System/Number.Formatting.Common.cs index 37734e001ad949..e33d842dbc81d5 100644 --- a/src/libraries/Common/src/System/Number.Formatting.Common.cs +++ b/src/libraries/Common/src/System/Number.Formatting.Common.cs @@ -12,7 +12,7 @@ namespace System { internal static partial class Number { - private const int CharStackBufferSize = 32; + internal const int CharStackBufferSize = 32; private const int DefaultPrecisionExponentialFormat = 6; @@ -950,7 +950,11 @@ private static unsafe void FormatExponent(ref ValueListBuilder vlb } TChar* digits = stackalloc TChar[MaxUInt32DecDigits]; +#if !SYSTEM_PRIVATE_CORELIB TChar* p = UInt32ToDecChars(digits + MaxUInt32DecDigits, (uint)value, minDigits); +#else + TChar* p = NumberFormat.UInt32ToDecChars(digits + MaxUInt32DecDigits, (uint)value, minDigits); +#endif vlb.Append(new ReadOnlySpan(p, (int)(digits + MaxUInt32DecDigits - p))); } diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index d3b69efe615e4f..48429754f352fc 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -603,6 +603,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.cs index 80da6024050824..cafa83ba3f5167 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.cs @@ -135,16 +135,16 @@ public static bool TryFormat(uint value, Span destination, out int bytesWr { if (format.IsDefault) { - return Number.TryUInt32ToDecStr(value, destination, out bytesWritten); + return NumberFormat.TryUInt32ToDecStr(value, destination, out bytesWritten); } switch (format.Symbol | 0x20) { case 'd': - return Number.TryUInt32ToDecStr(value, format.PrecisionOrZero, destination, out bytesWritten); + return NumberFormat.TryUInt32ToDecStr(value, format.PrecisionOrZero, destination, out bytesWritten); case 'x': - return Number.TryInt32ToHexStr((int)value, Number.GetHexBase(format.Symbol), format.PrecisionOrZero, destination, out bytesWritten); + return NumberFormat.TryInt32ToHexStr((int)value, Number.GetHexBase(format.Symbol), format.PrecisionOrZero, destination, out bytesWritten); case 'n': return FormattingHelpers.TryFormat(value, destination, out bytesWritten, format); @@ -192,19 +192,19 @@ private static bool TryFormat(int value, int hexMask, Span destination, ou if (format.IsDefault) { return value >= 0 ? - Number.TryUInt32ToDecStr((uint)value, destination, out bytesWritten) : - Number.TryNegativeInt32ToDecStr(value, format.PrecisionOrZero, "-"u8, destination, out bytesWritten); + NumberFormat.TryUInt32ToDecStr((uint)value, destination, out bytesWritten) : + NumberFormat.TryNegativeInt32ToDecStr(value, format.PrecisionOrZero, "-"u8, destination, out bytesWritten); } switch (format.Symbol | 0x20) { case 'd': return value >= 0 ? - Number.TryUInt32ToDecStr((uint)value, format.PrecisionOrZero, destination, out bytesWritten) : - Number.TryNegativeInt32ToDecStr(value, format.PrecisionOrZero, "-"u8, destination, out bytesWritten); + NumberFormat.TryUInt32ToDecStr((uint)value, format.PrecisionOrZero, destination, out bytesWritten) : + NumberFormat.TryNegativeInt32ToDecStr(value, format.PrecisionOrZero, "-"u8, destination, out bytesWritten); case 'x': - return Number.TryInt32ToHexStr(value & hexMask, Number.GetHexBase(format.Symbol), format.PrecisionOrZero, destination, out bytesWritten); + return NumberFormat.TryInt32ToHexStr(value & hexMask, Number.GetHexBase(format.Symbol), format.PrecisionOrZero, destination, out bytesWritten); case 'n': return FormattingHelpers.TryFormat(value, destination, out bytesWritten, format); @@ -249,16 +249,16 @@ public static bool TryFormat(ulong value, Span destination, out int bytesW { if (format.IsDefault) { - return Number.TryUInt64ToDecStr(value, destination, out bytesWritten); + return NumberFormat.TryUInt64ToDecStr(value, destination, out bytesWritten); } switch (format.Symbol | 0x20) { case 'd': - return Number.TryUInt64ToDecStr(value, format.PrecisionOrZero, destination, out bytesWritten); + return NumberFormat.TryUInt64ToDecStr(value, format.PrecisionOrZero, destination, out bytesWritten); case 'x': - return Number.TryInt64ToHexStr((long)value, Number.GetHexBase(format.Symbol), format.PrecisionOrZero, destination, out bytesWritten); + return NumberFormat.TryInt64ToHexStr((long)value, Number.GetHexBase(format.Symbol), format.PrecisionOrZero, destination, out bytesWritten); case 'n': return FormattingHelpers.TryFormat(value, destination, out bytesWritten, format); @@ -303,19 +303,19 @@ public static bool TryFormat(long value, Span destination, out int bytesWr if (format.IsDefault) { return value >= 0 ? - Number.TryUInt64ToDecStr((ulong)value, destination, out bytesWritten) : - Number.TryNegativeInt64ToDecStr(value, format.PrecisionOrZero, "-"u8, destination, out bytesWritten); + NumberFormat.TryUInt64ToDecStr((ulong)value, destination, out bytesWritten) : + NumberFormat.TryNegativeInt64ToDecStr(value, format.PrecisionOrZero, "-"u8, destination, out bytesWritten); } switch (format.Symbol | 0x20) { case 'd': return value >= 0 ? - Number.TryUInt64ToDecStr((ulong)value, format.PrecisionOrZero, destination, out bytesWritten) : - Number.TryNegativeInt64ToDecStr(value, format.PrecisionOrZero, "-"u8, destination, out bytesWritten); + NumberFormat.TryUInt64ToDecStr((ulong)value, format.PrecisionOrZero, destination, out bytesWritten) : + NumberFormat.TryNegativeInt64ToDecStr(value, format.PrecisionOrZero, "-"u8, destination, out bytesWritten); case 'x': - return Number.TryInt64ToHexStr(value, Number.GetHexBase(format.Symbol), format.PrecisionOrZero, destination, out bytesWritten); + return NumberFormat.TryInt64ToHexStr(value, Number.GetHexBase(format.Symbol), format.PrecisionOrZero, destination, out bytesWritten); case 'n': return FormattingHelpers.TryFormat(value, destination, out bytesWritten, format); diff --git a/src/libraries/System.Private.CoreLib/src/System/Byte.cs b/src/libraries/System.Private.CoreLib/src/System/Byte.cs index 1c933aaaced78b..64fa425a6bb2c7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Byte.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Byte.cs @@ -161,13 +161,13 @@ public string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] strin public bool TryFormat(Span destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatUInt32(m_value, format, provider, destination, out charsWritten); + return NumberFormat.TryFormatUInt32(m_value, format, provider, destination, out charsWritten); } /// public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatUInt32(m_value, format, provider, utf8Destination, out bytesWritten); + return NumberFormat.TryFormatUInt32(m_value, format, provider, utf8Destination, out bytesWritten); } // diff --git a/src/libraries/System.Private.CoreLib/src/System/Decimal.cs b/src/libraries/System.Private.CoreLib/src/System/Decimal.cs index 4ae829ca83e174..0e08a5afa9885f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Decimal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Decimal.cs @@ -501,13 +501,13 @@ public string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] strin public bool TryFormat(Span destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatDecimal(this, format, NumberFormatInfo.GetInstance(provider), destination, out charsWritten); + return NumberFormat.TryFormatDecimal(this, format, NumberFormatInfo.GetInstance(provider), destination, out charsWritten); } /// public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatDecimal(this, format, NumberFormatInfo.GetInstance(provider), utf8Destination, out bytesWritten); + return NumberFormat.TryFormatDecimal(this, format, NumberFormatInfo.GetInstance(provider), utf8Destination, out bytesWritten); } // Converts a string to a Decimal. The string must consist of an optional diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormat.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormat.cs index bb7952affe4b73..7b2906dffe9d9c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormat.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormat.cs @@ -175,20 +175,20 @@ internal static unsafe void FormatDigits(ref ValueListBuilder outp case 2 when value < 100: fixed (TChar* ptr = &MemoryMarshal.GetReference(outputBuffer.AppendSpan(2))) { - Number.WriteTwoDigits((uint)value, ptr); + NumberFormat.WriteTwoDigits((uint)value, ptr); } break; case 4 when value < 10000: fixed (TChar* ptr = &MemoryMarshal.GetReference(outputBuffer.AppendSpan(4))) { - Number.WriteFourDigits((uint)value, ptr); + NumberFormat.WriteFourDigits((uint)value, ptr); } break; default: TChar* buffer = stackalloc TChar[16]; - TChar* p = Number.UInt32ToDecChars(buffer + 16, (uint)value, minimumLength); + TChar* p = NumberFormat.UInt32ToDecChars(buffer + 16, (uint)value, minimumLength); outputBuffer.Append(new ReadOnlySpan(p, (int)(buffer + 16 - p))); break; } @@ -833,7 +833,7 @@ private static unsafe void FormatCustomizedTimeZone(DateTime dateTime, Ti // 'zz' format e.g "-07" fixed (TChar* p = &MemoryMarshal.GetReference(result.AppendSpan(2))) { - Number.WriteTwoDigits((uint)offset.Hours, p); + NumberFormat.WriteTwoDigits((uint)offset.Hours, p); } } else @@ -841,9 +841,9 @@ private static unsafe void FormatCustomizedTimeZone(DateTime dateTime, Ti Debug.Assert(tokenLen >= 3); fixed (TChar* p = &MemoryMarshal.GetReference(result.AppendSpan(5))) { - Number.WriteTwoDigits((uint)offset.Hours, p); + NumberFormat.WriteTwoDigits((uint)offset.Hours, p); p[2] = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)offset.Minutes, p + 3); + NumberFormat.WriteTwoDigits((uint)offset.Minutes, p + 3); } } } @@ -887,9 +887,9 @@ private static unsafe void FormatCustomizedRoundripTimeZone(DateTime date fixed (TChar* hoursMinutes = &MemoryMarshal.GetReference(result.AppendSpan(5))) { - Number.WriteTwoDigits((uint)offset.Hours, hoursMinutes); + NumberFormat.WriteTwoDigits((uint)offset.Hours, hoursMinutes); hoursMinutes[2] = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)offset.Minutes, hoursMinutes + 3); + NumberFormat.WriteTwoDigits((uint)offset.Minutes, hoursMinutes + 3); } } @@ -1326,13 +1326,13 @@ internal static unsafe bool TryFormatTimeOnlyO(TimeOnly value, Span.WriteTwoDigits((uint)hour, dest); dest[2] = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)minute, dest + 3); + NumberFormat.WriteTwoDigits((uint)minute, dest + 3); dest[5] = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)second, dest + 6); + NumberFormat.WriteTwoDigits((uint)second, dest + 6); dest[8] = TChar.CastFrom('.'); - Number.WriteDigits((uint)fraction, dest + 9, 7); + NumberFormat.WriteDigits((uint)fraction, dest + 9, 7); } return true; @@ -1354,11 +1354,11 @@ internal static unsafe bool TryFormatTimeOnlyR(TimeOnly value, Span.WriteTwoDigits((uint)hour, dest); dest[2] = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)minute, dest + 3); + NumberFormat.WriteTwoDigits((uint)minute, dest + 3); dest[5] = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)second, dest + 6); + NumberFormat.WriteTwoDigits((uint)second, dest + 6); } return true; @@ -1381,11 +1381,11 @@ internal static unsafe bool TryFormatDateOnlyO(DateOnly value, Span.WriteFourDigits((uint)year, dest); dest[4] = TChar.CastFrom('-'); - Number.WriteTwoDigits((uint)month, dest + 5); + NumberFormat.WriteTwoDigits((uint)month, dest + 5); dest[7] = TChar.CastFrom('-'); - Number.WriteTwoDigits((uint)day, dest + 8); + NumberFormat.WriteTwoDigits((uint)day, dest + 8); } return true; @@ -1420,14 +1420,14 @@ internal static unsafe bool TryFormatDateOnlyR(DateOnly value, Span.WriteTwoDigits((uint)day, dest + 5); dest[7] = TChar.CastFrom(' '); c = monthAbbrev[2]; // remove bounds checks on remaining monthAbbrev accesses dest[8] = TChar.CastFrom(monthAbbrev[0]); dest[9] = TChar.CastFrom(monthAbbrev[1]); dest[10] = TChar.CastFrom(c); dest[11] = TChar.CastFrom(' '); - Number.WriteFourDigits((uint)year, dest + 12); + NumberFormat.WriteFourDigits((uint)year, dest + 12); } return true; @@ -1473,20 +1473,20 @@ internal static unsafe bool TryFormatO(DateTime dateTime, TimeSpan offset fixed (TChar* dest = &MemoryMarshal.GetReference(destination)) { - Number.WriteFourDigits((uint)year, dest); + NumberFormat.WriteFourDigits((uint)year, dest); dest[4] = TChar.CastFrom('-'); - Number.WriteTwoDigits((uint)month, dest + 5); + NumberFormat.WriteTwoDigits((uint)month, dest + 5); dest[7] = TChar.CastFrom('-'); - Number.WriteTwoDigits((uint)day, dest + 8); + NumberFormat.WriteTwoDigits((uint)day, dest + 8); dest[10] = TChar.CastFrom('T'); dateTime.GetTimePrecise(out int hour, out int minute, out int second, out int tick); - Number.WriteTwoDigits((uint)hour, dest + 11); + NumberFormat.WriteTwoDigits((uint)hour, dest + 11); dest[13] = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)minute, dest + 14); + NumberFormat.WriteTwoDigits((uint)minute, dest + 14); dest[16] = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)second, dest + 17); + NumberFormat.WriteTwoDigits((uint)second, dest + 17); dest[19] = TChar.CastFrom('.'); - Number.WriteDigits((uint)tick, dest + 20, 7); + NumberFormat.WriteDigits((uint)tick, dest + 20, 7); if (kind == DateTimeKind.Local) { @@ -1502,9 +1502,9 @@ internal static unsafe bool TryFormatO(DateTime dateTime, TimeSpan offset (int offsetHours, int offsetMinutes) = Math.DivRem(offsetTotalMinutes, 60); dest[27] = TChar.CastFrom(sign); - Number.WriteTwoDigits((uint)offsetHours, dest + 28); + NumberFormat.WriteTwoDigits((uint)offsetHours, dest + 28); dest[30] = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)offsetMinutes, dest + 31); + NumberFormat.WriteTwoDigits((uint)offsetMinutes, dest + 31); } else if (kind == DateTimeKind.Utc) { @@ -1533,18 +1533,18 @@ internal static unsafe bool TryFormatS(DateTime dateTime, Span des fixed (TChar* dest = &MemoryMarshal.GetReference(destination)) { - Number.WriteFourDigits((uint)year, dest); + NumberFormat.WriteFourDigits((uint)year, dest); dest[4] = TChar.CastFrom('-'); - Number.WriteTwoDigits((uint)month, dest + 5); + NumberFormat.WriteTwoDigits((uint)month, dest + 5); dest[7] = TChar.CastFrom('-'); - Number.WriteTwoDigits((uint)day, dest + 8); + NumberFormat.WriteTwoDigits((uint)day, dest + 8); dest[10] = TChar.CastFrom('T'); dateTime.GetTime(out int hour, out int minute, out int second); - Number.WriteTwoDigits((uint)hour, dest + 11); + NumberFormat.WriteTwoDigits((uint)hour, dest + 11); dest[13] = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)minute, dest + 14); + NumberFormat.WriteTwoDigits((uint)minute, dest + 14); dest[16] = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)second, dest + 17); + NumberFormat.WriteTwoDigits((uint)second, dest + 17); } return true; @@ -1573,18 +1573,18 @@ internal static unsafe bool TryFormatu(DateTime dateTime, TimeSpan offset fixed (TChar* dest = &MemoryMarshal.GetReference(destination)) { - Number.WriteFourDigits((uint)year, dest); + NumberFormat.WriteFourDigits((uint)year, dest); dest[4] = TChar.CastFrom('-'); - Number.WriteTwoDigits((uint)month, dest + 5); + NumberFormat.WriteTwoDigits((uint)month, dest + 5); dest[7] = TChar.CastFrom('-'); - Number.WriteTwoDigits((uint)day, dest + 8); + NumberFormat.WriteTwoDigits((uint)day, dest + 8); dest[10] = TChar.CastFrom(' '); dateTime.GetTime(out int hour, out int minute, out int second); - Number.WriteTwoDigits((uint)hour, dest + 11); + NumberFormat.WriteTwoDigits((uint)hour, dest + 11); dest[13] = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)minute, dest + 14); + NumberFormat.WriteTwoDigits((uint)minute, dest + 14); dest[16] = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)second, dest + 17); + NumberFormat.WriteTwoDigits((uint)second, dest + 17); dest[19] = TChar.CastFrom('Z'); } @@ -1627,21 +1627,21 @@ internal static unsafe bool TryFormatR(DateTime dateTime, TimeSpan offset dest[2] = TChar.CastFrom(c); dest[3] = TChar.CastFrom(','); dest[4] = TChar.CastFrom(' '); - Number.WriteTwoDigits((uint)day, dest + 5); + NumberFormat.WriteTwoDigits((uint)day, dest + 5); dest[7] = TChar.CastFrom(' '); c = monthAbbrev[2]; // remove bounds checks on remaining monthAbbrev accesses dest[8] = TChar.CastFrom(monthAbbrev[0]); dest[9] = TChar.CastFrom(monthAbbrev[1]); dest[10] = TChar.CastFrom(c); dest[11] = TChar.CastFrom(' '); - Number.WriteFourDigits((uint)year, dest + 12); + NumberFormat.WriteFourDigits((uint)year, dest + 12); dest[16] = TChar.CastFrom(' '); dateTime.GetTime(out int hour, out int minute, out int second); - Number.WriteTwoDigits((uint)hour, dest + 17); + NumberFormat.WriteTwoDigits((uint)hour, dest + 17); dest[19] = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)minute, dest + 20); + NumberFormat.WriteTwoDigits((uint)minute, dest + 20); dest[22] = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)second, dest + 23); + NumberFormat.WriteTwoDigits((uint)second, dest + 23); dest[25] = TChar.CastFrom(' '); dest[26] = TChar.CastFrom('G'); dest[27] = TChar.CastFrom('M'); @@ -1680,19 +1680,19 @@ internal static unsafe bool TryFormatInvariantG(DateTime value, TimeSpan fixed (TChar* dest = &MemoryMarshal.GetReference(destination)) { - Number.WriteTwoDigits((uint)month, dest); + NumberFormat.WriteTwoDigits((uint)month, dest); dest[2] = TChar.CastFrom('/'); - Number.WriteTwoDigits((uint)day, dest + 3); + NumberFormat.WriteTwoDigits((uint)day, dest + 3); dest[5] = TChar.CastFrom('/'); - Number.WriteFourDigits((uint)year, dest + 6); + NumberFormat.WriteFourDigits((uint)year, dest + 6); dest[10] = TChar.CastFrom(' '); value.GetTime(out int hour, out int minute, out int second); - Number.WriteTwoDigits((uint)hour, dest + 11); + NumberFormat.WriteTwoDigits((uint)hour, dest + 11); dest[13] = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)minute, dest + 14); + NumberFormat.WriteTwoDigits((uint)minute, dest + 14); dest[16] = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)second, dest + 17); + NumberFormat.WriteTwoDigits((uint)second, dest + 17); if (offset.Ticks != NullOffset) { @@ -1707,9 +1707,9 @@ internal static unsafe bool TryFormatInvariantG(DateTime value, TimeSpan dest[19] = TChar.CastFrom(' '); dest[20] = sign; - Number.WriteTwoDigits((uint)offsetHours, dest + 21); + NumberFormat.WriteTwoDigits((uint)offsetHours, dest + 21); dest[23] = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)offsetMinutes, dest + 24); + NumberFormat.WriteTwoDigits((uint)offsetMinutes, dest + 24); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/TimeSpanFormat.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/TimeSpanFormat.cs index 33595d0907242a..75dc3081c5dbb6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/TimeSpanFormat.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/TimeSpanFormat.cs @@ -242,7 +242,7 @@ internal static unsafe bool TryFormatStandard(TimeSpan value, StandardFor // Write day and separator, if necessary if (dayDigits != 0) { - Number.WriteDigits(days, p, dayDigits); + NumberFormat.WriteDigits(days, p, dayDigits); p += dayDigits; *p++ = TChar.CastFrom(format == StandardFormat.C ? '.' : ':'); } @@ -251,7 +251,7 @@ internal static unsafe bool TryFormatStandard(TimeSpan value, StandardFor Debug.Assert(hourDigits == 1 || hourDigits == 2); if (hourDigits == 2) { - Number.WriteTwoDigits(hours, p); + NumberFormat.WriteTwoDigits(hours, p); p += 2; } else @@ -259,10 +259,10 @@ internal static unsafe bool TryFormatStandard(TimeSpan value, StandardFor *p++ = TChar.CastFrom('0' + hours); } *p++ = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)minutes, p); + NumberFormat.WriteTwoDigits((uint)minutes, p); p += 2; *p++ = TChar.CastFrom(':'); - Number.WriteTwoDigits((uint)seconds, p); + NumberFormat.WriteTwoDigits((uint)seconds, p); p += 2; // Write fraction and separator, if necessary @@ -282,7 +282,7 @@ internal static unsafe bool TryFormatStandard(TimeSpan value, StandardFor p += decimalSeparator.Length; } - Number.WriteDigits(fraction, p, fractionDigits); + NumberFormat.WriteDigits(fraction, p, fractionDigits); p += fractionDigits; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Int128.cs b/src/libraries/System.Private.CoreLib/src/System/Int128.cs index bfc8e8c8bf0e25..b6c40ad5142482 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Int128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Int128.cs @@ -117,13 +117,13 @@ public string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] strin public bool TryFormat(Span destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatInt128(this, format, provider, destination, out charsWritten); + return NumberFormat.TryFormatInt128(this, format, provider, destination, out charsWritten); } /// public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatInt128(this, format, provider, utf8Destination, out bytesWritten); + return NumberFormat.TryFormatInt128(this, format, provider, utf8Destination, out bytesWritten); } public static Int128 Parse(string s) => Parse(s, NumberStyles.Integer, provider: null); diff --git a/src/libraries/System.Private.CoreLib/src/System/Int16.cs b/src/libraries/System.Private.CoreLib/src/System/Int16.cs index b1a90999ea5e9e..b5cb3a3dfdf985 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Int16.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Int16.cs @@ -117,13 +117,13 @@ public string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] strin public bool TryFormat(Span destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatInt32(m_value, 0x0000FFFF, format, provider, destination, out charsWritten); + return NumberFormat.TryFormatInt32(m_value, 0x0000FFFF, format, provider, destination, out charsWritten); } /// public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatInt32(m_value, 0x0000FFFF, format, provider, utf8Destination, out bytesWritten); + return NumberFormat.TryFormatInt32(m_value, 0x0000FFFF, format, provider, utf8Destination, out bytesWritten); } public static short Parse(string s) => Parse(s, NumberStyles.Integer, provider: null); diff --git a/src/libraries/System.Private.CoreLib/src/System/Int32.cs b/src/libraries/System.Private.CoreLib/src/System/Int32.cs index 7a0cce55bc8099..271d6593d9ecef 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Int32.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Int32.cs @@ -133,13 +133,13 @@ public string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] strin public bool TryFormat(Span destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatInt32(m_value, ~0, format, provider, destination, out charsWritten); + return NumberFormat.TryFormatInt32(m_value, ~0, format, provider, destination, out charsWritten); } /// public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatInt32(m_value, ~0, format, provider, utf8Destination, out bytesWritten); + return NumberFormat.TryFormatInt32(m_value, ~0, format, provider, utf8Destination, out bytesWritten); } public static int Parse(string s) => Parse(s, NumberStyles.Integer, provider: null); diff --git a/src/libraries/System.Private.CoreLib/src/System/Int64.cs b/src/libraries/System.Private.CoreLib/src/System/Int64.cs index aa07dbb7d0327b..df564a6dba08bb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Int64.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Int64.cs @@ -130,13 +130,13 @@ public string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] strin public bool TryFormat(Span destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatInt64(m_value, format, provider, destination, out charsWritten); + return NumberFormat.TryFormatInt64(m_value, format, provider, destination, out charsWritten); } /// public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatInt64(m_value, format, provider, utf8Destination, out bytesWritten); + return NumberFormat.TryFormatInt64(m_value, format, provider, utf8Destination, out bytesWritten); } public static long Parse(string s) => Parse(s, NumberStyles.Integer, provider: null); diff --git a/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs b/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs index 2062aa526cb386..1ddf466ceb11d2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs @@ -250,7 +250,7 @@ namespace System internal static partial class Number { - internal const int DecimalPrecision = 29; // Decimal.DecCalc also uses this value + private const int DecimalPrecision = 29; // Decimal.DecCalc also uses this value /// The non-inclusive upper bound of . /// @@ -325,7 +325,7 @@ private static ref byte GetTwoDigitsBytesRef(bool useChars) => "90919293949596979899"u8; [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ref byte GetTwoDigitsBytesRef(bool useChars) => + public static ref byte GetTwoDigitsBytesRef(bool useChars) => ref MemoryMarshal.GetReference(useChars ? TwoDigitsCharsAsBytes : TwoDigitsBytes); #endif @@ -356,35 +356,7 @@ public static unsafe string FormatDecimal(decimal value, ReadOnlySpan form return result; } - public static unsafe bool TryFormatDecimal(decimal value, ReadOnlySpan format, NumberFormatInfo info, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - char fmt = ParseFormatSpecifier(format, out int digits); - - byte* pDigits = stackalloc byte[DecimalNumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Decimal, pDigits, DecimalNumberBufferLength); - - DecimalToNumber(ref value, ref number); - - TChar* stackPtr = stackalloc TChar[CharStackBufferSize]; - var vlb = new ValueListBuilder(new Span(stackPtr, CharStackBufferSize)); - - if (fmt != 0) - { - NumberToString(ref vlb, ref number, fmt, digits, info); - } - else - { - NumberToStringFormat(ref vlb, ref number, format, info); - } - - bool success = vlb.TryCopyTo(destination, out charsWritten); - vlb.Dispose(); - return success; - } - - internal static unsafe void DecimalToNumber(scoped ref decimal d, ref NumberBuffer number) + public static unsafe void DecimalToNumber(scoped ref decimal d, ref NumberBuffer number) { byte* buffer = number.DigitsPtr; number.DigitsCount = DecimalPrecision; @@ -393,9 +365,9 @@ internal static unsafe void DecimalToNumber(scoped ref decimal d, ref NumberBuff byte* p = buffer + DecimalPrecision; while ((d.Mid | d.High) != 0) { - p = UInt32ToDecChars(p, decimal.DecDivMod1E9(ref d), 9); + p = NumberFormat.UInt32ToDecChars(p, decimal.DecDivMod1E9(ref d), 9); } - p = UInt32ToDecChars(p, d.Low, 0); + p = NumberFormat.UInt32ToDecChars(p, d.Low, 0); int i = (int)((buffer + DecimalPrecision) - p); @@ -664,7 +636,7 @@ private static bool TryCopyTo(string source, Span destination, out } } - internal static char GetHexBase(char fmt) + public static char GetHexBase(char fmt) { // The fmt-(X-A+10) hack has the effect of dictating whether we produce uppercase or lowercase // hex numbers for a-f. 'X' as the fmt code produces uppercase. 'x' as the format code produces lowercase. @@ -730,65 +702,6 @@ static unsafe string FormatInt32Slow(int value, int hexMask, string? format, IFo } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] // expose to caller's likely-const format to trim away slow path - public static bool TryFormatInt32(int value, int hexMask, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - // Fast path for default format - if (format.Length == 0) - { - return value >= 0 ? - TryUInt32ToDecStr((uint)value, destination, out charsWritten) : - TryNegativeInt32ToDecStr(value, digits: -1, NumberFormatInfo.GetInstance(provider).NegativeSignTChar(), destination, out charsWritten); - } - - return TryFormatInt32Slow(value, hexMask, format, provider, destination, out charsWritten); - - static unsafe bool TryFormatInt32Slow(int value, int hexMask, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) - { - char fmt = ParseFormatSpecifier(format, out int digits); - char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison - if (fmtUpper == 'G' ? digits < 1 : fmtUpper == 'D') - { - return value >= 0 ? - TryUInt32ToDecStr((uint)value, digits, destination, out charsWritten) : - TryNegativeInt32ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSignTChar(), destination, out charsWritten); - } - else if (fmtUpper == 'X') - { - return TryInt32ToHexStr(value & hexMask, GetHexBase(fmt), digits, destination, out charsWritten); - } - else if (fmtUpper == 'B') - { - return TryUInt32ToBinaryStr((uint)(value & hexMask), digits, destination, out charsWritten); - } - else - { - NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); - - byte* pDigits = stackalloc byte[Int32NumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int32NumberBufferLength); - - Int32ToNumber(value, ref number); - - TChar* stackPtr = stackalloc TChar[CharStackBufferSize]; - var vlb = new ValueListBuilder(new Span(stackPtr, CharStackBufferSize)); - - if (fmt != 0) - { - NumberToString(ref vlb, ref number, fmt, digits, info); - } - else - { - NumberToStringFormat(ref vlb, ref number, format, info); - } - - bool success = vlb.TryCopyTo(destination, out charsWritten); - vlb.Dispose(); - return success; - } - } - } - public static string FormatUInt32(uint value, string? format, IFormatProvider? provider) { // Fast path for default format @@ -844,63 +757,6 @@ static unsafe string FormatUInt32Slow(uint value, string? format, IFormatProvide } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] // expose to caller's likely-const format to trim away slow path - public static bool TryFormatUInt32(uint value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - // Fast path for default format - if (format.Length == 0) - { - return TryUInt32ToDecStr(value, destination, out charsWritten); - } - - return TryFormatUInt32Slow(value, format, provider, destination, out charsWritten); - - static unsafe bool TryFormatUInt32Slow(uint value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) - { - char fmt = ParseFormatSpecifier(format, out int digits); - char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison - if (fmtUpper == 'G' ? digits < 1 : fmtUpper == 'D') - { - return TryUInt32ToDecStr(value, digits, destination, out charsWritten); - } - else if (fmtUpper == 'X') - { - return TryInt32ToHexStr((int)value, GetHexBase(fmt), digits, destination, out charsWritten); - } - else if (fmtUpper == 'B') - { - return TryUInt32ToBinaryStr(value, digits, destination, out charsWritten); - } - else - { - NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); - - byte* pDigits = stackalloc byte[UInt32NumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt32NumberBufferLength); - - UInt32ToNumber(value, ref number); - - TChar* stackPtr = stackalloc TChar[CharStackBufferSize]; - var vlb = new ValueListBuilder(new Span(stackPtr, CharStackBufferSize)); - - if (fmt != 0) - { - NumberToString(ref vlb, ref number, fmt, digits, info); - } - else - { - NumberToStringFormat(ref vlb, ref number, format, info); - } - - bool success = vlb.TryCopyTo(destination, out charsWritten); - vlb.Dispose(); - return success; - } - } - } - public static string FormatInt64(long value, string? format, IFormatProvider? provider) { // Fast path for default format @@ -960,67 +816,6 @@ static unsafe string FormatInt64Slow(long value, string? format, IFormatProvider } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] // expose to caller's likely-const format to trim away slow path - public static bool TryFormatInt64(long value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - // Fast path for default format - if (format.Length == 0) - { - return value >= 0 ? - TryUInt64ToDecStr((ulong)value, destination, out charsWritten) : - TryNegativeInt64ToDecStr(value, digits: -1, NumberFormatInfo.GetInstance(provider).NegativeSignTChar(), destination, out charsWritten); - } - - return TryFormatInt64Slow(value, format, provider, destination, out charsWritten); - - static unsafe bool TryFormatInt64Slow(long value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) - { - char fmt = ParseFormatSpecifier(format, out int digits); - char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison - if (fmtUpper == 'G' ? digits < 1 : fmtUpper == 'D') - { - return value >= 0 ? - TryUInt64ToDecStr((ulong)value, digits, destination, out charsWritten) : - TryNegativeInt64ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSignTChar(), destination, out charsWritten); - } - else if (fmtUpper == 'X') - { - return TryInt64ToHexStr(value, GetHexBase(fmt), digits, destination, out charsWritten); - } - else if (fmtUpper == 'B') - { - return TryUInt64ToBinaryStr((ulong)value, digits, destination, out charsWritten); - } - else - { - NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); - - byte* pDigits = stackalloc byte[Int64NumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int64NumberBufferLength); - - Int64ToNumber(value, ref number); - - char* stackPtr = stackalloc char[CharStackBufferSize]; - var vlb = new ValueListBuilder(new Span(stackPtr, CharStackBufferSize)); - - if (fmt != 0) - { - NumberToString(ref vlb, ref number, fmt, digits, info); - } - else - { - NumberToStringFormat(ref vlb, ref number, format, info); - } - - bool success = vlb.TryCopyTo(destination, out charsWritten); - vlb.Dispose(); - return success; - } - } - } - public static string FormatUInt64(ulong value, string? format, IFormatProvider? provider) { // Fast path for default format @@ -1076,63 +871,6 @@ static unsafe string FormatUInt64Slow(ulong value, string? format, IFormatProvid } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] // expose to caller's likely-const format to trim away slow path - public static bool TryFormatUInt64(ulong value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - // Fast path for default format - if (format.Length == 0) - { - return TryUInt64ToDecStr(value, destination, out charsWritten); - } - - return TryFormatUInt64Slow(value, format, provider, destination, out charsWritten); - - static unsafe bool TryFormatUInt64Slow(ulong value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) - { - char fmt = ParseFormatSpecifier(format, out int digits); - char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison - if (fmtUpper == 'G' ? digits < 1 : fmtUpper == 'D') - { - return TryUInt64ToDecStr(value, digits, destination, out charsWritten); - } - else if (fmtUpper == 'X') - { - return TryInt64ToHexStr((long)value, GetHexBase(fmt), digits, destination, out charsWritten); - } - else if (fmtUpper == 'B') - { - return TryUInt64ToBinaryStr(value, digits, destination, out charsWritten); - } - else - { - NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); - - byte* pDigits = stackalloc byte[UInt64NumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt64NumberBufferLength); - - UInt64ToNumber(value, ref number); - - TChar* stackPtr = stackalloc TChar[CharStackBufferSize]; - var vlb = new ValueListBuilder(new Span(stackPtr, CharStackBufferSize)); - - if (fmt != 0) - { - NumberToString(ref vlb, ref number, fmt, digits, info); - } - else - { - NumberToStringFormat(ref vlb, ref number, format, info); - } - - bool success = vlb.TryCopyTo(destination, out charsWritten); - vlb.Dispose(); - return success; - } - } - } - public static string FormatInt128(Int128 value, string? format, IFormatProvider? provider) { // Fast path for default format @@ -1194,67 +932,6 @@ static unsafe string FormatInt128Slow(Int128 value, string? format, IFormatProvi } } - public static bool TryFormatInt128(Int128 value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - // Fast path for default format - if (format.Length == 0) - { - return Int128.IsPositive(value) - ? TryUInt128ToDecStr((UInt128)value, digits: -1, destination, out charsWritten) - : TryNegativeInt128ToDecStr(value, digits: -1, NumberFormatInfo.GetInstance(provider).NegativeSignTChar(), destination, out charsWritten); - } - - return TryFormatInt128Slow(value, format, provider, destination, out charsWritten); - - static unsafe bool TryFormatInt128Slow(Int128 value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) - { - char fmt = ParseFormatSpecifier(format, out int digits); - char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison - - if (fmtUpper == 'G' ? digits < 1 : fmtUpper == 'D') - { - return Int128.IsPositive(value) - ? TryUInt128ToDecStr((UInt128)value, digits, destination, out charsWritten) - : TryNegativeInt128ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSignTChar(), destination, out charsWritten); - } - else if (fmtUpper == 'X') - { - return TryInt128ToHexStr(value, GetHexBase(fmt), digits, destination, out charsWritten); - } - else if (fmtUpper == 'B') - { - return TryUInt128ToBinaryStr(value, digits, destination, out charsWritten); - } - else - { - NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); - - byte* pDigits = stackalloc byte[Int128NumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, Int128NumberBufferLength); - - Int128ToNumber(value, ref number); - - TChar* stackPtr = stackalloc TChar[CharStackBufferSize]; - var vlb = new ValueListBuilder(new Span(stackPtr, CharStackBufferSize)); - - if (fmt != 0) - { - NumberToString(ref vlb, ref number, fmt, digits, info); - } - else - { - NumberToStringFormat(ref vlb, ref number, format, info); - } - - bool success = vlb.TryCopyTo(destination, out charsWritten); - vlb.Dispose(); - return success; - } - } - } - public static string FormatUInt128(UInt128 value, string? format, IFormatProvider? provider) { // Fast path for default format @@ -1312,82 +989,25 @@ static unsafe string FormatUInt128Slow(UInt128 value, string? format, IFormatPro } } - public static bool TryFormatUInt128(UInt128 value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void Int32ToNumber(int value, ref NumberBuffer number) { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + number.DigitsCount = Int32Precision; - // Fast path for default format - if (format.Length == 0) + if (value >= 0) + { + number.IsNegative = false; + } + else { - return TryUInt128ToDecStr(value, digits: -1, destination, out charsWritten); + number.IsNegative = true; + value = -value; } - return TryFormatUInt128Slow(value, format, provider, destination, out charsWritten); + byte* buffer = number.DigitsPtr; + byte* p = NumberFormat.UInt32ToDecChars(buffer + Int32Precision, (uint)value, 0); - static unsafe bool TryFormatUInt128Slow(UInt128 value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) - { - char fmt = ParseFormatSpecifier(format, out int digits); - char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison - - if (fmtUpper == 'G' ? digits < 1 : fmtUpper == 'D') - { - return TryUInt128ToDecStr(value, digits, destination, out charsWritten); - } - else if (fmtUpper == 'X') - { - return TryInt128ToHexStr((Int128)value, GetHexBase(fmt), digits, destination, out charsWritten); - } - else if (fmtUpper == 'B') - { - return TryUInt128ToBinaryStr((Int128)value, digits, destination, out charsWritten); - } - else - { - NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); - - byte* pDigits = stackalloc byte[UInt128NumberBufferLength]; - NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, pDigits, UInt128NumberBufferLength); - - UInt128ToNumber(value, ref number); - - TChar* stackPtr = stackalloc TChar[CharStackBufferSize]; - var vlb = new ValueListBuilder(new Span(stackPtr, CharStackBufferSize)); - - if (fmt != 0) - { - NumberToString(ref vlb, ref number, fmt, digits, info); - } - else - { - NumberToStringFormat(ref vlb, ref number, format, info); - } - - bool success = vlb.TryCopyTo(destination, out charsWritten); - vlb.Dispose(); - return success; - } - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe void Int32ToNumber(int value, ref NumberBuffer number) - { - number.DigitsCount = Int32Precision; - - if (value >= 0) - { - number.IsNegative = false; - } - else - { - number.IsNegative = true; - value = -value; - } - - byte* buffer = number.DigitsPtr; - byte* p = UInt32ToDecChars(buffer + Int32Precision, (uint)value, 0); - - int i = (int)(buffer + Int32Precision - p); + int i = (int)(buffer + Int32Precision - p); number.DigitsCount = i; number.Scale = i; @@ -1420,7 +1040,7 @@ private static unsafe string NegativeInt32ToDecStr(int value, int digits, string string result = string.FastAllocateString(bufferLength); fixed (char* buffer = result) { - char* p = UInt32ToDecChars(buffer + bufferLength, (uint)(-value), digits); + char* p = NumberFormat.UInt32ToDecChars(buffer + bufferLength, (uint)(-value), digits); Debug.Assert(p == buffer + sNegative.Length); for (int i = sNegative.Length - 1; i >= 0; i--) @@ -1432,38 +1052,6 @@ private static unsafe string NegativeInt32ToDecStr(int value, int digits, string return result; } - internal static unsafe bool TryNegativeInt32ToDecStr(int value, int digits, ReadOnlySpan sNegative, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - Debug.Assert(value < 0); - - if (digits < 1) - { - digits = 1; - } - - int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits((uint)(-value))) + sNegative.Length; - if (bufferLength > destination.Length) - { - charsWritten = 0; - return false; - } - - charsWritten = bufferLength; - fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) - { - TChar* p = UInt32ToDecChars(buffer + bufferLength, (uint)(-value), digits); - Debug.Assert(p == buffer + sNegative.Length); - - for (int i = sNegative.Length - 1; i >= 0; i--) - { - *(--p) = sNegative[i]; - } - Debug.Assert(p == buffer); - } - return true; - } - private static unsafe string Int32ToHexStr(int value, char hexBase, int digits) { if (digits < 1) @@ -1475,51 +1063,12 @@ private static unsafe string Int32ToHexStr(int value, char hexBase, int digits) string result = string.FastAllocateString(bufferLength); fixed (char* buffer = result) { - char* p = Int32ToHexChars(buffer + bufferLength, (uint)value, hexBase, digits); + char* p = NumberFormat.Int32ToHexChars(buffer + bufferLength, (uint)value, hexBase, digits); Debug.Assert(p == buffer); } return result; } - internal static unsafe bool TryInt32ToHexStr(int value, char hexBase, int digits, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - if (digits < 1) - { - digits = 1; - } - - int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits((uint)value)); - if (bufferLength > destination.Length) - { - charsWritten = 0; - return false; - } - - charsWritten = bufferLength; - fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) - { - TChar* p = Int32ToHexChars(buffer + bufferLength, (uint)value, hexBase, digits); - Debug.Assert(p == buffer); - } - return true; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe TChar* Int32ToHexChars(TChar* buffer, uint value, int hexBase, int digits) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - while (--digits >= 0 || value != 0) - { - byte digit = (byte)(value & 0xF); - *(--buffer) = TChar.CastFrom(digit + (digit < 10 ? (byte)'0' : hexBase)); - value >>= 4; - } - return buffer; - } - private static unsafe string UInt32ToBinaryStr(uint value, int digits) { if (digits < 1) @@ -1531,58 +1080,20 @@ private static unsafe string UInt32ToBinaryStr(uint value, int digits) string result = string.FastAllocateString(bufferLength); fixed (char* buffer = result) { - char* p = UInt32ToBinaryChars(buffer + bufferLength, value, digits); + char* p = NumberFormat.UInt32ToBinaryChars(buffer + bufferLength, value, digits); Debug.Assert(p == buffer); } return result; } - private static unsafe bool TryUInt32ToBinaryStr(uint value, int digits, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - if (digits < 1) - { - digits = 1; - } - - int bufferLength = Math.Max(digits, 32 - (int)uint.LeadingZeroCount(value)); - if (bufferLength > destination.Length) - { - charsWritten = 0; - return false; - } - - charsWritten = bufferLength; - fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) - { - TChar* p = UInt32ToBinaryChars(buffer + bufferLength, value, digits); - Debug.Assert(p == buffer); - } - return true; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe TChar* UInt32ToBinaryChars(TChar* buffer, uint value, int digits) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - while (--digits >= 0 || value != 0) - { - *(--buffer) = TChar.CastFrom('0' + (byte)(value & 0x1)); - value >>= 1; - } - return buffer; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe void UInt32ToNumber(uint value, ref NumberBuffer number) + public static unsafe void UInt32ToNumber(uint value, ref NumberBuffer number) { number.DigitsCount = UInt32Precision; number.IsNegative = false; byte* buffer = number.DigitsPtr; - byte* p = UInt32ToDecChars(buffer + UInt32Precision, value, 0); + byte* p = NumberFormat.UInt32ToDecChars(buffer + UInt32Precision, value, 0); int i = (int)(buffer + UInt32Precision - p); @@ -1599,113 +1110,7 @@ private static unsafe void UInt32ToNumber(uint value, ref NumberBuffer number) number.CheckConsistency(); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static unsafe void WriteTwoDigits(uint value, TChar* ptr) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - Debug.Assert(value <= 99); - - Unsafe.CopyBlockUnaligned( - ref *(byte*)ptr, - ref Unsafe.Add(ref GetTwoDigitsBytesRef(typeof(TChar) == typeof(char)), (uint)sizeof(TChar) * 2 * value), - (uint)sizeof(TChar) * 2); - } - - /// - /// Writes a value [ 0000 .. 9999 ] to the buffer starting at the specified offset. - /// This method performs best when the starting index is a constant literal. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static unsafe void WriteFourDigits(uint value, TChar* ptr) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - Debug.Assert(value <= 9999); - - (value, uint remainder) = Math.DivRem(value, 100); - - ref byte charsArray = ref GetTwoDigitsBytesRef(typeof(TChar) == typeof(char)); - - Unsafe.CopyBlockUnaligned( - ref *(byte*)ptr, - ref Unsafe.Add(ref charsArray, (uint)sizeof(TChar) * 2 * value), - (uint)sizeof(TChar) * 2); - - Unsafe.CopyBlockUnaligned( - ref *(byte*)(ptr + 2), - ref Unsafe.Add(ref charsArray, (uint)sizeof(TChar) * 2 * remainder), - (uint)sizeof(TChar) * 2); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static unsafe void WriteDigits(uint value, TChar* ptr, int count) where TChar : unmanaged, IUtfChar - { - TChar* cur; - for (cur = ptr + count - 1; cur > ptr; cur--) - { - uint temp = '0' + value; - value /= 10; - *cur = TChar.CastFrom(temp - (value * 10)); - } - - Debug.Assert(value < 10); - Debug.Assert(cur == ptr); - *cur = TChar.CastFrom('0' + value); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static unsafe TChar* UInt32ToDecChars(TChar* bufferEnd, uint value) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - if (value >= 10) - { - // Handle all values >= 100 two-digits at a time so as to avoid expensive integer division operations. - while (value >= 100) - { - bufferEnd -= 2; - (value, uint remainder) = Math.DivRem(value, 100); - WriteTwoDigits(remainder, bufferEnd); - } - - // If there are two digits remaining, store them. - if (value >= 10) - { - bufferEnd -= 2; - WriteTwoDigits(value, bufferEnd); - return bufferEnd; - } - } - - // Otherwise, store the single digit remaining. - *(--bufferEnd) = TChar.CastFrom(value + '0'); - return bufferEnd; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static unsafe TChar* UInt32ToDecChars(TChar* bufferEnd, uint value, int digits) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - uint remainder; - while (value >= 100) - { - bufferEnd -= 2; - digits -= 2; - (value, remainder) = Math.DivRem(value, 100); - WriteTwoDigits(remainder, bufferEnd); - } - - while (value != 0 || digits > 0) - { - digits--; - (value, remainder) = Math.DivRem(value, 10); - *(--bufferEnd) = TChar.CastFrom(remainder + '0'); - } - - return bufferEnd; - } - - internal static string UInt32ToDecStr(uint value) + public static string UInt32ToDecStr(uint value) { // For small numbers, consult a lazily-populated cache. if (value < SmallNumberCacheLength) @@ -1716,7 +1121,7 @@ internal static string UInt32ToDecStr(uint value) return UInt32ToDecStr_NoSmallNumberCheck(value); } - internal static string UInt32ToDecStrForKnownSmallNumber(uint value) + private static string UInt32ToDecStrForKnownSmallNumber(uint value) { Debug.Assert(value < SmallNumberCacheLength); return s_smallNumberCache[value] ?? CreateAndCacheString(value); @@ -1734,7 +1139,7 @@ private static unsafe string UInt32ToDecStr_NoSmallNumberCheck(uint value) fixed (char* buffer = result) { char* p = buffer + bufferLength; - p = UInt32ToDecChars(p, value); + p = NumberFormat.UInt32ToDecChars(p, value); Debug.Assert(p == buffer); } return result; @@ -1750,58 +1155,14 @@ private static unsafe string UInt32ToDecStr(uint value, int digits) fixed (char* buffer = result) { char* p = buffer + bufferLength; - p = UInt32ToDecChars(p, value, digits); + p = NumberFormat.UInt32ToDecChars(p, value, digits); Debug.Assert(p == buffer); } return result; } - internal static unsafe bool TryUInt32ToDecStr(uint value, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - int bufferLength = FormattingHelpers.CountDigits(value); - if (bufferLength <= destination.Length) - { - charsWritten = bufferLength; - fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) - { - TChar* p = UInt32ToDecChars(buffer + bufferLength, value); - Debug.Assert(p == buffer); - } - return true; - } - - charsWritten = 0; - return false; - } - - internal static unsafe bool TryUInt32ToDecStr(uint value, int digits, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - int countedDigits = FormattingHelpers.CountDigits(value); - int bufferLength = Math.Max(digits, countedDigits); - if (bufferLength <= destination.Length) - { - charsWritten = bufferLength; - fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) - { - TChar* p = buffer + bufferLength; - p = digits > countedDigits ? - UInt32ToDecChars(p, value, digits) : - UInt32ToDecChars(p, value); - Debug.Assert(p == buffer); - } - return true; - } - - charsWritten = 0; - return false; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe void Int64ToNumber(long value, ref NumberBuffer number) + public static unsafe void Int64ToNumber(long value, ref NumberBuffer number) { number.DigitsCount = Int64Precision; @@ -1816,7 +1177,7 @@ private static unsafe void Int64ToNumber(long value, ref NumberBuffer number) } byte* buffer = number.DigitsPtr; - byte* p = UInt64ToDecChars(buffer + Int64Precision, (ulong)value, 0); + byte* p = NumberFormat.UInt64ToDecChars(buffer + Int64Precision, (ulong)value, 0); int i = (int)(buffer + Int64Precision - p); @@ -1853,7 +1214,7 @@ private static unsafe string NegativeInt64ToDecStr(long value, int digits, strin string result = string.FastAllocateString(bufferLength); fixed (char* buffer = result) { - char* p = UInt64ToDecChars(buffer + bufferLength, (ulong)(-value), digits); + char* p = NumberFormat.UInt64ToDecChars(buffer + bufferLength, (ulong)(-value), digits); Debug.Assert(p == buffer + sNegative.Length); for (int i = sNegative.Length - 1; i >= 0; i--) @@ -1865,38 +1226,6 @@ private static unsafe string NegativeInt64ToDecStr(long value, int digits, strin return result; } - internal static unsafe bool TryNegativeInt64ToDecStr(long value, int digits, ReadOnlySpan sNegative, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - Debug.Assert(value < 0); - - if (digits < 1) - { - digits = 1; - } - - int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits((ulong)(-value))) + sNegative.Length; - if (bufferLength > destination.Length) - { - charsWritten = 0; - return false; - } - - charsWritten = bufferLength; - fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) - { - TChar* p = UInt64ToDecChars(buffer + bufferLength, (ulong)(-value), digits); - Debug.Assert(p == buffer + sNegative.Length); - - for (int i = sNegative.Length - 1; i >= 0; i--) - { - *(--p) = sNegative[i]; - } - Debug.Assert(p == buffer); - } - return true; - } - private static unsafe string Int64ToHexStr(long value, char hexBase, int digits) { if (digits < 1) @@ -1908,67 +1237,12 @@ private static unsafe string Int64ToHexStr(long value, char hexBase, int digits) string result = string.FastAllocateString(bufferLength); fixed (char* buffer = result) { - char* p = Int64ToHexChars(buffer + bufferLength, (ulong)value, hexBase, digits); + char* p = NumberFormat.Int64ToHexChars(buffer + bufferLength, (ulong)value, hexBase, digits); Debug.Assert(p == buffer); } return result; } - internal static unsafe bool TryInt64ToHexStr(long value, char hexBase, int digits, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - if (digits < 1) - { - digits = 1; - } - - int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits((ulong)value)); - if (bufferLength > destination.Length) - { - charsWritten = 0; - return false; - } - - charsWritten = bufferLength; - fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) - { - TChar* p = Int64ToHexChars(buffer + bufferLength, (ulong)value, hexBase, digits); - Debug.Assert(p == buffer); - } - return true; - } - -#if TARGET_64BIT - [MethodImpl(MethodImplOptions.AggressiveInlining)] -#endif - private static unsafe TChar* Int64ToHexChars(TChar* buffer, ulong value, int hexBase, int digits) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); -#if TARGET_32BIT - uint lower = (uint)value; - uint upper = (uint)(value >> 32); - - if (upper != 0) - { - buffer = Int32ToHexChars(buffer, lower, hexBase, 8); - return Int32ToHexChars(buffer, upper, hexBase, digits - 8); - } - else - { - return Int32ToHexChars(buffer, lower, hexBase, Math.Max(digits, 1)); - } -#else - while (--digits >= 0 || value != 0) - { - byte digit = (byte)(value & 0xF); - *(--buffer) = TChar.CastFrom(digit + (digit < 10 ? (byte)'0' : hexBase)); - value >>= 4; - } - return buffer; -#endif - } - private static unsafe string UInt64ToBinaryStr(ulong value, int digits) { if (digits < 1) @@ -1980,74 +1254,20 @@ private static unsafe string UInt64ToBinaryStr(ulong value, int digits) string result = string.FastAllocateString(bufferLength); fixed (char* buffer = result) { - char* p = UInt64ToBinaryChars(buffer + bufferLength, value, digits); + char* p = NumberFormat.UInt64ToBinaryChars(buffer + bufferLength, value, digits); Debug.Assert(p == buffer); } return result; } - private static unsafe bool TryUInt64ToBinaryStr(ulong value, int digits, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - if (digits < 1) - { - digits = 1; - } - - int bufferLength = Math.Max(digits, 64 - (int)ulong.LeadingZeroCount(value)); - if (bufferLength > destination.Length) - { - charsWritten = 0; - return false; - } - - charsWritten = bufferLength; - fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) - { - TChar* p = UInt64ToBinaryChars(buffer + bufferLength, value, digits); - Debug.Assert(p == buffer); - } - return true; - } - -#if TARGET_64BIT - [MethodImpl(MethodImplOptions.AggressiveInlining)] -#endif - private static unsafe TChar* UInt64ToBinaryChars(TChar* buffer, ulong value, int digits) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); -#if TARGET_32BIT - uint lower = (uint)value; - uint upper = (uint)(value >> 32); - - if (upper != 0) - { - buffer = UInt32ToBinaryChars(buffer, lower, 32); - return UInt32ToBinaryChars(buffer, upper, digits - 32); - } - else - { - return UInt32ToBinaryChars(buffer, lower, Math.Max(digits, 1)); - } -#else - while (--digits >= 0 || value != 0) - { - *(--buffer) = TChar.CastFrom('0' + (byte)(value & 0x1)); - value >>= 1; - } - return buffer; -#endif - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe void UInt64ToNumber(ulong value, ref NumberBuffer number) + public static unsafe void UInt64ToNumber(ulong value, ref NumberBuffer number) { number.DigitsCount = UInt64Precision; number.IsNegative = false; byte* buffer = number.DigitsPtr; - byte* p = UInt64ToDecChars(buffer + UInt64Precision, value, 0); + byte* p = NumberFormat.UInt64ToDecChars(buffer + UInt64Precision, value, 0); int i = (int)(buffer + UInt64Precision - p); @@ -2065,88 +1285,14 @@ private static unsafe void UInt64ToNumber(ulong value, ref NumberBuffer number) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static uint Int64DivMod1E9(ref ulong value) + public static uint Int64DivMod1E9(ref ulong value) { uint rem = (uint)(value % 1_000_000_000); value /= 1_000_000_000; return rem; } -#if TARGET_64BIT - [MethodImpl(MethodImplOptions.AggressiveInlining)] -#endif - internal static unsafe TChar* UInt64ToDecChars(TChar* bufferEnd, ulong value) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - -#if TARGET_32BIT - while ((uint)(value >> 32) != 0) - { - bufferEnd = UInt32ToDecChars(bufferEnd, Int64DivMod1E9(ref value), 9); - } - return UInt32ToDecChars(bufferEnd, (uint)value); -#else - if (value >= 10) - { - // Handle all values >= 100 two-digits at a time so as to avoid expensive integer division operations. - while (value >= 100) - { - bufferEnd -= 2; - (value, ulong remainder) = Math.DivRem(value, 100); - WriteTwoDigits((uint)remainder, bufferEnd); - } - - // If there are two digits remaining, store them. - if (value >= 10) - { - bufferEnd -= 2; - WriteTwoDigits((uint)value, bufferEnd); - return bufferEnd; - } - } - - // Otherwise, store the single digit remaining. - *(--bufferEnd) = TChar.CastFrom(value + '0'); - return bufferEnd; -#endif - } - -#if TARGET_64BIT - [MethodImpl(MethodImplOptions.AggressiveInlining)] -#endif - internal static unsafe TChar* UInt64ToDecChars(TChar* bufferEnd, ulong value, int digits) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - -#if TARGET_32BIT - while ((uint)(value >> 32) != 0) - { - bufferEnd = UInt32ToDecChars(bufferEnd, Int64DivMod1E9(ref value), 9); - digits -= 9; - } - return UInt32ToDecChars(bufferEnd, (uint)value, digits); -#else - ulong remainder; - while (value >= 100) - { - bufferEnd -= 2; - digits -= 2; - (value, remainder) = Math.DivRem(value, 100); - WriteTwoDigits((uint)remainder, bufferEnd); - } - - while (value != 0 || digits > 0) - { - digits--; - (value, remainder) = Math.DivRem(value, 10); - *(--bufferEnd) = TChar.CastFrom(remainder + '0'); - } - - return bufferEnd; -#endif - } - - internal static unsafe string UInt64ToDecStr(ulong value) + public static unsafe string UInt64ToDecStr(ulong value) { // For small numbers, consult a lazily-populated cache. if (value < SmallNumberCacheLength) @@ -2160,13 +1306,13 @@ internal static unsafe string UInt64ToDecStr(ulong value) fixed (char* buffer = result) { char* p = buffer + bufferLength; - p = UInt64ToDecChars(p, value); + p = NumberFormat.UInt64ToDecChars(p, value); Debug.Assert(p == buffer); } return result; } - internal static unsafe string UInt64ToDecStr(ulong value, int digits) + private static unsafe string UInt64ToDecStr(ulong value, int digits) { if (digits <= 1) { @@ -2178,56 +1324,13 @@ internal static unsafe string UInt64ToDecStr(ulong value, int digits) fixed (char* buffer = result) { char* p = buffer + bufferLength; - p = UInt64ToDecChars(p, value, digits); + p = NumberFormat.UInt64ToDecChars(p, value, digits); Debug.Assert(p == buffer); } return result; } - internal static unsafe bool TryUInt64ToDecStr(ulong value, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - int bufferLength = FormattingHelpers.CountDigits(value); - if (bufferLength <= destination.Length) - { - charsWritten = bufferLength; - fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) - { - TChar* p = buffer + bufferLength; - p = UInt64ToDecChars(p, value); - Debug.Assert(p == buffer); - } - return true; - } - - charsWritten = 0; - return false; - } - - internal static unsafe bool TryUInt64ToDecStr(ulong value, int digits, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - int countedDigits = FormattingHelpers.CountDigits(value); - int bufferLength = Math.Max(digits, countedDigits); - if (bufferLength <= destination.Length) - { - charsWritten = bufferLength; - fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) - { - TChar* p = buffer + bufferLength; - p = digits > countedDigits ? - UInt64ToDecChars(p, value, digits) : - UInt64ToDecChars(p, value); - Debug.Assert(p == buffer); - } - return true; - } - - charsWritten = 0; - return false; - } - - private static unsafe void Int128ToNumber(Int128 value, ref NumberBuffer number) + public static unsafe void Int128ToNumber(Int128 value, ref NumberBuffer number) { number.DigitsCount = Int128Precision; @@ -2242,7 +1345,7 @@ private static unsafe void Int128ToNumber(Int128 value, ref NumberBuffer number) } byte* buffer = number.DigitsPtr; - byte* p = UInt128ToDecChars(buffer + Int128Precision, (UInt128)value, 0); + byte* p = NumberFormat.UInt128ToDecChars(buffer + Int128Precision, (UInt128)value, 0); int i = (int)(buffer + Int128Precision - p); @@ -2281,7 +1384,7 @@ private static unsafe string NegativeInt128ToDecStr(Int128 value, int digits, st string result = string.FastAllocateString(bufferLength); fixed (char* buffer = result) { - char* p = UInt128ToDecChars(buffer + bufferLength, absValue, digits); + char* p = NumberFormat.UInt128ToDecChars(buffer + bufferLength, absValue, digits); Debug.Assert(p == buffer + sNegative.Length); for (int i = sNegative.Length - 1; i >= 0; i--) @@ -2293,40 +1396,6 @@ private static unsafe string NegativeInt128ToDecStr(Int128 value, int digits, st return result; } - private static unsafe bool TryNegativeInt128ToDecStr(Int128 value, int digits, ReadOnlySpan sNegative, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - Debug.Assert(Int128.IsNegative(value)); - - if (digits < 1) - { - digits = 1; - } - - UInt128 absValue = (UInt128)(-value); - - int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits(absValue)) + sNegative.Length; - if (bufferLength > destination.Length) - { - charsWritten = 0; - return false; - } - - charsWritten = bufferLength; - fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) - { - TChar* p = UInt128ToDecChars(buffer + bufferLength, absValue, digits); - Debug.Assert(p == buffer + sNegative.Length); - - for (int i = sNegative.Length - 1; i >= 0; i--) - { - *(--p) = sNegative[i]; - } - Debug.Assert(p == buffer); - } - return true; - } - private static unsafe string Int128ToHexStr(Int128 value, char hexBase, int digits) { if (digits < 1) @@ -2340,56 +1409,12 @@ private static unsafe string Int128ToHexStr(Int128 value, char hexBase, int digi string result = string.FastAllocateString(bufferLength); fixed (char* buffer = result) { - char* p = Int128ToHexChars(buffer + bufferLength, uValue, hexBase, digits); + char* p = NumberFormat.Int128ToHexChars(buffer + bufferLength, uValue, hexBase, digits); Debug.Assert(p == buffer); } return result; } - private static unsafe bool TryInt128ToHexStr(Int128 value, char hexBase, int digits, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - if (digits < 1) - { - digits = 1; - } - - UInt128 uValue = (UInt128)value; - - int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits(uValue)); - if (bufferLength > destination.Length) - { - charsWritten = 0; - return false; - } - - charsWritten = bufferLength; - fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) - { - TChar* p = Int128ToHexChars(buffer + bufferLength, uValue, hexBase, digits); - Debug.Assert(p == buffer); - } - return true; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe TChar* Int128ToHexChars(TChar* buffer, UInt128 value, int hexBase, int digits) where TChar : unmanaged, IUtfChar - { - ulong lower = value.Lower; - ulong upper = value.Upper; - - if (upper != 0) - { - buffer = Int64ToHexChars(buffer, lower, hexBase, 16); - return Int64ToHexChars(buffer, upper, hexBase, digits - 16); - } - else - { - return Int64ToHexChars(buffer, lower, hexBase, Math.Max(digits, 1)); - } - } - private static unsafe string UInt128ToBinaryStr(Int128 value, int digits) { if (digits < 1) @@ -2403,63 +1428,19 @@ private static unsafe string UInt128ToBinaryStr(Int128 value, int digits) string result = string.FastAllocateString(bufferLength); fixed (char* buffer = result) { - char* p = UInt128ToBinaryChars(buffer + bufferLength, uValue, digits); + char* p = NumberFormat.UInt128ToBinaryChars(buffer + bufferLength, uValue, digits); Debug.Assert(p == buffer); } return result; } - private static unsafe bool TryUInt128ToBinaryStr(Int128 value, int digits, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - if (digits < 1) - { - digits = 1; - } - - UInt128 uValue = (UInt128)value; - - int bufferLength = Math.Max(digits, 128 - (int)UInt128.LeadingZeroCount((UInt128)value)); - if (bufferLength > destination.Length) - { - charsWritten = 0; - return false; - } - - charsWritten = bufferLength; - fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) - { - TChar* p = UInt128ToBinaryChars(buffer + bufferLength, uValue, digits); - Debug.Assert(p == buffer); - } - return true; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe TChar* UInt128ToBinaryChars(TChar* buffer, UInt128 value, int digits) where TChar : unmanaged, IUtfChar - { - ulong lower = value.Lower; - ulong upper = value.Upper; - - if (upper != 0) - { - buffer = UInt64ToBinaryChars(buffer, lower, 64); - return UInt64ToBinaryChars(buffer, upper, digits - 64); - } - else - { - return UInt64ToBinaryChars(buffer, lower, Math.Max(digits, 1)); - } - } - - private static unsafe void UInt128ToNumber(UInt128 value, ref NumberBuffer number) + public static unsafe void UInt128ToNumber(UInt128 value, ref NumberBuffer number) { number.DigitsCount = UInt128Precision; number.IsNegative = false; byte* buffer = number.DigitsPtr; - byte* p = UInt128ToDecChars(buffer + UInt128Precision, value, 0); + byte* p = NumberFormat.UInt128ToDecChars(buffer + UInt128Precision, value, 0); int i = (int)(buffer + UInt128Precision - p); @@ -2477,39 +1458,14 @@ private static unsafe void UInt128ToNumber(UInt128 value, ref NumberBuffer numbe } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static ulong Int128DivMod1E19(ref UInt128 value) + public static ulong Int128DivMod1E19(ref UInt128 value) { UInt128 divisor = new UInt128(0, 10_000_000_000_000_000_000); (value, UInt128 remainder) = UInt128.DivRem(value, divisor); return remainder.Lower; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static unsafe TChar* UInt128ToDecChars(TChar* bufferEnd, UInt128 value) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - while (value.Upper != 0) - { - bufferEnd = UInt64ToDecChars(bufferEnd, Int128DivMod1E19(ref value), 19); - } - return UInt64ToDecChars(bufferEnd, value.Lower); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static unsafe TChar* UInt128ToDecChars(TChar* bufferEnd, UInt128 value, int digits) where TChar : unmanaged, IUtfChar - { - Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); - - while (value.Upper != 0) - { - bufferEnd = UInt64ToDecChars(bufferEnd, Int128DivMod1E19(ref value), 19); - digits -= 19; - } - return UInt64ToDecChars(bufferEnd, value.Lower, digits); - } - - internal static unsafe string UInt128ToDecStr(UInt128 value) + public static unsafe string UInt128ToDecStr(UInt128 value) { if (value.Upper == 0) { @@ -2522,13 +1478,13 @@ internal static unsafe string UInt128ToDecStr(UInt128 value) fixed (char* buffer = result) { char* p = buffer + bufferLength; - p = UInt128ToDecChars(p, value); + p = NumberFormat.UInt128ToDecChars(p, value); Debug.Assert(p == buffer); } return result; } - internal static unsafe string UInt128ToDecStr(UInt128 value, int digits) + private static unsafe string UInt128ToDecStr(UInt128 value, int digits) { if (digits <= 1) { @@ -2540,34 +1496,12 @@ internal static unsafe string UInt128ToDecStr(UInt128 value, int digits) fixed (char* buffer = result) { char* p = buffer + bufferLength; - p = UInt128ToDecChars(p, value, digits); + p = NumberFormat.UInt128ToDecChars(p, value, digits); Debug.Assert(p == buffer); } return result; } - private static unsafe bool TryUInt128ToDecStr(UInt128 value, int digits, Span destination, out int charsWritten) where TChar : unmanaged, IUtfChar - { - int countedDigits = FormattingHelpers.CountDigits(value); - int bufferLength = Math.Max(digits, countedDigits); - if (bufferLength <= destination.Length) - { - charsWritten = bufferLength; - fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) - { - TChar* p = buffer + bufferLength; - p = digits > countedDigits ? - UInt128ToDecChars(p, value, digits) : - UInt128ToDecChars(p, value); - Debug.Assert(p == buffer); - } - return true; - } - - charsWritten = 0; - return false; - } - private static ulong ExtractFractionAndBiasedExponent(TNumber value, out int exponent) where TNumber : unmanaged, IBinaryFloatParseAndFormatInfo { diff --git a/src/libraries/System.Private.CoreLib/src/System/NumberFormat_1.cs b/src/libraries/System.Private.CoreLib/src/System/NumberFormat_1.cs new file mode 100644 index 00000000000000..88e7584d2fb419 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/NumberFormat_1.cs @@ -0,0 +1,1082 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers.Text; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System +{ + internal static partial class NumberFormat + where TChar : unmanaged, IUtfChar + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe TChar* Int32ToHexChars(TChar* buffer, uint value, int hexBase, int digits) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + while (--digits >= 0 || value != 0) + { + byte digit = (byte)(value & 0xF); + *(--buffer) = TChar.CastFrom(digit + (digit < 10 ? (byte)'0' : hexBase)); + value >>= 4; + } + return buffer; + } + +#if TARGET_64BIT + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public static unsafe TChar* Int64ToHexChars(TChar* buffer, ulong value, int hexBase, int digits) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); +#if TARGET_32BIT + uint lower = (uint)value; + uint upper = (uint)(value >> 32); + + if (upper != 0) + { + buffer = Int32ToHexChars(buffer, lower, hexBase, 8); + return Int32ToHexChars(buffer, upper, hexBase, digits - 8); + } + else + { + return Int32ToHexChars(buffer, lower, hexBase, Math.Max(digits, 1)); + } +#else + while (--digits >= 0 || value != 0) + { + byte digit = (byte)(value & 0xF); + *(--buffer) = TChar.CastFrom(digit + (digit < 10 ? (byte)'0' : hexBase)); + value >>= 4; + } + return buffer; +#endif + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe TChar* Int128ToHexChars(TChar* buffer, UInt128 value, int hexBase, int digits) + { + ulong lower = value.Lower; + ulong upper = value.Upper; + + if (upper != 0) + { + buffer = Int64ToHexChars(buffer, lower, hexBase, 16); + return Int64ToHexChars(buffer, upper, hexBase, digits - 16); + } + else + { + return Int64ToHexChars(buffer, lower, hexBase, Math.Max(digits, 1)); + } + } + + public static unsafe bool TryFormatDecimal(decimal value, ReadOnlySpan format, NumberFormatInfo info, Span destination, out int charsWritten) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + char fmt = Number.ParseFormatSpecifier(format, out int digits); + + byte* pDigits = stackalloc byte[Number.DecimalNumberBufferLength]; + Number.NumberBuffer number = new Number.NumberBuffer(Number.NumberBufferKind.Decimal, pDigits, Number.DecimalNumberBufferLength); + + Number.DecimalToNumber(ref value, ref number); + + TChar* stackPtr = stackalloc TChar[Number.CharStackBufferSize]; + var vlb = new ValueListBuilder(new Span(stackPtr, Number.CharStackBufferSize)); + + if (fmt != 0) + { + Number.NumberToString(ref vlb, ref number, fmt, digits, info); + } + else + { + Number.NumberToStringFormat(ref vlb, ref number, format, info); + } + + bool success = vlb.TryCopyTo(destination, out charsWritten); + vlb.Dispose(); + return success; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] // expose to caller's likely-const format to trim away slow path + public static bool TryFormatInt32(int value, int hexMask, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) + { + // Fast path for default format + if (format.Length == 0) + { + return value >= 0 ? + TryUInt32ToDecStr((uint)value, destination, out charsWritten) : + TryNegativeInt32ToDecStr(value, digits: -1, NumberFormatInfo.GetInstance(provider).NegativeSignTChar(), destination, out charsWritten); + } + + return TryFormatInt32Slow(value, hexMask, format, provider, destination, out charsWritten); + + static unsafe bool TryFormatInt32Slow(int value, int hexMask, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) + { + char fmt = Number.ParseFormatSpecifier(format, out int digits); + char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison + if (fmtUpper == 'G' ? digits < 1 : fmtUpper == 'D') + { + return value >= 0 ? + TryUInt32ToDecStr((uint)value, digits, destination, out charsWritten) : + TryNegativeInt32ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSignTChar(), destination, out charsWritten); + } + else if (fmtUpper == 'X') + { + return TryInt32ToHexStr(value & hexMask, Number.GetHexBase(fmt), digits, destination, out charsWritten); + } + else if (fmtUpper == 'B') + { + return TryUInt32ToBinaryStr((uint)(value & hexMask), digits, destination, out charsWritten); + } + else + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[Number.Int32NumberBufferLength]; + Number.NumberBuffer number = new Number.NumberBuffer(Number.NumberBufferKind.Integer, pDigits, Number.Int32NumberBufferLength); + + Number.Int32ToNumber(value, ref number); + + TChar* stackPtr = stackalloc TChar[Number.CharStackBufferSize]; + var vlb = new ValueListBuilder(new Span(stackPtr, Number.CharStackBufferSize)); + + if (fmt != 0) + { + Number.NumberToString(ref vlb, ref number, fmt, digits, info); + } + else + { + Number.NumberToStringFormat(ref vlb, ref number, format, info); + } + + bool success = vlb.TryCopyTo(destination, out charsWritten); + vlb.Dispose(); + return success; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] // expose to caller's likely-const format to trim away slow path + public static bool TryFormatInt64(long value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + // Fast path for default format + if (format.Length == 0) + { + return value >= 0 ? + TryUInt64ToDecStr((ulong)value, destination, out charsWritten) : + TryNegativeInt64ToDecStr(value, digits: -1, NumberFormatInfo.GetInstance(provider).NegativeSignTChar(), destination, out charsWritten); + } + + return TryFormatInt64Slow(value, format, provider, destination, out charsWritten); + + static unsafe bool TryFormatInt64Slow(long value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) + { + char fmt = Number.ParseFormatSpecifier(format, out int digits); + char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison + if (fmtUpper == 'G' ? digits < 1 : fmtUpper == 'D') + { + return value >= 0 ? + TryUInt64ToDecStr((ulong)value, digits, destination, out charsWritten) : + TryNegativeInt64ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSignTChar(), destination, out charsWritten); + } + else if (fmtUpper == 'X') + { + return TryInt64ToHexStr(value, Number.GetHexBase(fmt), digits, destination, out charsWritten); + } + else if (fmtUpper == 'B') + { + return TryUInt64ToBinaryStr((ulong)value, digits, destination, out charsWritten); + } + else + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[Number.Int64NumberBufferLength]; + Number.NumberBuffer number = new Number.NumberBuffer(Number.NumberBufferKind.Integer, pDigits, Number.Int64NumberBufferLength); + + Number.Int64ToNumber(value, ref number); + + char* stackPtr = stackalloc char[Number.CharStackBufferSize]; + var vlb = new ValueListBuilder(new Span(stackPtr, Number.CharStackBufferSize)); + + if (fmt != 0) + { + Number.NumberToString(ref vlb, ref number, fmt, digits, info); + } + else + { + Number.NumberToStringFormat(ref vlb, ref number, format, info); + } + + bool success = vlb.TryCopyTo(destination, out charsWritten); + vlb.Dispose(); + return success; + } + } + } + + public static bool TryFormatInt128(Int128 value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + // Fast path for default format + if (format.Length == 0) + { + return Int128.IsPositive(value) + ? TryUInt128ToDecStr((UInt128)value, digits: -1, destination, out charsWritten) + : TryNegativeInt128ToDecStr(value, digits: -1, NumberFormatInfo.GetInstance(provider).NegativeSignTChar(), destination, out charsWritten); + } + + return TryFormatInt128Slow(value, format, provider, destination, out charsWritten); + + static unsafe bool TryFormatInt128Slow(Int128 value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) + { + char fmt = Number.ParseFormatSpecifier(format, out int digits); + char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison + + if (fmtUpper == 'G' ? digits < 1 : fmtUpper == 'D') + { + return Int128.IsPositive(value) + ? TryUInt128ToDecStr((UInt128)value, digits, destination, out charsWritten) + : TryNegativeInt128ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSignTChar(), destination, out charsWritten); + } + else if (fmtUpper == 'X') + { + return TryInt128ToHexStr(value, Number.GetHexBase(fmt), digits, destination, out charsWritten); + } + else if (fmtUpper == 'B') + { + return TryUInt128ToBinaryStr(value, digits, destination, out charsWritten); + } + else + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[Number.Int128NumberBufferLength]; + Number.NumberBuffer number = new Number.NumberBuffer(Number.NumberBufferKind.Integer, pDigits, Number.Int128NumberBufferLength); + + Number.Int128ToNumber(value, ref number); + + TChar* stackPtr = stackalloc TChar[Number.CharStackBufferSize]; + var vlb = new ValueListBuilder(new Span(stackPtr, Number.CharStackBufferSize)); + + if (fmt != 0) + { + Number.NumberToString(ref vlb, ref number, fmt, digits, info); + } + else + { + Number.NumberToStringFormat(ref vlb, ref number, format, info); + } + + bool success = vlb.TryCopyTo(destination, out charsWritten); + vlb.Dispose(); + return success; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] // expose to caller's likely-const format to trim away slow path + public static bool TryFormatUInt32(uint value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + // Fast path for default format + if (format.Length == 0) + { + return TryUInt32ToDecStr(value, destination, out charsWritten); + } + + return TryFormatUInt32Slow(value, format, provider, destination, out charsWritten); + + static unsafe bool TryFormatUInt32Slow(uint value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) + { + char fmt = Number.ParseFormatSpecifier(format, out int digits); + char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison + if (fmtUpper == 'G' ? digits < 1 : fmtUpper == 'D') + { + return TryUInt32ToDecStr(value, digits, destination, out charsWritten); + } + else if (fmtUpper == 'X') + { + return TryInt32ToHexStr((int)value, Number.GetHexBase(fmt), digits, destination, out charsWritten); + } + else if (fmtUpper == 'B') + { + return TryUInt32ToBinaryStr(value, digits, destination, out charsWritten); + } + else + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[Number.UInt32NumberBufferLength]; + Number.NumberBuffer number = new Number.NumberBuffer(Number.NumberBufferKind.Integer, pDigits, Number.UInt32NumberBufferLength); + + Number.UInt32ToNumber(value, ref number); + + TChar* stackPtr = stackalloc TChar[Number.CharStackBufferSize]; + var vlb = new ValueListBuilder(new Span(stackPtr, Number.CharStackBufferSize)); + + if (fmt != 0) + { + Number.NumberToString(ref vlb, ref number, fmt, digits, info); + } + else + { + Number.NumberToStringFormat(ref vlb, ref number, format, info); + } + + bool success = vlb.TryCopyTo(destination, out charsWritten); + vlb.Dispose(); + return success; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] // expose to caller's likely-const format to trim away slow path + public static bool TryFormatUInt64(ulong value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + // Fast path for default format + if (format.Length == 0) + { + return TryUInt64ToDecStr(value, destination, out charsWritten); + } + + return TryFormatUInt64Slow(value, format, provider, destination, out charsWritten); + + static unsafe bool TryFormatUInt64Slow(ulong value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) + { + char fmt = Number.ParseFormatSpecifier(format, out int digits); + char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison + if (fmtUpper == 'G' ? digits < 1 : fmtUpper == 'D') + { + return TryUInt64ToDecStr(value, digits, destination, out charsWritten); + } + else if (fmtUpper == 'X') + { + return TryInt64ToHexStr((long)value, Number.GetHexBase(fmt), digits, destination, out charsWritten); + } + else if (fmtUpper == 'B') + { + return TryUInt64ToBinaryStr(value, digits, destination, out charsWritten); + } + else + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[Number.UInt64NumberBufferLength]; + Number.NumberBuffer number = new Number.NumberBuffer(Number.NumberBufferKind.Integer, pDigits, Number.UInt64NumberBufferLength); + + Number.UInt64ToNumber(value, ref number); + + TChar* stackPtr = stackalloc TChar[Number.CharStackBufferSize]; + var vlb = new ValueListBuilder(new Span(stackPtr, Number.CharStackBufferSize)); + + if (fmt != 0) + { + Number.NumberToString(ref vlb, ref number, fmt, digits, info); + } + else + { + Number.NumberToStringFormat(ref vlb, ref number, format, info); + } + + bool success = vlb.TryCopyTo(destination, out charsWritten); + vlb.Dispose(); + return success; + } + } + } + + public static bool TryFormatUInt128(UInt128 value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + // Fast path for default format + if (format.Length == 0) + { + return TryUInt128ToDecStr(value, digits: -1, destination, out charsWritten); + } + + return TryFormatUInt128Slow(value, format, provider, destination, out charsWritten); + + static unsafe bool TryFormatUInt128Slow(UInt128 value, ReadOnlySpan format, IFormatProvider? provider, Span destination, out int charsWritten) + { + char fmt = Number.ParseFormatSpecifier(format, out int digits); + char fmtUpper = (char)(fmt & 0xFFDF); // ensure fmt is upper-cased for purposes of comparison + + if (fmtUpper == 'G' ? digits < 1 : fmtUpper == 'D') + { + return TryUInt128ToDecStr(value, digits, destination, out charsWritten); + } + else if (fmtUpper == 'X') + { + return TryInt128ToHexStr((Int128)value, Number.GetHexBase(fmt), digits, destination, out charsWritten); + } + else if (fmtUpper == 'B') + { + return TryUInt128ToBinaryStr((Int128)value, digits, destination, out charsWritten); + } + else + { + NumberFormatInfo info = NumberFormatInfo.GetInstance(provider); + + byte* pDigits = stackalloc byte[Number.UInt128NumberBufferLength]; + Number.NumberBuffer number = new Number.NumberBuffer(Number.NumberBufferKind.Integer, pDigits, Number.UInt128NumberBufferLength); + + Number.UInt128ToNumber(value, ref number); + + TChar* stackPtr = stackalloc TChar[Number.CharStackBufferSize]; + var vlb = new ValueListBuilder(new Span(stackPtr, Number.CharStackBufferSize)); + + if (fmt != 0) + { + Number.NumberToString(ref vlb, ref number, fmt, digits, info); + } + else + { + Number.NumberToStringFormat(ref vlb, ref number, format, info); + } + + bool success = vlb.TryCopyTo(destination, out charsWritten); + vlb.Dispose(); + return success; + } + } + } + + public static unsafe bool TryInt32ToHexStr(int value, char hexBase, int digits, Span destination, out int charsWritten) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + if (digits < 1) + { + digits = 1; + } + + int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits((uint)value)); + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) + { + TChar* p = Int32ToHexChars(buffer + bufferLength, (uint)value, hexBase, digits); + Debug.Assert(p == buffer); + } + return true; + } + + public static unsafe bool TryInt64ToHexStr(long value, char hexBase, int digits, Span destination, out int charsWritten) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + if (digits < 1) + { + digits = 1; + } + + int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits((ulong)value)); + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) + { + TChar* p = Int64ToHexChars(buffer + bufferLength, (ulong)value, hexBase, digits); + Debug.Assert(p == buffer); + } + return true; + } + + public static unsafe bool TryInt128ToHexStr(Int128 value, char hexBase, int digits, Span destination, out int charsWritten) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + if (digits < 1) + { + digits = 1; + } + + UInt128 uValue = (UInt128)value; + + int bufferLength = Math.Max(digits, FormattingHelpers.CountHexDigits(uValue)); + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) + { + TChar* p = Int128ToHexChars(buffer + bufferLength, uValue, hexBase, digits); + Debug.Assert(p == buffer); + } + return true; + } + + public static unsafe bool TryNegativeInt32ToDecStr(int value, int digits, ReadOnlySpan sNegative, Span destination, out int charsWritten) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + Debug.Assert(value < 0); + + if (digits < 1) + { + digits = 1; + } + + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits((uint)(-value))) + sNegative.Length; + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) + { + TChar* p = UInt32ToDecChars(buffer + bufferLength, (uint)(-value), digits); + Debug.Assert(p == buffer + sNegative.Length); + + for (int i = sNegative.Length - 1; i >= 0; i--) + { + *(--p) = sNegative[i]; + } + Debug.Assert(p == buffer); + } + return true; + } + + public static unsafe bool TryNegativeInt64ToDecStr(long value, int digits, ReadOnlySpan sNegative, Span destination, out int charsWritten) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + Debug.Assert(value < 0); + + if (digits < 1) + { + digits = 1; + } + + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits((ulong)(-value))) + sNegative.Length; + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) + { + TChar* p = UInt64ToDecChars(buffer + bufferLength, (ulong)(-value), digits); + Debug.Assert(p == buffer + sNegative.Length); + + for (int i = sNegative.Length - 1; i >= 0; i--) + { + *(--p) = sNegative[i]; + } + Debug.Assert(p == buffer); + } + return true; + } + + public static unsafe bool TryNegativeInt128ToDecStr(Int128 value, int digits, ReadOnlySpan sNegative, Span destination, out int charsWritten) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + Debug.Assert(Int128.IsNegative(value)); + + if (digits < 1) + { + digits = 1; + } + + UInt128 absValue = (UInt128)(-value); + + int bufferLength = Math.Max(digits, FormattingHelpers.CountDigits(absValue)) + sNegative.Length; + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) + { + TChar* p = UInt128ToDecChars(buffer + bufferLength, absValue, digits); + Debug.Assert(p == buffer + sNegative.Length); + + for (int i = sNegative.Length - 1; i >= 0; i--) + { + *(--p) = sNegative[i]; + } + Debug.Assert(p == buffer); + } + return true; + } + + public static unsafe bool TryUInt32ToBinaryStr(uint value, int digits, Span destination, out int charsWritten) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + if (digits < 1) + { + digits = 1; + } + + int bufferLength = Math.Max(digits, 32 - (int)uint.LeadingZeroCount(value)); + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) + { + TChar* p = UInt32ToBinaryChars(buffer + bufferLength, value, digits); + Debug.Assert(p == buffer); + } + return true; + } + + public static unsafe bool TryUInt32ToDecStr(uint value, Span destination, out int charsWritten) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + int bufferLength = FormattingHelpers.CountDigits(value); + if (bufferLength <= destination.Length) + { + charsWritten = bufferLength; + fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) + { + TChar* p = UInt32ToDecChars(buffer + bufferLength, value); + Debug.Assert(p == buffer); + } + return true; + } + + charsWritten = 0; + return false; + } + + public static unsafe bool TryUInt32ToDecStr(uint value, int digits, Span destination, out int charsWritten) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + int countedDigits = FormattingHelpers.CountDigits(value); + int bufferLength = Math.Max(digits, countedDigits); + if (bufferLength <= destination.Length) + { + charsWritten = bufferLength; + fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) + { + TChar* p = buffer + bufferLength; + p = digits > countedDigits ? + UInt32ToDecChars(p, value, digits) : + UInt32ToDecChars(p, value); + Debug.Assert(p == buffer); + } + return true; + } + + charsWritten = 0; + return false; + } + + public static unsafe bool TryUInt64ToBinaryStr(ulong value, int digits, Span destination, out int charsWritten) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + if (digits < 1) + { + digits = 1; + } + + int bufferLength = Math.Max(digits, 64 - (int)ulong.LeadingZeroCount(value)); + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) + { + TChar* p = UInt64ToBinaryChars(buffer + bufferLength, value, digits); + Debug.Assert(p == buffer); + } + return true; + } + + public static unsafe bool TryUInt64ToDecStr(ulong value, Span destination, out int charsWritten) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + int bufferLength = FormattingHelpers.CountDigits(value); + if (bufferLength <= destination.Length) + { + charsWritten = bufferLength; + fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) + { + TChar* p = buffer + bufferLength; + p = UInt64ToDecChars(p, value); + Debug.Assert(p == buffer); + } + return true; + } + + charsWritten = 0; + return false; + } + + public static unsafe bool TryUInt64ToDecStr(ulong value, int digits, Span destination, out int charsWritten) + { + int countedDigits = FormattingHelpers.CountDigits(value); + int bufferLength = Math.Max(digits, countedDigits); + if (bufferLength <= destination.Length) + { + charsWritten = bufferLength; + fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) + { + TChar* p = buffer + bufferLength; + p = digits > countedDigits ? + UInt64ToDecChars(p, value, digits) : + UInt64ToDecChars(p, value); + Debug.Assert(p == buffer); + } + return true; + } + + charsWritten = 0; + return false; + } + + public static unsafe bool TryUInt128ToBinaryStr(Int128 value, int digits, Span destination, out int charsWritten) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + if (digits < 1) + { + digits = 1; + } + + UInt128 uValue = (UInt128)value; + + int bufferLength = Math.Max(digits, 128 - (int)UInt128.LeadingZeroCount((UInt128)value)); + if (bufferLength > destination.Length) + { + charsWritten = 0; + return false; + } + + charsWritten = bufferLength; + fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) + { + TChar* p = UInt128ToBinaryChars(buffer + bufferLength, uValue, digits); + Debug.Assert(p == buffer); + } + return true; + } + + public static unsafe bool TryUInt128ToDecStr(UInt128 value, int digits, Span destination, out int charsWritten) + { + int countedDigits = FormattingHelpers.CountDigits(value); + int bufferLength = Math.Max(digits, countedDigits); + if (bufferLength <= destination.Length) + { + charsWritten = bufferLength; + fixed (TChar* buffer = &MemoryMarshal.GetReference(destination)) + { + TChar* p = buffer + bufferLength; + p = digits > countedDigits ? + UInt128ToDecChars(p, value, digits) : + UInt128ToDecChars(p, value); + Debug.Assert(p == buffer); + } + return true; + } + + charsWritten = 0; + return false; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe TChar* UInt32ToBinaryChars(TChar* buffer, uint value, int digits) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + while (--digits >= 0 || value != 0) + { + *(--buffer) = TChar.CastFrom('0' + (byte)(value & 0x1)); + value >>= 1; + } + return buffer; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe TChar* UInt32ToDecChars(TChar* bufferEnd, uint value) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + if (value >= 10) + { + // Handle all values >= 100 two-digits at a time so as to avoid expensive integer division operations. + while (value >= 100) + { + bufferEnd -= 2; + (value, uint remainder) = Math.DivRem(value, 100); + WriteTwoDigits(remainder, bufferEnd); + } + + // If there are two digits remaining, store them. + if (value >= 10) + { + bufferEnd -= 2; + WriteTwoDigits(value, bufferEnd); + return bufferEnd; + } + } + + // Otherwise, store the single digit remaining. + *(--bufferEnd) = TChar.CastFrom(value + '0'); + return bufferEnd; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe TChar* UInt32ToDecChars(TChar* bufferEnd, uint value, int digits) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + uint remainder; + while (value >= 100) + { + bufferEnd -= 2; + digits -= 2; + (value, remainder) = Math.DivRem(value, 100); + WriteTwoDigits(remainder, bufferEnd); + } + + while (value != 0 || digits > 0) + { + digits--; + (value, remainder) = Math.DivRem(value, 10); + *(--bufferEnd) = TChar.CastFrom(remainder + '0'); + } + + return bufferEnd; + } + +#if TARGET_64BIT + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public static unsafe TChar* UInt64ToBinaryChars(TChar* buffer, ulong value, int digits) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); +#if TARGET_32BIT + uint lower = (uint)value; + uint upper = (uint)(value >> 32); + + if (upper != 0) + { + buffer = UInt32ToBinaryChars(buffer, lower, 32); + return UInt32ToBinaryChars(buffer, upper, digits - 32); + } + else + { + return UInt32ToBinaryChars(buffer, lower, Math.Max(digits, 1)); + } +#else + while (--digits >= 0 || value != 0) + { + *(--buffer) = TChar.CastFrom('0' + (byte)(value & 0x1)); + value >>= 1; + } + return buffer; +#endif + } + +#if TARGET_64BIT + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public static unsafe TChar* UInt64ToDecChars(TChar* bufferEnd, ulong value) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + +#if TARGET_32BIT + while ((uint)(value >> 32) != 0) + { + bufferEnd = UInt32ToDecChars(bufferEnd, Number.Int64DivMod1E9(ref value), 9); + } + return UInt32ToDecChars(bufferEnd, (uint)value); +#else + if (value >= 10) + { + // Handle all values >= 100 two-digits at a time so as to avoid expensive integer division operations. + while (value >= 100) + { + bufferEnd -= 2; + (value, ulong remainder) = Math.DivRem(value, 100); + WriteTwoDigits((uint)remainder, bufferEnd); + } + + // If there are two digits remaining, store them. + if (value >= 10) + { + bufferEnd -= 2; + WriteTwoDigits((uint)value, bufferEnd); + return bufferEnd; + } + } + + // Otherwise, store the single digit remaining. + *(--bufferEnd) = TChar.CastFrom(value + '0'); + return bufferEnd; +#endif + } + +#if TARGET_64BIT + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public static unsafe TChar* UInt64ToDecChars(TChar* bufferEnd, ulong value, int digits) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + +#if TARGET_32BIT + while ((uint)(value >> 32) != 0) + { + bufferEnd = UInt32ToDecChars(bufferEnd, Number.Int64DivMod1E9(ref value), 9); + digits -= 9; + } + return UInt32ToDecChars(bufferEnd, (uint)value, digits); +#else + ulong remainder; + while (value >= 100) + { + bufferEnd -= 2; + digits -= 2; + (value, remainder) = Math.DivRem(value, 100); + WriteTwoDigits((uint)remainder, bufferEnd); + } + + while (value != 0 || digits > 0) + { + digits--; + (value, remainder) = Math.DivRem(value, 10); + *(--bufferEnd) = TChar.CastFrom(remainder + '0'); + } + + return bufferEnd; +#endif + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe TChar* UInt128ToBinaryChars(TChar* buffer, UInt128 value, int digits) + { + ulong lower = value.Lower; + ulong upper = value.Upper; + + if (upper != 0) + { + buffer = UInt64ToBinaryChars(buffer, lower, 64); + return UInt64ToBinaryChars(buffer, upper, digits - 64); + } + else + { + return UInt64ToBinaryChars(buffer, lower, Math.Max(digits, 1)); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe TChar* UInt128ToDecChars(TChar* bufferEnd, UInt128 value) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + while (value.Upper != 0) + { + bufferEnd = UInt64ToDecChars(bufferEnd, Number.Int128DivMod1E19(ref value), 19); + } + return UInt64ToDecChars(bufferEnd, value.Lower); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe TChar* UInt128ToDecChars(TChar* bufferEnd, UInt128 value, int digits) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + + while (value.Upper != 0) + { + bufferEnd = UInt64ToDecChars(bufferEnd, Number.Int128DivMod1E19(ref value), 19); + digits -= 19; + } + return UInt64ToDecChars(bufferEnd, value.Lower, digits); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void WriteDigits(uint value, TChar* ptr, int count) + { + TChar* cur; + for (cur = ptr + count - 1; cur > ptr; cur--) + { + uint temp = '0' + value; + value /= 10; + *cur = TChar.CastFrom(temp - (value * 10)); + } + + Debug.Assert(value < 10); + Debug.Assert(cur == ptr); + *cur = TChar.CastFrom('0' + value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void WriteTwoDigits(uint value, TChar* ptr) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + Debug.Assert(value <= 99); + + Unsafe.CopyBlockUnaligned( + ref *(byte*)ptr, + ref Unsafe.Add(ref Number.GetTwoDigitsBytesRef(typeof(TChar) == typeof(char)), (uint)sizeof(TChar) * 2 * value), + (uint)sizeof(TChar) * 2); + } + + /// + /// Writes a value [ 0000 .. 9999 ] to the buffer starting at the specified offset. + /// This method performs best when the starting index is a constant literal. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void WriteFourDigits(uint value, TChar* ptr) + { + Debug.Assert(typeof(TChar) == typeof(char) || typeof(TChar) == typeof(byte)); + Debug.Assert(value <= 9999); + + (value, uint remainder) = Math.DivRem(value, 100); + + ref byte charsArray = ref Number.GetTwoDigitsBytesRef(typeof(TChar) == typeof(char)); + + Unsafe.CopyBlockUnaligned( + ref *(byte*)ptr, + ref Unsafe.Add(ref charsArray, (uint)sizeof(TChar) * 2 * value), + (uint)sizeof(TChar) * 2); + + Unsafe.CopyBlockUnaligned( + ref *(byte*)(ptr + 2), + ref Unsafe.Add(ref charsArray, (uint)sizeof(TChar) * 2 * remainder), + (uint)sizeof(TChar) * 2); + } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/SByte.cs b/src/libraries/System.Private.CoreLib/src/System/SByte.cs index 4ba9c4372de61b..6cf018dc68dbfe 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SByte.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SByte.cs @@ -120,13 +120,13 @@ public string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] strin public bool TryFormat(Span destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatInt32(m_value, 0x000000FF, format, provider, destination, out charsWritten); + return NumberFormat.TryFormatInt32(m_value, 0x000000FF, format, provider, destination, out charsWritten); } /// public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatInt32(m_value, 0x000000FF, format, provider, utf8Destination, out bytesWritten); + return NumberFormat.TryFormatInt32(m_value, 0x000000FF, format, provider, utf8Destination, out bytesWritten); } public static sbyte Parse(string s) => Parse(s, NumberStyles.Integer, provider: null); diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt128.cs b/src/libraries/System.Private.CoreLib/src/System/UInt128.cs index b76e5a04f5ce11..2bdc57359cf7fd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UInt128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UInt128.cs @@ -119,13 +119,13 @@ public string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] strin public bool TryFormat(Span destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatUInt128(this, format, provider, destination, out charsWritten); + return NumberFormat.TryFormatUInt128(this, format, provider, destination, out charsWritten); } /// public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatUInt128(this, format, provider, utf8Destination, out bytesWritten); + return NumberFormat.TryFormatUInt128(this, format, provider, utf8Destination, out bytesWritten); } public static UInt128 Parse(string s) => Parse(s, NumberStyles.Integer, provider: null); diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt16.cs b/src/libraries/System.Private.CoreLib/src/System/UInt16.cs index 87d4f12a9a10d9..9de88c60d743a1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UInt16.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UInt16.cs @@ -112,13 +112,13 @@ public string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] strin public bool TryFormat(Span destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatUInt32(m_value, format, provider, destination, out charsWritten); + return NumberFormat.TryFormatUInt32(m_value, format, provider, destination, out charsWritten); } /// public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatUInt32(m_value, format, provider, utf8Destination, out bytesWritten); + return NumberFormat.TryFormatUInt32(m_value, format, provider, utf8Destination, out bytesWritten); } public static ushort Parse(string s) => Parse(s, NumberStyles.Integer, provider: null); diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt32.cs b/src/libraries/System.Private.CoreLib/src/System/UInt32.cs index a774069fb560b2..5fcdf44b5d33a2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UInt32.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UInt32.cs @@ -128,13 +128,13 @@ public string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] strin public bool TryFormat(Span destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatUInt32(m_value, format, provider, destination, out charsWritten); + return NumberFormat.TryFormatUInt32(m_value, format, provider, destination, out charsWritten); } /// public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatUInt32(m_value, format, provider, utf8Destination, out bytesWritten); + return NumberFormat.TryFormatUInt32(m_value, format, provider, utf8Destination, out bytesWritten); } public static uint Parse(string s) => Parse(s, NumberStyles.Integer, provider: null); diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt64.cs b/src/libraries/System.Private.CoreLib/src/System/UInt64.cs index 56d9fc2cc2015a..f88dc9da9d5513 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UInt64.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UInt64.cs @@ -127,13 +127,13 @@ public string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] strin public bool TryFormat(Span destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatUInt64(m_value, format, provider, destination, out charsWritten); + return NumberFormat.TryFormatUInt64(m_value, format, provider, destination, out charsWritten); } /// public bool TryFormat(Span utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) { - return Number.TryFormatUInt64(m_value, format, provider, utf8Destination, out bytesWritten); + return NumberFormat.TryFormatUInt64(m_value, format, provider, utf8Destination, out bytesWritten); } public static ulong Parse(string s) => Parse(s, NumberStyles.Integer, provider: null);