Decompiled source of ZString v2.6.1

BepInEx/core/ZString/netstandard2.1/ZString.dll

Decompiled 5 months ago
using System;
using System.Buffers;
using System.Buffers.Text;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("ConsoleApp, PublicKey=00240000048000009400000006020000002400005253413100040000010001000144ec28f1e9ef7b17dacc47425a7a153aea0a7baa590743a2d1a86f4b3e10a8a12712c6e647966bfd8bd6e830048b23bd42bbc56f179585c15b8c19cf86c0eed1b73c993dd7a93a30051dd50fdda0e4d6b65e6874e30f1c37cf8bcbc7fe02c7f2e6a0a3327c0ccc1631bf645f40732521fa0b41a30c178d08f7dd779d42a1ee")]
[assembly: InternalsVisibleTo("ConsoleAppNet472, PublicKey=00240000048000009400000006020000002400005253413100040000010001000144ec28f1e9ef7b17dacc47425a7a153aea0a7baa590743a2d1a86f4b3e10a8a12712c6e647966bfd8bd6e830048b23bd42bbc56f179585c15b8c19cf86c0eed1b73c993dd7a93a30051dd50fdda0e4d6b65e6874e30f1c37cf8bcbc7fe02c7f2e6a0a3327c0ccc1631bf645f40732521fa0b41a30c178d08f7dd779d42a1ee")]
[assembly: InternalsVisibleTo("ZString.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001000144ec28f1e9ef7b17dacc47425a7a153aea0a7baa590743a2d1a86f4b3e10a8a12712c6e647966bfd8bd6e830048b23bd42bbc56f179585c15b8c19cf86c0eed1b73c993dd7a93a30051dd50fdda0e4d6b65e6874e30f1c37cf8bcbc7fe02c7f2e6a0a3327c0ccc1631bf645f40732521fa0b41a30c178d08f7dd779d42a1ee")]
[assembly: InternalsVisibleTo("ZString.NetCore2Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001000144ec28f1e9ef7b17dacc47425a7a153aea0a7baa590743a2d1a86f4b3e10a8a12712c6e647966bfd8bd6e830048b23bd42bbc56f179585c15b8c19cf86c0eed1b73c993dd7a93a30051dd50fdda0e4d6b65e6874e30f1c37cf8bcbc7fe02c7f2e6a0a3327c0ccc1631bf645f40732521fa0b41a30c178d08f7dd779d42a1ee")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Cysharp")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("© Cysharp, Inc.")]
[assembly: AssemblyDescription("Zero allocation StringBuilder for .NET Core and Unity.")]
[assembly: AssemblyFileVersion("2.6.0.0")]
[assembly: AssemblyInformationalVersion("2.6.0+3156134075b89a162fe95350a2e92a4c85ccca59")]
[assembly: AssemblyProduct("ZString")]
[assembly: AssemblyTitle("ZString")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Cysharp/ZString")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.6.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace System
{
	internal static class BufferEx
	{
		internal unsafe static void ZeroMemory(byte* dest, uint len)
		{
			if (len != 0)
			{
				for (int i = 0; i < len; i++)
				{
					dest[i] = 0;
				}
			}
		}

		internal unsafe static void Memcpy(byte* dest, byte* src, int len)
		{
			if (len != 0)
			{
				for (int i = 0; i < len; i++)
				{
					dest[i] = src[i];
				}
			}
		}
	}
	internal static class DecimalEx
	{
		[StructLayout(LayoutKind.Explicit)]
		private struct DecimalBits
		{
			[FieldOffset(0)]
			public int flags;

			[FieldOffset(4)]
			public int hi;

			[FieldOffset(8)]
			public int lo;

			[FieldOffset(12)]
			public int mid;
		}

		[StructLayout(LayoutKind.Explicit)]
		private struct DecCalc
		{
			private const uint TenToPowerNine = 1000000000u;

			[FieldOffset(0)]
			public uint uflags;

			[FieldOffset(4)]
			public uint uhi;

			[FieldOffset(8)]
			public uint ulo;

			[FieldOffset(12)]
			public uint umid;

			[FieldOffset(8)]
			private ulong ulomidLE;

			internal static uint DecDivMod1E9(ref DecCalc value)
			{
				ulong num = ((ulong)value.uhi << 32) + value.umid;
				ulong num2 = num / 1000000000;
				value.uhi = (uint)(num2 >> 32);
				value.umid = (uint)num2;
				ulong num3 = (num - (uint)((int)num2 * 1000000000) << 32) + value.ulo;
				return (uint)(int)num3 - (value.ulo = (uint)(num3 / 1000000000)) * 1000000000;
			}
		}

		private const int ScaleShift = 16;

		private static ref DecCalc AsMutable(ref decimal d)
		{
			return ref Unsafe.As<decimal, DecCalc>(ref d);
		}

		internal static uint High(this decimal value)
		{
			return Unsafe.As<decimal, DecCalc>(ref value).uhi;
		}

		internal static uint Low(this decimal value)
		{
			return Unsafe.As<decimal, DecCalc>(ref value).ulo;
		}

		internal static uint Mid(this decimal value)
		{
			return Unsafe.As<decimal, DecCalc>(ref value).umid;
		}

		internal static bool IsNegative(this decimal value)
		{
			return Unsafe.As<decimal, DecimalBits>(ref value).flags < 0;
		}

		internal static int Scale(this decimal value)
		{
			return (byte)(Unsafe.As<decimal, DecimalBits>(ref value).flags >> 16);
		}

		internal static uint DecDivMod1E9(ref decimal value)
		{
			return DecCalc.DecDivMod1E9(ref AsMutable(ref value));
		}
	}
	internal static class FloatEx
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsFinite(double d)
		{
			return (BitConverter.DoubleToInt64Bits(d) & 0x7FFFFFFFFFFFFFFFL) < 9218868437227405312L;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsNegative(double d)
		{
			return BitConverter.DoubleToInt64Bits(d) < 0;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsFinite(float f)
		{
			return (SingleToInt32Bits(f) & 0x7FFFFFFF) < 2139095040;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsNegative(float f)
		{
			return SingleToInt32Bits(f) < 0;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static int SingleToInt32Bits(float value)
		{
			return *(int*)(&value);
		}
	}
	internal struct GuidEx
	{
		private int _a;

		private short _b;

		private short _c;

		private byte _d;

		private byte _e;

		private byte _f;

		private byte _g;

		private byte _h;

		private byte _i;

		private byte _j;

		private byte _k;

		private unsafe static int HexsToChars(char* guidChars, int a, int b)
		{
			*guidChars = System.HexConverter.ToCharLower(a >> 4);
			guidChars[1] = System.HexConverter.ToCharLower(a);
			guidChars[2] = System.HexConverter.ToCharLower(b >> 4);
			guidChars[3] = System.HexConverter.ToCharLower(b);
			return 4;
		}

		private unsafe static int HexsToCharsHexOutput(char* guidChars, int a, int b)
		{
			*guidChars = '0';
			guidChars[1] = 'x';
			guidChars[2] = System.HexConverter.ToCharLower(a >> 4);
			guidChars[3] = System.HexConverter.ToCharLower(a);
			guidChars[4] = ',';
			guidChars[5] = '0';
			guidChars[6] = 'x';
			guidChars[7] = System.HexConverter.ToCharLower(b >> 4);
			guidChars[8] = System.HexConverter.ToCharLower(b);
			return 9;
		}

		public unsafe bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format = default(ReadOnlySpan<char>))
		{
			if (format.Length == 0)
			{
				format = "D".AsSpan();
			}
			if (format.Length != 1)
			{
				throw new FormatException("InvalidGuidFormatSpecification");
			}
			bool flag = true;
			bool flag2 = false;
			int num = 0;
			int num2;
			switch (format[0])
			{
			case 'D':
			case 'd':
				num2 = 36;
				break;
			case 'N':
			case 'n':
				flag = false;
				num2 = 32;
				break;
			case 'B':
			case 'b':
				num = 8192123;
				num2 = 38;
				break;
			case 'P':
			case 'p':
				num = 2687016;
				num2 = 38;
				break;
			case 'X':
			case 'x':
				num = 8192123;
				flag = false;
				flag2 = true;
				num2 = 68;
				break;
			default:
				throw new FormatException("InvalidGuidFormatSpecification");
			}
			if (destination.Length < num2)
			{
				charsWritten = 0;
				return false;
			}
			fixed (char* ptr = &MemoryMarshal.GetReference(destination))
			{
				char* ptr2 = ptr;
				if (num != 0)
				{
					*(ptr2++) = (char)num;
				}
				if (flag2)
				{
					*(ptr2++) = '0';
					*(ptr2++) = 'x';
					ptr2 += HexsToChars(ptr2, _a >> 24, _a >> 16);
					ptr2 += HexsToChars(ptr2, _a >> 8, _a);
					*(ptr2++) = ',';
					*(ptr2++) = '0';
					*(ptr2++) = 'x';
					ptr2 += HexsToChars(ptr2, _b >> 8, _b);
					*(ptr2++) = ',';
					*(ptr2++) = '0';
					*(ptr2++) = 'x';
					ptr2 += HexsToChars(ptr2, _c >> 8, _c);
					*(ptr2++) = ',';
					*(ptr2++) = '{';
					ptr2 += HexsToCharsHexOutput(ptr2, _d, _e);
					*(ptr2++) = ',';
					ptr2 += HexsToCharsHexOutput(ptr2, _f, _g);
					*(ptr2++) = ',';
					ptr2 += HexsToCharsHexOutput(ptr2, _h, _i);
					*(ptr2++) = ',';
					ptr2 += HexsToCharsHexOutput(ptr2, _j, _k);
					*(ptr2++) = '}';
				}
				else
				{
					ptr2 += HexsToChars(ptr2, _a >> 24, _a >> 16);
					ptr2 += HexsToChars(ptr2, _a >> 8, _a);
					if (flag)
					{
						*(ptr2++) = '-';
					}
					ptr2 += HexsToChars(ptr2, _b >> 8, _b);
					if (flag)
					{
						*(ptr2++) = '-';
					}
					ptr2 += HexsToChars(ptr2, _c >> 8, _c);
					if (flag)
					{
						*(ptr2++) = '-';
					}
					ptr2 += HexsToChars(ptr2, _d, _e);
					if (flag)
					{
						*(ptr2++) = '-';
					}
					ptr2 += HexsToChars(ptr2, _f, _g);
					ptr2 += HexsToChars(ptr2, _h, _i);
					ptr2 += HexsToChars(ptr2, _j, _k);
				}
				if (num != 0)
				{
					*(ptr2++) = (char)(num >> 16);
				}
			}
			charsWritten = num2;
			return true;
		}
	}
	internal static class HexConverter
	{
		public enum Casing : uint
		{
			Upper = 0u,
			Lower = 8224u
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void ToBytesBuffer(byte value, Span<byte> buffer, int startingIndex = 0, Casing casing = Casing.Upper)
		{
			uint num = (uint)(((value & 0xF0) << 4) + (value & 0xF) - 35209);
			uint num2 = ((((0 - num) & 0x7070) >> 4) + num + 47545) | (uint)casing;
			buffer[startingIndex + 1] = (byte)num2;
			buffer[startingIndex] = (byte)(num2 >> 8);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void ToCharsBuffer(byte value, Span<char> buffer, int startingIndex = 0, Casing casing = Casing.Upper)
		{
			uint num = (uint)(((value & 0xF0) << 4) + (value & 0xF) - 35209);
			uint num2 = ((((0 - num) & 0x7070) >> 4) + num + 47545) | (uint)casing;
			buffer[startingIndex + 1] = (char)(num2 & 0xFFu);
			buffer[startingIndex] = (char)(num2 >> 8);
		}

		public static string ToString(ReadOnlySpan<byte> bytes, Casing casing = Casing.Upper)
		{
			Span<char> span = default(Span<char>);
			span = ((bytes.Length <= 16) ? stackalloc char[bytes.Length * 2] : new char[bytes.Length * 2].AsSpan());
			int num = 0;
			ReadOnlySpan<byte> readOnlySpan = bytes;
			for (int i = 0; i < readOnlySpan.Length; i++)
			{
				ToCharsBuffer(readOnlySpan[i], span, num, casing);
				num += 2;
			}
			return span.ToString();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static char ToCharUpper(int value)
		{
			value &= 0xF;
			value += 48;
			if (value > 57)
			{
				value += 7;
			}
			return (char)value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static char ToCharLower(int value)
		{
			value &= 0xF;
			value += 48;
			if (value > 57)
			{
				value += 39;
			}
			return (char)value;
		}
	}
	internal static class InternalSpanEx
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static bool EqualsOrdinalIgnoreCase(this ReadOnlySpan<char> span, ReadOnlySpan<char> value)
		{
			if (span.Length != value.Length)
			{
				return false;
			}
			if (value.Length == 0)
			{
				return true;
			}
			return EqualsOrdinalIgnoreCase(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(value), span.Length);
		}

		private static bool EqualsOrdinalIgnoreCase(ref char charA, ref char charB, int length)
		{
			IntPtr zero = IntPtr.Zero;
			if (IntPtr.Size == 8)
			{
				while ((uint)length >= 4u)
				{
					ulong num = Unsafe.ReadUnaligned<ulong>(ref Unsafe.As<char, byte>(ref Unsafe.AddByteOffset(ref charA, zero)));
					ulong num2 = Unsafe.ReadUnaligned<ulong>(ref Unsafe.As<char, byte>(ref Unsafe.AddByteOffset(ref charB, zero)));
					ulong num3 = num | num2;
					if (AllCharsInUInt32AreAscii((uint)((int)num3 | (int)(num3 >> 32))))
					{
						if (!UInt64OrdinalIgnoreCaseAscii(num, num2))
						{
							return false;
						}
						zero += 8;
						length -= 4;
						continue;
					}
					goto IL_0101;
				}
			}
			while (true)
			{
				switch (length)
				{
				default:
				{
					uint num6 = Unsafe.ReadUnaligned<uint>(ref Unsafe.As<char, byte>(ref Unsafe.AddByteOffset(ref charA, zero)));
					uint num7 = Unsafe.ReadUnaligned<uint>(ref Unsafe.As<char, byte>(ref Unsafe.AddByteOffset(ref charB, zero)));
					if (AllCharsInUInt32AreAscii(num6 | num7))
					{
						if (UInt32OrdinalIgnoreCaseAscii(num6, num7))
						{
							goto IL_00aa;
						}
						return false;
					}
					break;
				}
				case 1:
				{
					uint num4 = Unsafe.AddByteOffset(ref charA, zero);
					uint num5 = Unsafe.AddByteOffset(ref charB, zero);
					if ((num4 | num5) <= 127)
					{
						if (num4 == num5)
						{
							return true;
						}
						num4 |= 0x20u;
						if (num4 - 97 > 25)
						{
							return false;
						}
						return num4 == (num5 | 0x20);
					}
					break;
				}
				case 0:
					return true;
				}
				break;
				IL_00aa:
				zero += 4;
				length -= 2;
			}
			goto IL_0101;
			IL_0101:
			return EqualsOrdinalIgnoreCaseNonAscii(ref Unsafe.AddByteOffset(ref charA, zero), ref Unsafe.AddByteOffset(ref charB, zero), length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static bool AllCharsInUInt32AreAscii(uint value)
		{
			return (value & 0xFF80FF80u) == 0;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static bool AllCharsInUInt64AreAscii(ulong value)
		{
			return (value & 0xFF80FF80FF80FF80uL) == 0;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static bool UInt32OrdinalIgnoreCaseAscii(uint valueA, uint valueB)
		{
			uint num = valueA ^ valueB;
			uint num2 = valueA + 16777472 - 4259905;
			uint num3 = (valueA | 0x200020) + 8388736 - 8061051;
			return ((((num2 | num3) >> 2) | 0xFFDFFFDFu) & num) == 0;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static bool UInt64OrdinalIgnoreCaseAscii(ulong valueA, ulong valueB)
		{
			ulong num = valueA + 36029346783166592L - 18296152663326785L;
			ulong num2 = (valueA | 0x20002000200020L) + 72058693566333184L - 34621950424449147L;
			ulong num3 = (0x80008000800080L & num & num2) >> 2;
			return (valueA | num3) == (valueB | num3);
		}

		private static bool EqualsOrdinalIgnoreCaseNonAscii(ref char charA, ref char charB, int length)
		{
			IntPtr zero = IntPtr.Zero;
			while (length != 0)
			{
				uint num = Unsafe.AddByteOffset(ref charA, zero);
				uint num2 = Unsafe.AddByteOffset(ref charB, zero);
				if (num == num2 || ((num | 0x20) == (num2 | 0x20) && (num | 0x20) - 97 <= 25))
				{
					zero += 2;
					length--;
					continue;
				}
				return false;
			}
			return true;
		}
	}
	internal static class MathEx
	{
		public static uint DivRem(uint a, uint b, out uint result)
		{
			uint num = a / b;
			result = a - num * b;
			return num;
		}

		public static ulong DivRem(ulong a, ulong b, out ulong result)
		{
			ulong num = a / b;
			result = a - num * b;
			return num;
		}

		public static int DivRem(int a, int b, out int result)
		{
			int num = a / b;
			result = a - num * b;
			return num;
		}

		public static long DivRem(long a, long b, out long result)
		{
			long num = a / b;
			result = a - num * b;
			return num;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static byte Clamp(byte value, byte min, byte max)
		{
			if (min > max)
			{
				ThrowMinMaxException(min, max);
			}
			if (value < min)
			{
				return min;
			}
			if (value > max)
			{
				return max;
			}
			return value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static decimal Clamp(decimal value, decimal min, decimal max)
		{
			if (min > max)
			{
				ThrowMinMaxException(min, max);
			}
			if (value < min)
			{
				return min;
			}
			if (value > max)
			{
				return max;
			}
			return value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static double Clamp(double value, double min, double max)
		{
			if (min > max)
			{
				ThrowMinMaxException(min, max);
			}
			if (value < min)
			{
				return min;
			}
			if (value > max)
			{
				return max;
			}
			return value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static short Clamp(short value, short min, short max)
		{
			if (min > max)
			{
				ThrowMinMaxException(min, max);
			}
			if (value < min)
			{
				return min;
			}
			if (value > max)
			{
				return max;
			}
			return value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int Clamp(int value, int min, int max)
		{
			if (min > max)
			{
				ThrowMinMaxException(min, max);
			}
			if (value < min)
			{
				return min;
			}
			if (value > max)
			{
				return max;
			}
			return value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static long Clamp(long value, long min, long max)
		{
			if (min > max)
			{
				ThrowMinMaxException(min, max);
			}
			if (value < min)
			{
				return min;
			}
			if (value > max)
			{
				return max;
			}
			return value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static sbyte Clamp(sbyte value, sbyte min, sbyte max)
		{
			if (min > max)
			{
				ThrowMinMaxException(min, max);
			}
			if (value < min)
			{
				return min;
			}
			if (value > max)
			{
				return max;
			}
			return value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Clamp(float value, float min, float max)
		{
			if (min > max)
			{
				ThrowMinMaxException(min, max);
			}
			if (value < min)
			{
				return min;
			}
			if (value > max)
			{
				return max;
			}
			return value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ushort Clamp(ushort value, ushort min, ushort max)
		{
			if (min > max)
			{
				ThrowMinMaxException(min, max);
			}
			if (value < min)
			{
				return min;
			}
			if (value > max)
			{
				return max;
			}
			return value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static uint Clamp(uint value, uint min, uint max)
		{
			if (min > max)
			{
				ThrowMinMaxException(min, max);
			}
			if (value < min)
			{
				return min;
			}
			if (value > max)
			{
				return max;
			}
			return value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ulong Clamp(ulong value, ulong min, ulong max)
		{
			if (min > max)
			{
				ThrowMinMaxException(min, max);
			}
			if (value < min)
			{
				return min;
			}
			if (value > max)
			{
				return max;
			}
			return value;
		}

		private static void ThrowMinMaxException<T>(T min, T max)
		{
			throw new ArgumentException($"Argument_MinMaxValue, min:{min} max:{max}");
		}
	}
	internal static class Number
	{
		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		internal ref struct BigInteger
		{
			private const int BitsForLongestBinaryMantissa = 1074;

			private const int BitsForLongestDigitSequence = 2552;

			private const int MaxBits = 3658;

			private const int BitsPerBlock = 32;

			private const int MaxBlockCount = 115;

			private static readonly uint[] s_Pow10UInt32Table = new uint[8] { 1u, 10u, 100u, 1000u, 10000u, 100000u, 1000000u, 10000000u };

			private static readonly int[] s_Pow10BigNumTableIndices = new int[8] { 0, 2, 5, 10, 18, 33, 61, 116 };

			private static readonly uint[] s_Pow10BigNumTable = new uint[233]
			{
				1u, 100000000u, 2u, 1874919424u, 2328306u, 4u, 0u, 2242703233u, 762134875u, 1262u,
				7u, 0u, 0u, 3211403009u, 1849224548u, 3668416493u, 3913284084u, 1593091u, 14u, 0u,
				0u, 0u, 0u, 781532673u, 64985353u, 253049085u, 594863151u, 3553621484u, 3288652808u, 3167596762u,
				2788392729u, 3911132675u, 590u, 27u, 0u, 0u, 0u, 0u, 0u, 0u,
				0u, 0u, 2553183233u, 3201533787u, 3638140786u, 303378311u, 1809731782u, 3477761648u, 3583367183u, 649228654u,
				2915460784u, 487929380u, 1011012442u, 1677677582u, 3428152256u, 1710878487u, 1438394610u, 2161952759u, 4100910556u, 1608314830u,
				349175u, 54u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
				0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4234999809u, 2012377703u,
				2408924892u, 1570150255u, 3090844311u, 3273530073u, 1187251475u, 2498123591u, 3364452033u, 1148564857u, 687371067u, 2854068671u,
				1883165473u, 505794538u, 2988060450u, 3159489326u, 2531348317u, 3215191468u, 849106862u, 3892080979u, 3288073877u, 2242451748u,
				4183778142u, 2995818208u, 2477501924u, 325481258u, 2487842652u, 1774082830u, 1933815724u, 2962865281u, 1168579910u, 2724829000u,
				2360374019u, 2315984659u, 2360052375u, 3251779801u, 1664357844u, 28u, 107u, 0u, 0u, 0u,
				0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
				0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
				0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 689565697u,
				4116392818u, 1853628763u, 516071302u, 2568769159u, 365238920u, 336250165u, 1283268122u, 3425490969u, 248595470u, 2305176814u,
				2111925499u, 507770399u, 2681111421u, 589114268u, 591287751u, 1708941527u, 4098957707u, 475844916u, 3378731398u, 2452339615u,
				2817037361u, 2678008327u, 1656645978u, 2383430340u, 73103988u, 448667107u, 2329420453u, 3124020241u, 3625235717u, 3208634035u,
				2412059158u, 2981664444u, 4117622508u, 838560765u, 3069470027u, 270153238u, 1802868219u, 3692709886u, 2161737865u, 2159912357u,
				2585798786u, 837488486u, 4237238160u, 2540319504u, 3798629246u, 3748148874u, 1021550776u, 2386715342u, 1973637538u, 1823520457u,
				1146713475u, 833971519u, 3277251466u, 905620390u, 26278816u, 2680483154u, 2294040859u, 373297482u, 5996609u, 4109575006u,
				512575049u, 917036550u, 1942311753u, 2816916778u, 3248920332u, 1192784020u, 3537586671u, 2456567643u, 2925660628u, 759380297u,
				888447942u, 3559939476u, 3654687237u, 805u, 0u, 0u, 0u, 0u, 0u, 0u,
				0u, 0u, 0u
			};

			private int _length;

			private unsafe fixed uint _blocks[115];

			public unsafe static void Add(ref BigInteger lhs, ref BigInteger rhs, out BigInteger result)
			{
				ref BigInteger reference = ref lhs._length < rhs._length ? ref rhs : ref lhs;
				ref BigInteger reference2 = ref lhs._length < rhs._length ? ref lhs : ref rhs;
				int length = reference._length;
				int length2 = reference2._length;
				result._length = length;
				ulong num = 0uL;
				int num2 = 0;
				int num3 = 0;
				int num4 = 0;
				while (num3 < length2)
				{
					ulong num5 = num + reference._blocks[num2] + reference2._blocks[num3];
					num = num5 >> 32;
					result._blocks[num4] = (uint)num5;
					num2++;
					num3++;
					num4++;
				}
				while (num2 < length)
				{
					ulong num6 = num + reference._blocks[num2];
					num = num6 >> 32;
					result._blocks[num4] = (uint)num6;
					num2++;
					num4++;
				}
				if (num != 0L)
				{
					result._blocks[num4] = 1u;
					result._length++;
				}
			}

			public unsafe static int Compare(ref BigInteger lhs, ref BigInteger rhs)
			{
				int length = lhs._length;
				int length2 = rhs._length;
				int num = length - length2;
				if (num != 0)
				{
					return num;
				}
				if (length == 0)
				{
					return 0;
				}
				for (int num2 = length - 1; num2 >= 0; num2--)
				{
					long num3 = (long)lhs._blocks[num2] - (long)rhs._blocks[num2];
					if (num3 != 0L)
					{
						if (num3 <= 0)
						{
							return -1;
						}
						return 1;
					}
				}
				return 0;
			}

			public static uint CountSignificantBits(uint value)
			{
				return (uint)(32 - BitOperations.LeadingZeroCount(value));
			}

			public static uint CountSignificantBits(ulong value)
			{
				return (uint)(64 - BitOperations.LeadingZeroCount(value));
			}

			public unsafe static uint CountSignificantBits(ref BigInteger value)
			{
				if (value.IsZero())
				{
					return 0u;
				}
				uint num = (uint)(value._length - 1);
				return num * 32 + CountSignificantBits(value._blocks[num]);
			}

			public unsafe static void DivRem(ref BigInteger lhs, ref BigInteger rhs, out BigInteger quo, out BigInteger rem)
			{
				if (lhs.IsZero())
				{
					SetZero(out quo);
					SetZero(out rem);
					return;
				}
				int length = lhs._length;
				int length2 = rhs._length;
				if (length == 1 && length2 == 1)
				{
					uint result;
					uint value = MathEx.DivRem(lhs._blocks[0], rhs._blocks[0], out result);
					SetUInt32(out quo, value);
					SetUInt32(out rem, result);
					return;
				}
				if (length2 == 1)
				{
					int num = length;
					ulong b = rhs._blocks[0];
					ulong result2 = 0uL;
					for (int num2 = num - 1; num2 >= 0; num2--)
					{
						ulong num3 = MathEx.DivRem((result2 << 32) | lhs._blocks[num2], b, out result2);
						if (num3 == 0L && num2 == num - 1)
						{
							num--;
						}
						else
						{
							quo._blocks[num2] = (uint)num3;
						}
					}
					quo._length = num;
					SetUInt32(out rem, (uint)result2);
					return;
				}
				if (length2 > length)
				{
					SetZero(out quo);
					SetValue(out rem, ref lhs);
					return;
				}
				int num4 = length - length2 + 1;
				SetValue(out rem, ref lhs);
				int num5 = length;
				uint num6 = rhs._blocks[length2 - 1];
				uint num7 = rhs._blocks[length2 - 2];
				int num8 = BitOperations.LeadingZeroCount(num6);
				int num9 = 32 - num8;
				if (num8 > 0)
				{
					num6 = (num6 << num8) | (num7 >> num9);
					num7 <<= num8;
					if (length2 > 2)
					{
						num7 |= rhs._blocks[length2 - 3] >> num9;
					}
				}
				for (int num10 = length; num10 >= length2; num10--)
				{
					int num11 = num10 - length2;
					uint num12 = ((num10 < length) ? rem._blocks[num10] : 0u);
					ulong num13 = ((ulong)num12 << 32) | rem._blocks[num10 - 1];
					uint num14 = ((num10 > 1) ? rem._blocks[num10 - 2] : 0u);
					if (num8 > 0)
					{
						num13 = (num13 << num8) | (num14 >> num9);
						num14 <<= num8;
						if (num10 > 2)
						{
							num14 |= rem._blocks[num10 - 3] >> num9;
						}
					}
					ulong num15 = num13 / num6;
					if (num15 > uint.MaxValue)
					{
						num15 = 4294967295uL;
					}
					while (DivideGuessTooBig(num15, num13, num14, num6, num7))
					{
						num15--;
					}
					if (num15 != 0 && SubtractDivisor(ref rem, num11, ref rhs, num15) != num12)
					{
						AddDivisor(ref rem, num11, ref rhs);
						num15--;
					}
					if (num4 != 0)
					{
						if (num15 == 0L && num11 == num4 - 1)
						{
							num4--;
						}
						else
						{
							quo._blocks[num11] = (uint)num15;
						}
					}
					if (num10 < num5)
					{
						num5--;
					}
				}
				quo._length = num4;
				for (int num16 = num5 - 1; num16 >= 0; num16--)
				{
					if (rem._blocks[num16] == 0)
					{
						num5--;
					}
				}
				rem._length = num5;
			}

			public unsafe static uint HeuristicDivide(ref BigInteger dividend, ref BigInteger divisor)
			{
				int num = divisor._length;
				if (dividend._length < num)
				{
					return 0u;
				}
				int num2 = num - 1;
				uint num3 = dividend._blocks[num2] / (divisor._blocks[num2] + 1);
				if (num3 != 0)
				{
					int num4 = 0;
					ulong num5 = 0uL;
					ulong num6 = 0uL;
					do
					{
						ulong num7 = (ulong)((long)divisor._blocks[num4] * (long)num3) + num6;
						num6 = num7 >> 32;
						ulong num8 = (ulong)((long)dividend._blocks[num4] - (long)(uint)num7) - num5;
						num5 = (num8 >> 32) & 1;
						dividend._blocks[num4] = (uint)num8;
						num4++;
					}
					while (num4 < num);
					while (num > 0 && dividend._blocks[num - 1] == 0)
					{
						num--;
					}
					dividend._length = num;
				}
				if (Compare(ref dividend, ref divisor) >= 0)
				{
					num3++;
					int num9 = 0;
					ulong num10 = 0uL;
					do
					{
						ulong num11 = (ulong)((long)dividend._blocks[num9] - (long)divisor._blocks[num9]) - num10;
						num10 = (num11 >> 32) & 1;
						dividend._blocks[num9] = (uint)num11;
						num9++;
					}
					while (num9 < num);
					while (num > 0 && dividend._blocks[num - 1] == 0)
					{
						num--;
					}
					dividend._length = num;
				}
				return num3;
			}

			public unsafe static void Multiply(ref BigInteger lhs, uint value, out BigInteger result)
			{
				if (!lhs.IsZero())
				{
					switch (value)
					{
					case 1u:
						break;
					case 0u:
						SetZero(out result);
						return;
					default:
					{
						int length = lhs._length;
						int i = 0;
						uint num = 0u;
						for (; i < length; i++)
						{
							ulong num2 = (ulong)((long)lhs._blocks[i] * (long)value + num);
							result._blocks[i] = (uint)num2;
							num = (uint)(num2 >> 32);
						}
						if (num != 0)
						{
							result._blocks[i] = num;
							result._length = length + 1;
						}
						else
						{
							result._length = length;
						}
						return;
					}
					}
				}
				SetValue(out result, ref lhs);
			}

			public unsafe static void Multiply(ref BigInteger lhs, ref BigInteger rhs, out BigInteger result)
			{
				if (lhs.IsZero() || rhs.IsOne())
				{
					SetValue(out result, ref lhs);
					return;
				}
				if (rhs.IsZero())
				{
					SetZero(out result);
					return;
				}
				ref BigInteger reference = ref lhs;
				int length = lhs._length;
				ref BigInteger reference2 = ref rhs;
				int length2 = rhs._length;
				if (length < length2)
				{
					reference = ref rhs;
					length = rhs._length;
					reference2 = ref lhs;
					length2 = lhs._length;
				}
				int num = (result._length = length2 + length);
				BufferEx.ZeroMemory((byte*)result.GetBlocksPointer(), (uint)(num * 4));
				int num2 = 0;
				int num3 = 0;
				while (num2 < length2)
				{
					if (reference2._blocks[num2] != 0)
					{
						int num4 = 0;
						int num5 = num3;
						ulong num6 = 0uL;
						do
						{
							ulong num7 = (ulong)(result._blocks[num5] + (long)reference2._blocks[num2] * (long)reference._blocks[num4]) + num6;
							num6 = num7 >> 32;
							result._blocks[num5] = (uint)num7;
							num5++;
							num4++;
						}
						while (num4 < length);
						result._blocks[num5] = (uint)num6;
					}
					num2++;
					num3++;
				}
				if (num > 0 && result._blocks[num - 1] == 0)
				{
					result._length--;
				}
			}

			public unsafe static void Pow2(uint exponent, out BigInteger result)
			{
				uint remainder;
				uint num = DivRem32(exponent, out remainder);
				result._length = (int)(num + 1);
				if (num != 0)
				{
					BufferEx.ZeroMemory((byte*)result.GetBlocksPointer(), num * 4);
				}
				result._blocks[num] = (uint)(1 << (int)remainder);
			}

			public unsafe static void Pow10(uint exponent, out BigInteger result)
			{
				SetUInt32(out var result2, s_Pow10UInt32Table[exponent & 7]);
				ref BigInteger reference = ref result2;
				SetZero(out var result3);
				ref BigInteger reference2 = ref result3;
				exponent >>= 3;
				uint num = 0u;
				while (exponent != 0)
				{
					if ((exponent & (true ? 1u : 0u)) != 0)
					{
						fixed (uint* ptr = &s_Pow10BigNumTable[s_Pow10BigNumTableIndices[num]])
						{
							Multiply(ref reference, ref *(BigInteger*)ptr, out reference2);
						}
						ref BigInteger reference3 = ref reference2;
						reference2 = ref reference;
						reference = ref reference3;
					}
					num++;
					exponent >>= 1;
				}
				SetValue(out result, ref reference);
			}

			private unsafe static uint AddDivisor(ref BigInteger lhs, int lhsStartIndex, ref BigInteger rhs)
			{
				int length = rhs._length;
				ulong num = 0uL;
				for (int i = 0; i < length; i++)
				{
					ref uint reference = ref lhs._blocks[lhsStartIndex + i];
					ulong num2 = reference + num + rhs._blocks[i];
					reference = (uint)num2;
					num = num2 >> 32;
				}
				return (uint)num;
			}

			private static bool DivideGuessTooBig(ulong q, ulong valHi, uint valLo, uint divHi, uint divLo)
			{
				ulong num = divHi * q;
				ulong num2 = divLo * q;
				num += num2 >> 32;
				num2 &= 0xFFFFFFFFu;
				if (num < valHi)
				{
					return false;
				}
				if (num > valHi)
				{
					return true;
				}
				if (num2 < valLo)
				{
					return false;
				}
				if (num2 > valLo)
				{
					return true;
				}
				return false;
			}

			private unsafe static uint SubtractDivisor(ref BigInteger lhs, int lhsStartIndex, ref BigInteger rhs, ulong q)
			{
				int length = rhs._length;
				ulong num = 0uL;
				for (int i = 0; i < length; i++)
				{
					num += rhs._blocks[i] * q;
					uint num2 = (uint)num;
					num >>= 32;
					ref uint reference = ref lhs._blocks[lhsStartIndex + i];
					if (reference < num2)
					{
						num++;
					}
					reference -= num2;
				}
				return (uint)num;
			}

			public unsafe void Add(uint value)
			{
				int length = _length;
				if (length == 0)
				{
					SetUInt32(out this, value);
					return;
				}
				_blocks[0] += value;
				if (_blocks[0] >= value)
				{
					return;
				}
				for (int i = 1; i < length; i++)
				{
					ref uint reference = ref _blocks[i];
					reference++;
					if (_blocks[i] != 0)
					{
						return;
					}
				}
				_blocks[length] = 1u;
				_length = length + 1;
			}

			public unsafe uint GetBlock(uint index)
			{
				return _blocks[index];
			}

			public int GetLength()
			{
				return _length;
			}

			public unsafe bool IsOne()
			{
				if (_length == 1)
				{
					return _blocks[0] == 1;
				}
				return false;
			}

			public bool IsZero()
			{
				return _length == 0;
			}

			public void Multiply(uint value)
			{
				Multiply(ref this, value, out this);
			}

			public void Multiply(ref BigInteger value)
			{
				SetValue(out var result, ref this);
				Multiply(ref result, ref value, out this);
			}

			public unsafe void Multiply10()
			{
				if (!IsZero())
				{
					int i = 0;
					int length = _length;
					ulong num = 0uL;
					for (; i < length; i++)
					{
						ulong num2 = _blocks[i];
						ulong num3 = (num2 << 3) + (num2 << 1) + num;
						num = num3 >> 32;
						_blocks[i] = (uint)num3;
					}
					if (num != 0L)
					{
						_blocks[i] = (uint)num;
						_length++;
					}
				}
			}

			public unsafe void MultiplyPow10(uint exponent)
			{
				if (!IsZero())
				{
					Pow10(exponent, out var result);
					if (result._length == 1)
					{
						Multiply(result._blocks[0]);
					}
					else
					{
						Multiply(ref result);
					}
				}
			}

			public unsafe static void SetUInt32(out BigInteger result, uint value)
			{
				if (value == 0)
				{
					SetZero(out result);
					return;
				}
				result._blocks[0] = value;
				result._length = 1;
			}

			public unsafe static void SetUInt64(out BigInteger result, ulong value)
			{
				if (value <= uint.MaxValue)
				{
					SetUInt32(out result, (uint)value);
					return;
				}
				result._blocks[0] = (uint)value;
				result._blocks[1] = (uint)(value >> 32);
				result._length = 2;
			}

			public unsafe static void SetValue(out BigInteger result, ref BigInteger value)
			{
				BufferEx.Memcpy(len: (result._length = value._length) * 4, dest: (byte*)result.GetBlocksPointer(), src: (byte*)value.GetBlocksPointer());
			}

			public static void SetZero(out BigInteger result)
			{
				result._length = 0;
			}

			public unsafe void ShiftLeft(uint shift)
			{
				int length = _length;
				if (length == 0 || shift == 0)
				{
					return;
				}
				uint remainder;
				uint num = DivRem32(shift, out remainder);
				int num2 = length - 1;
				int num3 = num2 + (int)num;
				if (remainder == 0)
				{
					while (num2 >= 0)
					{
						_blocks[num3] = _blocks[num2];
						num2--;
						num3--;
					}
					_length += (int)num;
					BufferEx.ZeroMemory((byte*)GetBlocksPointer(), num * 4);
					return;
				}
				num3++;
				_length = num3 + 1;
				uint num4 = 32 - remainder;
				uint num5 = 0u;
				uint num6 = _blocks[num2];
				uint num7 = num6 >> (int)num4;
				while (num2 > 0)
				{
					_blocks[num3] = num5 | num7;
					num5 = num6 << (int)remainder;
					num2--;
					num3--;
					num6 = _blocks[num2];
					num7 = num6 >> (int)num4;
				}
				_blocks[num3] = num5 | num7;
				_blocks[num3 - 1] = num6 << (int)remainder;
				BufferEx.ZeroMemory((byte*)GetBlocksPointer(), num * 4);
				if (_blocks[_length - 1] == 0)
				{
					_length--;
				}
			}

			public unsafe ulong ToUInt64()
			{
				if (_length > 1)
				{
					return ((ulong)_blocks[1] << 32) + _blocks[0];
				}
				if (_length > 0)
				{
					return _blocks[0];
				}
				return 0uL;
			}

			private unsafe uint* GetBlocksPointer()
			{
				return (uint*)Unsafe.AsPointer(ref _blocks[0]);
			}

			private static uint DivRem32(uint value, out uint remainder)
			{
				remainder = value & 0x1Fu;
				return value >> 5;
			}
		}

		internal readonly ref struct DiyFp
		{
			public const int DoubleImplicitBitIndex = 52;

			public const int SingleImplicitBitIndex = 23;

			public const int SignificandSize = 64;

			public readonly ulong f;

			public readonly int e;

			public static DiyFp CreateAndGetBoundaries(double value, out DiyFp mMinus, out DiyFp mPlus)
			{
				DiyFp result = new DiyFp(value);
				result.GetBoundaries(52, out mMinus, out mPlus);
				return result;
			}

			public static DiyFp CreateAndGetBoundaries(float value, out DiyFp mMinus, out DiyFp mPlus)
			{
				DiyFp result = new DiyFp(value);
				result.GetBoundaries(23, out mMinus, out mPlus);
				return result;
			}

			public DiyFp(double value)
			{
				f = ExtractFractionAndBiasedExponent(value, out e);
			}

			public DiyFp(float value)
			{
				f = ExtractFractionAndBiasedExponent(value, out e);
			}

			public DiyFp(ulong f, int e)
			{
				this.f = f;
				this.e = e;
			}

			public DiyFp Multiply(in DiyFp other)
			{
				int num = (int)(f >> 32);
				uint num2 = (uint)f;
				uint num3 = (uint)(other.f >> 32);
				uint num4 = (uint)other.f;
				ulong num5 = (ulong)(uint)num * (ulong)num3;
				ulong num6 = (ulong)num2 * (ulong)num3;
				ulong num7 = (ulong)(uint)num * (ulong)num4;
				ulong num8 = (ulong)(((long)num2 * (long)num4 >>> 32) + (uint)num7 + (uint)num6);
				num8 += 2147483648u;
				return new DiyFp(num5 + (num7 >> 32) + (num6 >> 32) + (num8 >> 32), e + other.e + 64);
			}

			public DiyFp Normalize()
			{
				int num = BitOperations.LeadingZeroCount(f);
				return new DiyFp(f << num, e - num);
			}

			public DiyFp Subtract(in DiyFp other)
			{
				return new DiyFp(f - other.f, e);
			}

			private void GetBoundaries(int implicitBitIndex, out DiyFp mMinus, out DiyFp mPlus)
			{
				mPlus = new DiyFp((f << 1) + 1, e - 1).Normalize();
				if (f == (ulong)(1L << implicitBitIndex))
				{
					mMinus = new DiyFp((f << 2) - 1, e - 2);
				}
				else
				{
					mMinus = new DiyFp((f << 1) - 1, e - 1);
				}
				mMinus = new DiyFp(mMinus.f << mMinus.e - mPlus.e, mPlus.e);
			}
		}

		internal static class Grisu3
		{
			private const int CachedPowersDecimalExponentDistance = 8;

			private const int CachedPowersMinDecimalExponent = -348;

			private const int CachedPowersPowerMaxDecimalExponent = 340;

			private const int CachedPowersOffset = 348;

			private const double D1Log210 = 0.3010299956639812;

			private const int MaximalTargetExponent = -32;

			private const int MinimalTargetExponent = -60;

			private static readonly short[] s_CachedPowersBinaryExponent = new short[87]
			{
				-1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980,
				-954, -927, -901, -874, -847, -821, -794, -768, -741, -715,
				-688, -661, -635, -608, -582, -555, -529, -502, -475, -449,
				-422, -396, -369, -343, -316, -289, -263, -236, -210, -183,
				-157, -130, -103, -77, -50, -24, 3, 30, 56, 83,
				109, 136, 162, 189, 216, 242, 269, 295, 322, 348,
				375, 402, 428, 455, 481, 508, 534, 561, 588, 614,
				641, 667, 694, 720, 747, 774, 800, 827, 853, 880,
				907, 933, 960, 986, 1013, 1039, 1066
			};

			private static readonly short[] s_CachedPowersDecimalExponent = new short[87]
			{
				-348, -340, -332, -324, -316, -308, -300, -292, -284, -276,
				-268, -260, -252, -244, -236, -228, -220, -212, -204, -196,
				-188, -180, -172, -164, -156, -148, -140, -132, -124, -116,
				-108, -100, -92, -84, -76, -68, -60, -52, -44, -36,
				-28, -20, -12, -4, 4, 12, 20, 28, 36, 44,
				52, 60, 68, 76, 84, 92, 100, 108, 116, 124,
				132, 140, 148, 156, 164, 172, 180, 188, 196, 204,
				212, 220, 228, 236, 244, 252, 260, 268, 276, 284,
				292, 300, 308, 316, 324, 332, 340
			};

			private static readonly ulong[] s_CachedPowersSignificand = new ulong[87]
			{
				18054884314459144840uL, 13451937075301367670uL, 10022474136428063862uL, 14934650266808366570uL, 11127181549972568877uL, 16580792590934885855uL, 12353653155963782858uL, 18408377700990114895uL, 13715310171984221708uL, 10218702384817765436uL,
				15227053142812498563uL, 11345038669416679861uL, 16905424996341287883uL, 12595523146049147757uL, 9384396036005875287uL, 13983839803942852151uL, 10418772551374772303uL, 15525180923007089351uL, 11567161174868858868uL, 17236413322193710309uL,
				12842128665889583758uL, 9568131466127621947uL, 14257626930069360058uL, 10622759856335341974uL, 15829145694278690180uL, 11793632577567316726uL, 17573882009934360870uL, 13093562431584567480uL, 9755464219737475723uL, 14536774485912137811uL,
				10830740992659433045uL, 16139061738043178685uL, 12024538023802026127uL, 17917957937422433684uL, 13349918974505688015uL, 9946464728195732843uL, 14821387422376473014uL, 11042794154864902060uL, 16455045573212060422uL, 12259964326927110867uL,
				18268770466636286478uL, 13611294676837538539uL, 10141204801825835212uL, 15111572745182864684uL, 11258999068426240000uL, 16777216000000000000uL, 12500000000000000000uL, 9313225746154785156uL, 13877787807814456755uL, 10339757656912845936uL,
				15407439555097886824uL, 11479437019748901445uL, 17105694144590052135uL, 12744735289059618216uL, 9495567745759798747uL, 14149498560666738074uL, 10542197943230523224uL, 15709099088952724970uL, 11704190886730495818uL, 17440603504673385349uL,
				12994262207056124023uL, 9681479787123295682uL, 14426529090290212157uL, 10748601772107342003uL, 16016664761464807395uL, 11933345169920330789uL, 17782069995880619868uL, 13248674568444952270uL, 9871031767461413346uL, 14708983551653345445uL,
				10959046745042015199uL, 16330252207878254650uL, 12166986024289022870uL, 18130221999122236476uL, 13508068024458167312uL, 10064294952495520794uL, 14996968138956309548uL, 11173611982879273257uL, 16649979327439178909uL, 12405201291620119593uL,
				9242595204427927429uL, 13772540099066387757uL, 10261342003245940623uL, 15290591125556738113uL, 11392378155556871081uL, 16975966327722178521uL, 12648080533535911531uL
			};

			private static readonly uint[] s_SmallPowersOfTen = new uint[10] { 1u, 10u, 100u, 1000u, 10000u, 100000u, 1000000u, 10000000u, 100000000u, 1000000000u };

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			private static bool IsNegative(double d)
			{
				return BitConverter.DoubleToInt64Bits(d) < 0;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			private static bool IsNegativeInfinity(float f)
			{
				return f == float.NegativeInfinity;
			}

			public static bool TryRunDouble(double value, int requestedDigits, ref NumberBuffer number)
			{
				double value2 = (IsNegative(value) ? (0.0 - value) : value);
				DiyFp diyFp;
				bool flag;
				int length;
				int decimalExponent;
				if (requestedDigits == -1)
				{
					diyFp = DiyFp.CreateAndGetBoundaries(value2, out var mMinus, out var mPlus);
					DiyFp w = diyFp.Normalize();
					flag = TryRunShortest(in mMinus, in w, in mPlus, number.Digits, out length, out decimalExponent);
				}
				else
				{
					diyFp = new DiyFp(value2);
					DiyFp w2 = diyFp.Normalize();
					flag = TryRunCounted(in w2, requestedDigits, number.Digits, out length, out decimalExponent);
				}
				if (flag)
				{
					number.Scale = length + decimalExponent;
					number.Digits[length] = 0;
					number.DigitsCount = length;
				}
				return flag;
			}

			public static bool TryRunSingle(float value, int requestedDigits, ref NumberBuffer number)
			{
				float value2 = (IsNegative(value) ? (0f - value) : value);
				DiyFp diyFp;
				bool flag;
				int length;
				int decimalExponent;
				if (requestedDigits == -1)
				{
					diyFp = DiyFp.CreateAndGetBoundaries(value2, out var mMinus, out var mPlus);
					DiyFp w = diyFp.Normalize();
					flag = TryRunShortest(in mMinus, in w, in mPlus, number.Digits, out length, out decimalExponent);
				}
				else
				{
					diyFp = new DiyFp(value2);
					DiyFp w2 = diyFp.Normalize();
					flag = TryRunCounted(in w2, requestedDigits, number.Digits, out length, out decimalExponent);
				}
				if (flag)
				{
					number.Scale = length + decimalExponent;
					number.Digits[length] = 0;
					number.DigitsCount = length;
				}
				return flag;
			}

			private static bool TryRunCounted(in DiyFp w, int requestedDigits, Span<byte> buffer, out int length, out int decimalExponent)
			{
				int minExponent = -60 - (w.e + 64);
				int maxExponent = -32 - (w.e + 64);
				int decimalExponent2;
				DiyFp other = GetCachedPowerForBinaryExponentRange(minExponent, maxExponent, out decimalExponent2);
				DiyFp w2 = w.Multiply(in other);
				int kappa;
				bool result = TryDigitGenCounted(in w2, requestedDigits, buffer, out length, out kappa);
				decimalExponent = -decimalExponent2 + kappa;
				return result;
			}

			private static bool TryRunShortest(in DiyFp boundaryMinus, in DiyFp w, in DiyFp boundaryPlus, Span<byte> buffer, out int length, out int decimalExponent)
			{
				int minExponent = -60 - (w.e + 64);
				int maxExponent = -32 - (w.e + 64);
				int decimalExponent2;
				DiyFp other = GetCachedPowerForBinaryExponentRange(minExponent, maxExponent, out decimalExponent2);
				DiyFp w2 = w.Multiply(in other);
				DiyFp low = boundaryMinus.Multiply(in other);
				DiyFp high = boundaryPlus.Multiply(in other);
				int kappa;
				bool result = TryDigitGenShortest(in low, in w2, in high, buffer, out length, out kappa);
				decimalExponent = -decimalExponent2 + kappa;
				return result;
			}

			private static uint BiggestPowerTen(uint number, int numberBits, out int exponentPlusOne)
			{
				int num = (numberBits + 1) * 1233 >> 12;
				uint num2 = s_SmallPowersOfTen[num];
				if (number < num2)
				{
					num--;
					num2 = s_SmallPowersOfTen[num];
				}
				exponentPlusOne = num + 1;
				return num2;
			}

			private static bool TryDigitGenCounted(in DiyFp w, int requestedDigits, Span<byte> buffer, out int length, out int kappa)
			{
				ulong num = 1uL;
				DiyFp diyFp = new DiyFp((ulong)(1L << -w.e), w.e);
				uint result = (uint)(w.f >> -diyFp.e);
				ulong num2 = w.f & (diyFp.f - 1);
				if (num2 == 0L && (requestedDigits >= 11 || result < s_SmallPowersOfTen[requestedDigits - 1]))
				{
					length = 0;
					kappa = 0;
					return false;
				}
				uint num3 = BiggestPowerTen(result, 64 - -diyFp.e, out kappa);
				length = 0;
				while (kappa > 0)
				{
					uint num4 = MathEx.DivRem(result, num3, out result);
					buffer[length] = (byte)(48 + num4);
					length++;
					requestedDigits--;
					kappa--;
					if (requestedDigits == 0)
					{
						break;
					}
					num3 /= 10;
				}
				if (requestedDigits == 0)
				{
					ulong rest = ((ulong)result << -diyFp.e) + num2;
					return TryRoundWeedCounted(buffer, length, rest, (ulong)num3 << -diyFp.e, num, ref kappa);
				}
				while (requestedDigits > 0 && num2 > num)
				{
					num2 *= 10;
					num *= 10;
					uint num5 = (uint)(num2 >> -diyFp.e);
					buffer[length] = (byte)(48 + num5);
					length++;
					requestedDigits--;
					kappa--;
					num2 &= diyFp.f - 1;
				}
				if (requestedDigits != 0)
				{
					buffer[0] = 0;
					length = 0;
					kappa = 0;
					return false;
				}
				return TryRoundWeedCounted(buffer, length, num2, diyFp.f, num, ref kappa);
			}

			private static bool TryDigitGenShortest(in DiyFp low, in DiyFp w, in DiyFp high, Span<byte> buffer, out int length, out int kappa)
			{
				ulong num = 1uL;
				DiyFp other = new DiyFp(low.f - num, low.e);
				DiyFp diyFp = new DiyFp(high.f + num, high.e);
				DiyFp diyFp2 = diyFp.Subtract(in other);
				DiyFp diyFp3 = new DiyFp((ulong)(1L << -w.e), w.e);
				uint result = (uint)(diyFp.f >> -diyFp3.e);
				ulong num2 = diyFp.f & (diyFp3.f - 1);
				uint num3 = BiggestPowerTen(result, 64 - -diyFp3.e, out kappa);
				length = 0;
				while (kappa > 0)
				{
					uint num4 = MathEx.DivRem(result, num3, out result);
					buffer[length] = (byte)(48 + num4);
					length++;
					kappa--;
					ulong num5 = ((ulong)result << -diyFp3.e) + num2;
					if (num5 < diyFp2.f)
					{
						return TryRoundWeedShortest(buffer, length, diyFp.Subtract(in w).f, diyFp2.f, num5, (ulong)num3 << -diyFp3.e, num);
					}
					num3 /= 10;
				}
				do
				{
					num2 *= 10;
					num *= 10;
					diyFp2 = new DiyFp(diyFp2.f * 10, diyFp2.e);
					uint num6 = (uint)(num2 >> -diyFp3.e);
					buffer[length] = (byte)(48 + num6);
					length++;
					kappa--;
					num2 &= diyFp3.f - 1;
				}
				while (num2 >= diyFp2.f);
				return TryRoundWeedShortest(buffer, length, diyFp.Subtract(in w).f * num, diyFp2.f, num2, diyFp3.f, num);
			}

			private static DiyFp GetCachedPowerForBinaryExponentRange(int minExponent, int maxExponent, out int decimalExponent)
			{
				double num = Math.Ceiling((double)(minExponent + 64 - 1) * 0.3010299956639812);
				int num2 = (348 + (int)num - 1) / 8 + 1;
				decimalExponent = s_CachedPowersDecimalExponent[num2];
				return new DiyFp(s_CachedPowersSignificand[num2], s_CachedPowersBinaryExponent[num2]);
			}

			private static bool TryRoundWeedCounted(Span<byte> buffer, int length, ulong rest, ulong tenKappa, ulong unit, ref int kappa)
			{
				if (unit >= tenKappa || tenKappa - unit <= unit)
				{
					return false;
				}
				if (tenKappa - rest > rest && tenKappa - 2 * rest >= 2 * unit)
				{
					return true;
				}
				if (rest > unit && (tenKappa <= rest - unit || tenKappa - (rest - unit) <= rest - unit))
				{
					buffer[length - 1]++;
					int num = length - 1;
					while (num > 0 && buffer[num] == 58)
					{
						buffer[num] = 48;
						buffer[num - 1]++;
						num--;
					}
					if (buffer[0] == 58)
					{
						buffer[0] = 49;
						kappa++;
					}
					return true;
				}
				return false;
			}

			private static bool TryRoundWeedShortest(Span<byte> buffer, int length, ulong distanceTooHighW, ulong unsafeInterval, ulong rest, ulong tenKappa, ulong unit)
			{
				ulong num = distanceTooHighW - unit;
				ulong num2 = distanceTooHighW + unit;
				while (rest < num && unsafeInterval - rest >= tenKappa && (rest + tenKappa < num || num - rest >= rest + tenKappa - num))
				{
					buffer[length - 1]--;
					rest += tenKappa;
				}
				if (rest < num2 && unsafeInterval - rest >= tenKappa && (rest + tenKappa < num2 || num2 - rest > rest + tenKappa - num2))
				{
					return false;
				}
				if (2 * unit <= rest)
				{
					return rest <= unsafeInterval - 4 * unit;
				}
				return false;
			}
		}

		internal ref struct NumberBuffer
		{
			public int DigitsCount;

			public int Scale;

			public bool IsNegative;

			public bool HasNonZeroTail;

			public NumberBufferKind Kind;

			public Span<byte> Digits;

			public unsafe NumberBuffer(NumberBufferKind kind, byte* digits, int digitsLength)
			{
				DigitsCount = 0;
				Scale = 0;
				IsNegative = false;
				HasNonZeroTail = false;
				Kind = kind;
				Digits = new Span<byte>(digits, digitsLength);
				Digits[0] = 0;
			}

			[Conditional("DEBUG")]
			public void CheckConsistency()
			{
			}

			public unsafe byte* GetDigitsPointer()
			{
				return (byte*)Unsafe.AsPointer(ref Digits[0]);
			}

			public override string ToString()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append('[');
				stringBuilder.Append('"');
				for (int i = 0; i < Digits.Length; i++)
				{
					byte b = Digits[i];
					if (b == 0)
					{
						break;
					}
					stringBuilder.Append((char)b);
				}
				stringBuilder.Append('"');
				stringBuilder.Append(", Length = ").Append(DigitsCount);
				stringBuilder.Append(", Scale = ").Append(Scale);
				stringBuilder.Append(", IsNegative = ").Append(IsNegative);
				stringBuilder.Append(", HasNonZeroTail = ").Append(HasNonZeroTail);
				stringBuilder.Append(", Kind = ").Append(Kind);
				stringBuilder.Append(']');
				return stringBuilder.ToString();
			}
		}

		internal enum NumberBufferKind : byte
		{
			Unknown,
			Integer,
			Decimal,
			FloatingPoint
		}

		public readonly struct FloatingPointInfo
		{
			public static readonly FloatingPointInfo Double = new FloatingPointInfo(52, 11, 1023, 1023, 9218868437227405312uL);

			public static readonly FloatingPointInfo Single = new FloatingPointInfo(23, 8, 127, 127, 2139095040uL);

			public ulong ZeroBits { get; }

			public ulong InfinityBits { get; }

			public ulong NormalMantissaMask { get; }

			public ulong DenormalMantissaMask { get; }

			public int MinBinaryExponent { get; }

			public int MaxBinaryExponent { get; }

			public int ExponentBias { get; }

			public int OverflowDecimalExponent { get; }

			public ushort NormalMantissaBits { get; }

			public ushort DenormalMantissaBits { get; }

			public ushort ExponentBits { get; }

			public FloatingPointInfo(ushort denormalMantissaBits, ushort exponentBits, int maxBinaryExponent, int exponentBias, ulong infinityBits)
			{
				ExponentBits = exponentBits;
				DenormalMantissaBits = denormalMantissaBits;
				NormalMantissaBits = (ushort)(denormalMantissaBits + 1);
				OverflowDecimalExponent = (maxBinaryExponent + 2 * NormalMantissaBits) / 3;
				ExponentBias = exponentBias;
				MaxBinaryExponent = maxBinaryExponent;
				MinBinaryExponent = 1 - maxBinaryExponent;
				DenormalMantissaMask = (ulong)((1L << (int)denormalMantissaBits) - 1);
				NormalMantissaMask = (ulong)((1L << (int)NormalMantissaBits) - 1);
				InfinityBits = infinityBits;
				ZeroBits = 0uL;
			}
		}

		internal enum ParsingStatus
		{
			OK,
			Failed,
			Overflow
		}

		internal const int DecimalPrecision = 29;

		private const int SinglePrecision = 9;

		private const int DoublePrecision = 17;

		private const int SinglePrecisionCustomFormat = 7;

		private const int DoublePrecisionCustomFormat = 15;

		private const int DefaultPrecisionExponentialFormat = 6;

		private const int MaxUInt32DecDigits = 10;

		private const int CharStackBufferSize = 32;

		private const string PosNumberFormat = "#";

		private static readonly string[] s_singleDigitStringCache = new string[10] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };

		private static readonly string[] s_posCurrencyFormats = new string[4] { "$#", "#$", "$ #", "# $" };

		private static readonly string[] s_negCurrencyFormats = new string[16]
		{
			"($#)", "-$#", "$-#", "$#-", "(#$)", "-#$", "#-$", "#$-", "-# $", "-$ #",
			"# $-", "$ #-", "$ -#", "#- $", "($ #)", "(# $)"
		};

		private static readonly string[] s_posPercentFormats = new string[4] { "# %", "#%", "%#", "% #" };

		private static readonly string[] s_negPercentFormats = new string[12]
		{
			"-# %", "-#%", "-%#", "%-#", "%#-", "#-%", "#%-", "-% #", "# %-", "% #-",
			"% -#", "#- %"
		};

		private static readonly string[] s_negNumberFormats = new string[5] { "(#)", "-#", "- #", "#-", "# -" };

		internal const int DecimalNumberBufferLength = 31;

		internal const int DoubleNumberBufferLength = 769;

		internal const int Int32NumberBufferLength = 11;

		internal const int Int64NumberBufferLength = 20;

		internal const int SingleNumberBufferLength = 114;

		internal const int UInt32NumberBufferLength = 11;

		internal const int UInt64NumberBufferLength = 21;

		private static readonly float[] s_Pow10SingleTable = new float[11]
		{
			1f, 10f, 100f, 1000f, 10000f, 100000f, 1000000f, 10000000f, 100000000f, 1E+09f,
			1E+10f
		};

		private static readonly double[] s_Pow10DoubleTable = new double[23]
		{
			1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 10000000.0, 100000000.0, 1000000000.0,
			10000000000.0, 100000000000.0, 1000000000000.0, 10000000000000.0, 100000000000000.0, 1000000000000000.0, 10000000000000000.0, 1E+17, 1E+18, 1E+19,
			1E+20, 1E+21, 1E+22
		};

		private const int Int32Precision = 10;

		private const int UInt32Precision = 10;

		private const int Int64Precision = 19;

		private const int UInt64Precision = 20;

		private const int DoubleMaxExponent = 309;

		private const int DoubleMinExponent = -324;

		private const int FloatingPointMaxExponent = 309;

		private const int FloatingPointMinExponent = -324;

		private const int SingleMaxExponent = 39;

		private const int SingleMinExponent = -45;

		internal static ReadOnlySpan<byte> CharToHexLookup => new byte[103]
		{
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 0, 1,
			2, 3, 4, 5, 6, 7, 8, 9, 255, 255,
			255, 255, 255, 255, 255, 10, 11, 12, 13, 14,
			15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 10, 11, 12,
			13, 14, 15
		};

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static bool IsNegative(double d)
		{
			return BitConverter.DoubleToInt64Bits(d) < 0;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsNegativeInfinity(float f)
		{
			return f == float.NegativeInfinity;
		}

		public static void Dragon4Double(double value, int cutoffNumber, bool isSignificantDigits, ref NumberBuffer number)
		{
			IsNegative(value);
			int exponent;
			ulong num = ExtractFractionAndBiasedExponent(value, out exponent);
			bool hasUnequalMargins = false;
			uint mantissaHighBitIdx;
			if (num >> 52 != 0L)
			{
				mantissaHighBitIdx = 52u;
				hasUnequalMargins = num == 4503599627370496L;
			}
			else
			{
				mantissaHighBitIdx = (uint)BitOperations.Log2(num);
			}
			int decimalExponent;
			int num2 = (int)Dragon4(num, exponent, mantissaHighBitIdx, hasUnequalMargins, cutoffNumber, isSignificantDigits, number.Digits, out decimalExponent);
			number.Scale = decimalExponent + 1;
			number.Digits[num2] = 0;
			number.DigitsCount = num2;
		}

		public static void Dragon4Single(float value, int cutoffNumber, bool isSignificantDigits, ref NumberBuffer number)
		{
			IsNegative(value);
			int exponent;
			uint num = ExtractFractionAndBiasedExponent(value, out exponent);
			bool hasUnequalMargins = false;
			uint mantissaHighBitIdx;
			if (num >> 23 != 0)
			{
				mantissaHighBitIdx = 23u;
				hasUnequalMargins = num == 8388608;
			}
			else
			{
				mantissaHighBitIdx = (uint)BitOperations.Log2(num);
			}
			int decimalExponent;
			int num2 = (int)Dragon4(num, exponent, mantissaHighBitIdx, hasUnequalMargins, cutoffNumber, isSignificantDigits, number.Digits, out decimalExponent);
			number.Scale = decimalExponent + 1;
			number.Digits[num2] = 0;
			number.DigitsCount = num2;
		}

		private unsafe static uint Dragon4(ulong mantissa, int exponent, uint mantissaHighBitIdx, bool hasUnequalMargins, int cutoffNumber, bool isSignificantDigits, Span<byte> buffer, out int decimalExponent)
		{
			int num = 0;
			BigInteger result;
			BigInteger result2;
			BigInteger result3;
			BigInteger* ptr;
			if (hasUnequalMargins)
			{
				BigInteger result4;
				if (exponent > 0)
				{
					BigInteger.SetUInt64(out result, 4 * mantissa);
					result.ShiftLeft((uint)exponent);
					BigInteger.SetUInt32(out result2, 4u);
					BigInteger.Pow2((uint)exponent, out result3);
					BigInteger.Pow2((uint)(exponent + 1), out result4);
				}
				else
				{
					BigInteger.SetUInt64(out result, 4 * mantissa);
					BigInteger.Pow2((uint)(-exponent + 2), out result2);
					BigInteger.SetUInt32(out result3, 1u);
					BigInteger.SetUInt32(out result4, 2u);
				}
				ptr = &result4;
			}
			else
			{
				if (exponent > 0)
				{
					BigInteger.SetUInt64(out result, 2 * mantissa);
					result.ShiftLeft((uint)exponent);
					BigInteger.SetUInt32(out result2, 2u);
					BigInteger.Pow2((uint)exponent, out result3);
				}
				else
				{
					BigInteger.SetUInt64(out result, 2 * mantissa);
					BigInteger.Pow2((uint)(-exponent + 1), out result2);
					BigInteger.SetUInt32(out result3, 1u);
				}
				ptr = &result3;
			}
			int num2 = (int)Math.Ceiling((double)((int)mantissaHighBitIdx + exponent) * 0.3010299956639812 - 0.69);
			if (num2 > 0)
			{
				result2.MultiplyPow10((uint)num2);
			}
			else if (num2 < 0)
			{
				BigInteger.Pow10((uint)(-num2), out var result5);
				result.Multiply(ref result5);
				result3.Multiply(ref result5);
				if (ptr != &result3)
				{
					BigInteger.Multiply(ref result3, 2u, out *ptr);
				}
			}
			bool flag = mantissa % 2 == 0;
			bool flag2 = false;
			if (cutoffNumber == -1)
			{
				BigInteger.Add(ref result, ref *ptr, out var result6);
				int num3 = BigInteger.Compare(ref result6, ref result2);
				flag2 = (flag ? (num3 >= 0) : (num3 > 0));
			}
			else
			{
				flag2 = BigInteger.Compare(ref result, ref result2) >= 0;
			}
			if (flag2)
			{
				num2++;
			}
			else
			{
				result.Multiply10();
				result3.Multiply10();
				if (ptr != &result3)
				{
					BigInteger.Multiply(ref result3, 2u, out *ptr);
				}
			}
			int num4 = num2 - buffer.Length;
			if (cutoffNumber != -1)
			{
				int num5 = 0;
				num5 = ((!isSignificantDigits) ? (-cutoffNumber) : (num2 - cutoffNumber));
				if (num5 > num4)
				{
					num4 = num5;
				}
			}
			num2 = (decimalExponent = num2 - 1);
			uint block = result2.GetBlock((uint)(result2.GetLength() - 1));
			if (block < 8 || block > 429496729)
			{
				uint num6 = (uint)BitOperations.Log2(block);
				uint shift = (59 - num6) % 32;
				result2.ShiftLeft(shift);
				result.ShiftLeft(shift);
				result3.ShiftLeft(shift);
				if (ptr != &result3)
				{
					BigInteger.Multiply(ref result3, 2u, out *ptr);
				}
			}
			bool flag3;
			bool flag4;
			uint num7;
			if (cutoffNumber == -1)
			{
				while (true)
				{
					num7 = BigInteger.HeuristicDivide(ref result, ref result2);
					BigInteger.Add(ref result, ref *ptr, out var result7);
					int num8 = BigInteger.Compare(ref result, ref result3);
					int num9 = BigInteger.Compare(ref result7, ref result2);
					if (flag)
					{
						flag3 = num8 <= 0;
						flag4 = num9 >= 0;
					}
					else
					{
						flag3 = num8 < 0;
						flag4 = num9 > 0;
					}
					if (flag3 || flag4 || num2 == num4)
					{
						break;
					}
					buffer[num] = (byte)(48 + num7);
					num++;
					result.Multiply10();
					result3.Multiply10();
					if (ptr != &result3)
					{
						BigInteger.Multiply(ref result3, 2u, out *ptr);
					}
					num2--;
				}
			}
			else
			{
				if (num2 < num4)
				{
					num7 = BigInteger.HeuristicDivide(ref result, ref result2);
					if (num7 > 5 || (num7 == 5 && !result.IsZero()))
					{
						decimalExponent++;
						num7 = 1u;
					}
					buffer[num] = (byte)(48 + num7);
					return (uint)(num + 1);
				}
				flag3 = false;
				flag4 = false;
				while (true)
				{
					num7 = BigInteger.HeuristicDivide(ref result, ref result2);
					if (result.IsZero() || num2 <= num4)
					{
						break;
					}
					buffer[num] = (byte)(48 + num7);
					num++;
					result.Multiply10();
					num2--;
				}
			}
			bool flag5 = flag3;
			if (flag3 == flag4)
			{
				result.ShiftLeft(1u);
				int num10 = BigInteger.Compare(ref result, ref result2);
				flag5 = num10 < 0;
				if (num10 == 0)
				{
					flag5 = (num7 & 1) == 0;
				}
			}
			if (flag5)
			{
				buffer[num] = (byte)(48 + num7);
				num++;
			}
			else if (num7 == 9)
			{
				while (true)
				{
					if (num == 0)
					{
						buffer[num] = 49;
						num++;
						decimalExponent++;
						break;
					}
					num--;
					if (buffer[num] != 57)
					{
						buffer[num]++;
						num++;
						break;
					}
				}
			}
			else
			{
				buffer[num] = (byte)(48 + num7 + 1);
				num++;
			}
			return (uint)num;
		}

		public unsafe static string FormatDecimal(decimal value, ReadOnlySpan<char> format, NumberFormatInfo info)
		{
			int digits;
			char c = ParseFormatSpecifier(format, out digits);
			byte* digits2 = stackalloc byte[31];
			NumberBuffer number = new NumberBuffer(NumberBufferKind.Decimal, digits2, 31);
			DecimalToNumber(ref value, ref number);
			char* pointer = stackalloc char[32];
			System.Text.ValueStringBuilder sb = new System.Text.ValueStringBuilder(new Span<char>(pointer, 32));
			if (c != 0)
			{
				NumberToString(ref sb, ref number, c, digits, info);
			}
			else
			{
				NumberToStringFormat(ref sb, ref number, format, info);
			}
			return sb.ToString();
		}

		public unsafe static bool TryFormatDecimal(decimal value, ReadOnlySpan<char> format, NumberFormatInfo info, Span<char> destination, out int charsWritten)
		{
			int digits;
			char c = ParseFormatSpecifier(format, out digits);
			byte* digits2 = stackalloc byte[31];
			NumberBuffer number = new NumberBuffer(NumberBufferKind.Decimal, digits2, 31);
			DecimalToNumber(ref value, ref number);
			char* pointer = stackalloc char[32];
			System.Text.ValueStringBuilder sb = new System.Text.ValueStringBuilder(new Span<char>(pointer, 32));
			if (c != 0)
			{
				NumberToString(ref sb, ref number, c, digits, info);
			}
			else
			{
				NumberToStringFormat(ref sb, ref number, format, info);
			}
			return sb.TryCopyTo(destination, out charsWritten);
		}

		internal unsafe static void DecimalToNumber(ref decimal d, ref NumberBuffer number)
		{
			byte* digitsPointer = number.GetDigitsPointer();
			number.DigitsCount = 29;
			number.IsNegative = d.IsNegative();
			byte* bufferEnd = digitsPointer + 29;
			while ((d.Mid() | d.High()) != 0)
			{
				bufferEnd = UInt32ToDecChars(bufferEnd, DecimalEx.DecDivMod1E9(ref d), 9);
			}
			bufferEnd = UInt32ToDecChars(bufferEnd, d.Low(), 0);
			int num = (number.DigitsCount = (int)(digitsPointer + 29 - bufferEnd));
			number.Scale = num - d.Scale();
			byte* digitsPointer2 = number.GetDigitsPointer();
			while (--num >= 0)
			{
				*(digitsPointer2++) = *(bufferEnd++);
			}
			*digitsPointer2 = 0;
		}

		public static string FormatDouble(double value, string format, NumberFormatInfo info)
		{
			Span<char> initialBuffer = stackalloc char[32];
			System.Text.ValueStringBuilder sb = new System.Text.ValueStringBuilder(initialBuffer);
			return FormatDouble(ref sb, value, format.AsSpan(), info) ?? sb.ToString();
		}

		public static bool TryFormatDouble(double value, ReadOnlySpan<char> format, NumberFormatInfo info, Span<char> destination, out int charsWritten)
		{
			Span<char> initialBuffer = stackalloc char[32];
			System.Text.ValueStringBuilder sb = new System.Text.ValueStringBuilder(initialBuffer);
			string text = FormatDouble(ref sb, value, format, info);
			if (text == null)
			{
				return sb.TryCopyTo(destination, out charsWritten);
			}
			return TryCopyTo(text, destination, out charsWritten);
		}

		private static int GetFloatingPointMaxDigitsAndPrecision(char fmt, ref int precision, NumberFormatInfo info, out bool isSignificantDigits)
		{
			if (fmt == '\0')
			{
				isSignificantDigits = true;
				return precision;
			}
			int result = precision;
			switch (fmt)
			{
			case 'C':
			case 'c':
				if (precision == -1)
				{
					precision = info.CurrencyDecimalDigits;
				}
				isSignificantDigits = false;
				break;
			case 'E':
			case 'e':
				if (precision == -1)
				{
					precision = 6;
				}
				precision++;
				isSignificantDigits = true;
				break;
			case 'F':
			case 'N':
			case 'f':
			case 'n':
				if (precision == -1)
				{
					precision = info.NumberDecimalDigits;
				}
				isSignificantDigits = false;
				break;
			case 'G':
			case 'g':
				if (precision == 0)
				{
					precision = -1;
				}
				isSignificantDigits = true;
				break;
			case 'P':
			case 'p':
				if (precision == -1)
				{
					precision = info.PercentDecimalDigits;
				}
				precision += 2;
				isSignificantDigits = false;
				break;
			case 'R':
			case 'r':
				precision = -1;
				isSignificantDigits = true;
				break;
			default:
				throw new FormatException("SR.Argument_BadFormatSpecifier");
			}
			return result;
		}

		private unsafe static string FormatDouble(ref System.Text.ValueStringBuilder sb, double value, ReadOnlySpan<char> format, NumberFormatInfo info)
		{
			if (!FloatEx.IsFinite(value))
			{
				if (double.IsNaN(value))
				{
					return info.NaNSymbol;
				}
				if (!FloatEx.IsNegative(value))
				{
					return info.PositiveInfinitySymbol;
				}
				return info.NegativeInfinitySymbol;
			}
			int digits;
			char c = ParseFormatSpecifier(format, out digits);
			byte* digits2 = stackalloc byte[769];
			if (c == '\0')
			{
				digits = 15;
			}
			NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, digits2, 769);
			number.IsNegative = FloatEx.IsNegative(value);
			bool isSignificantDigits;
			int nMaxDigits = GetFloatingPointMaxDigitsAndPrecision(c, ref digits, info, out isSignificantDigits);
			if (value != 0.0 && (!isSignificantDigits || !Grisu3.TryRunDouble(value, digits, ref number)))
			{
				Dragon4Double(value, digits, isSignificantDigits, ref number);
			}
			if (c != 0)
			{
				if (digits == -1)
				{
					nMaxDigits = Math.Max(number.DigitsCount, 17);
				}
				NumberToString(ref sb, ref number, c, nMaxDigits, info);
			}
			else
			{
				NumberToStringFormat(ref sb, ref number, format, info);
			}
			return null;
		}

		public static string FormatSingle(float value, string format, NumberFormatInfo info)
		{
			Span<char> initialBuffer = stackalloc char[32];
			System.Text.ValueStringBuilder sb = new System.Text.ValueStringBuilder(initialBuffer);
			return FormatSingle(ref sb, value, format.AsSpan(), info) ?? sb.ToString();
		}

		public static bool TryFormatSingle(float value, ReadOnlySpan<char> format, NumberFormatInfo info, Span<char> destination, out int charsWritten)
		{
			Span<char> initialBuffer = stackalloc char[32];
			System.Text.ValueStringBuilder sb = new System.Text.ValueStringBuilder(initialBuffer);
			string text = FormatSingle(ref sb, value, format, info);
			if (text == null)
			{
				return sb.TryCopyTo(destination, out charsWritten);
			}
			return TryCopyTo(text, destination, out charsWritten);
		}

		private unsafe static string FormatSingle(ref System.Text.ValueStringBuilder sb, float value, ReadOnlySpan<char> format, NumberFormatInfo info)
		{
			if (!FloatEx.IsFinite(value))
			{
				if (float.IsNaN(value))
				{
					return info.NaNSymbol;
				}
				if (!FloatEx.IsNegative(value))
				{
					return info.PositiveInfinitySymbol;
				}
				return info.NegativeInfinitySymbol;
			}
			int digits;
			char c = ParseFormatSpecifier(format, out digits);
			byte* digits2 = stackalloc byte[114];
			if (c == '\0')
			{
				digits = 7;
			}
			NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, digits2, 114);
			number.IsNegative = FloatEx.IsNegative(value);
			bool isSignificantDigits;
			int nMaxDigits = GetFloatingPointMaxDigitsAndPrecision(c, ref digits, info, out isSignificantDigits);
			if (value != 0f && (!isSignificantDigits || !Grisu3.TryRunSingle(value, digits, ref number)))
			{
				Dragon4Single(value, digits, isSignificantDigits, ref number);
			}
			if (c != 0)
			{
				if (digits == -1)
				{
					nMaxDigits = Math.Max(number.DigitsCount, 9);
				}
				NumberToString(ref sb, ref number, c, nMaxDigits, info);
			}
			else
			{
				NumberToStringFormat(ref sb, ref number, format, info);
			}
			return null;
		}

		private static bool TryCopyTo(string source, Span<char> destination, out int charsWritten)
		{
			if (source.AsSpan().TryCopyTo(destination))
			{
				charsWritten = source.Length;
				return true;
			}
			charsWritten = 0;
			return false;
		}

		public unsafe static string FormatInt32(int value, ReadOnlySpan<char> format, IFormatProvider provider)
		{
			if (value >= 0 && format.Length == 0)
			{
				return UInt32ToDecStr((uint)value, -1);
			}
			int digits;
			char c = ParseFormatSpecifier(format, out digits);
			char c2 = (char)(c & 0xFFDFu);
			if (c2 != 'G' || digits >= 1)
			{
				switch (c2)
				{
				case 'D':
					break;
				case 'X':
					return Int32ToHexStr(value, (char)(c - 33), digits);
				default:
				{
					NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider);
					byte* digits2 = stackalloc byte[11];
					NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits2, 11);
					Int32ToNumber(value, ref number);
					char* pointer = stackalloc char[32];
					System.Text.ValueStringBuilder sb = new System.Text.ValueStringBuilder(new Span<char>(pointer, 32));
					if (c != 0)
					{
						NumberToString(ref sb, ref number, c, digits, instance);
					}
					else
					{
						NumberToStringFormat(ref sb, ref number, format, instance);
					}
					return sb.ToString();
				}
				}
			}
			if (value < 0)
			{
				return NegativeInt32ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSign);
			}
			return UInt32ToDecStr((uint)value, digits);
		}

		public unsafe static bool TryFormatInt32(int value, ReadOnlySpan<char> format, IFormatProvider provider, Span<char> destination, out int charsWritten)
		{
			if (value >= 0 && format.Length == 0)
			{
				return TryUInt32ToDecStr((uint)value, -1, destination, out charsWritten);
			}
			int digits;
			char c = ParseFormatSpecifier(format, out digits);
			char c2 = (char)(c & 0xFFDFu);
			if (c2 != 'G' || digits >= 1)
			{
				switch (c2)
				{
				case 'D':
					break;
				case 'X':
					return TryInt32ToHexStr(value, (char)(c - 33), digits, destination, out charsWritten);
				default:
				{
					NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider);
					byte* digits2 = stackalloc byte[11];
					NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits2, 11);
					Int32ToNumber(value, ref number);
					char* pointer = stackalloc char[32];
					System.Text.ValueStringBuilder sb = new System.Text.ValueStringBuilder(new Span<char>(pointer, 32));
					if (c != 0)
					{
						NumberToString(ref sb, ref number, c, digits, instance);
					}
					else
					{
						NumberToStringFormat(ref sb, ref number, format, instance);
					}
					return sb.TryCopyTo(destination, out charsWritten);
				}
				}
			}
			if (value < 0)
			{
				return TryNegativeInt32ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSign, destination, out charsWritten);
			}
			return TryUInt32ToDecStr((uint)value, digits, destination, out charsWritten);
		}

		public unsafe static string FormatUInt32(uint value, ReadOnlySpan<char> format, IFormatProvider provider)
		{
			if (format.Length == 0)
			{
				return UInt32ToDecStr(value, -1);
			}
			int digits;
			char c = ParseFormatSpecifier(format, out digits);
			char c2 = (char)(c & 0xFFDFu);
			if (c2 != 'G' || digits >= 1)
			{
				switch (c2)
				{
				case 'D':
					break;
				case 'X':
					return Int32ToHexStr((int)value, (char)(c - 33), digits);
				default:
				{
					NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider);
					byte* digits2 = stackalloc byte[11];
					NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits2, 11);
					UInt32ToNumber(value, ref number);
					char* pointer = stackalloc char[32];
					System.Text.ValueStringBuilder sb = new System.Text.ValueStringBuilder(new Span<char>(pointer, 32));
					if (c != 0)
					{
						NumberToString(ref sb, ref number, c, digits, instance);
					}
					else
					{
						NumberToStringFormat(ref sb, ref number, format, instance);
					}
					return sb.ToString();
				}
				}
			}
			return UInt32ToDecStr(value, digits);
		}

		public unsafe static bool TryFormatUInt32(uint value, ReadOnlySpan<char> format, IFormatProvider provider, Span<char> destination, out int charsWritten)
		{
			if (format.Length == 0)
			{
				return TryUInt32ToDecStr(value, -1, destination, out charsWritten);
			}
			int digits;
			char c = ParseFormatSpecifier(format, out digits);
			char c2 = (char)(c & 0xFFDFu);
			if (c2 != 'G' || digits >= 1)
			{
				switch (c2)
				{
				case 'D':
					break;
				case 'X':
					return TryInt32ToHexStr((int)value, (char)(c - 33), digits, destination, out charsWritten);
				default:
				{
					NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider);
					byte* digits2 = stackalloc byte[11];
					NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits2, 11);
					UInt32ToNumber(value, ref number);
					char* pointer = stackalloc char[32];
					System.Text.ValueStringBuilder sb = new System.Text.ValueStringBuilder(new Span<char>(pointer, 32));
					if (c != 0)
					{
						NumberToString(ref sb, ref number, c, digits, instance);
					}
					else
					{
						NumberToStringFormat(ref sb, ref number, format, instance);
					}
					return sb.TryCopyTo(destination, out charsWritten);
				}
				}
			}
			return TryUInt32ToDecStr(value, digits, destination, out charsWritten);
		}

		public unsafe static string FormatInt64(long value, ReadOnlySpan<char> format, IFormatProvider provider)
		{
			if (value >= 0 && format.Length == 0)
			{
				return UInt64ToDecStr((ulong)value, -1);
			}
			int digits;
			char c = ParseFormatSpecifier(format, out digits);
			char c2 = (char)(c & 0xFFDFu);
			if (c2 != 'G' || digits >= 1)
			{
				switch (c2)
				{
				case 'D':
					break;
				case 'X':
					return Int64ToHexStr(value, (char)(c - 33), digits);
				default:
				{
					NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider);
					byte* digits2 = stackalloc byte[20];
					NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits2, 20);
					Int64ToNumber(value, ref number);
					char* pointer = stackalloc char[32];
					System.Text.ValueStringBuilder sb = new System.Text.ValueStringBuilder(new Span<char>(pointer, 32));
					if (c != 0)
					{
						NumberToString(ref sb, ref number, c, digits, instance);
					}
					else
					{
						NumberToStringFormat(ref sb, ref number, format, instance);
					}
					return sb.ToString();
				}
				}
			}
			if (value < 0)
			{
				return NegativeInt64ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSign);
			}
			return UInt64ToDecStr((ulong)value, digits);
		}

		public unsafe static bool TryFormatInt64(long value, ReadOnlySpan<char> format, IFormatProvider provider, Span<char> destination, out int charsWritten)
		{
			if (value >= 0 && format.Length == 0)
			{
				return TryUInt64ToDecStr((ulong)value, -1, destination, out charsWritten);
			}
			int digits;
			char c = ParseFormatSpecifier(format, out digits);
			char c2 = (char)(c & 0xFFDFu);
			if (c2 != 'G' || digits >= 1)
			{
				switch (c2)
				{
				case 'D':
					break;
				case 'X':
					return TryInt64ToHexStr(value, (char)(c - 33), digits, destination, out charsWritten);
				default:
				{
					NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider);
					byte* digits2 = stackalloc byte[20];
					NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits2, 20);
					Int64ToNumber(value, ref number);
					char* pointer = stackalloc char[32];
					System.Text.ValueStringBuilder sb = new System.Text.ValueStringBuilder(new Span<char>(pointer, 32));
					if (c != 0)
					{
						NumberToString(ref sb, ref number, c, digits, instance);
					}
					else
					{
						NumberToStringFormat(ref sb, ref number, format, instance);
					}
					return sb.TryCopyTo(destination, out charsWritten);
				}
				}
			}
			if (value < 0)
			{
				return TryNegativeInt64ToDecStr(value, digits, NumberFormatInfo.GetInstance(provider).NegativeSign, destination, out charsWritten);
			}
			return TryUInt64ToDecStr((ulong)value, digits, destination, out charsWritten);
		}

		public unsafe static string FormatUInt64(ulong value, ReadOnlySpan<char> format, IFormatProvider provider)
		{
			if (format.Length == 0)
			{
				return UInt64ToDecStr(value, -1);
			}
			int digits;
			char c = ParseFormatSpecifier(format, out digits);
			char c2 = (char)(c & 0xFFDFu);
			if (c2 != 'G' || digits >= 1)
			{
				switch (c2)
				{
				case 'D':
					break;
				case 'X':
					return Int64ToHexStr((long)value, (char)(c - 33), digits);
				default:
				{
					NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider);
					byte* digits2 = stackalloc byte[21];
					NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits2, 21);
					UInt64ToNumber(value, ref number);
					char* pointer = stackalloc char[32];
					System.Text.ValueStringBuilder sb = new System.Text.ValueStringBuilder(new Span<char>(pointer, 32));
					if (c != 0)
					{
						NumberToString(ref sb, ref number, c, digits, instance);
					}
					else
					{
						NumberToStringFormat(ref sb, ref number, format, instance);
					}
					return sb.ToString();
				}
				}
			}
			return UInt64ToDecStr(value, digits);
		}

		public unsafe static bool TryFormatUInt64(ulong value, ReadOnlySpan<char> format, IFormatProvider provider, Span<char> destination, out int charsWritten)
		{
			if (format.Length == 0)
			{
				return TryUInt64ToDecStr(value, -1, destination, out charsWritten);
			}
			int digits;
			char c = ParseFormatSpecifier(format, out digits);
			char c2 = (char)(c & 0xFFDFu);
			if (c2 != 'G' || digits >= 1)
			{
				switch (c2)
				{
				case 'D':
					break;
				case 'X':
					return TryInt64ToHexStr((long)value, (char)(c - 33), digits, destination, out charsWritten);
				default:
				{
					NumberFormatInfo instance = NumberFormatInfo.GetInstance(provider);
					byte* digits2 = stackalloc byte[21];
					NumberBuffer number = new NumberBuffer(NumberBufferKind.Integer, digits2, 21);
					UInt64ToNumber(value, ref number);
					char* pointer = stackalloc char[32];
					System.Text.ValueStringBuilder sb = new System.Text.ValueStringBuilder(new Span<char>(pointer, 32));
					if (c != 0)
					{
						NumberToString(ref sb, ref number, c, digits, instance);
					}
					else
					{
						NumberToStringFormat(ref sb, ref number, format, instance);
					}
					return sb.TryCopyTo(destination, out charsWritten);
				}
				}
			}
			return TryUInt64ToDecStr(value, digits, destination, out charsWritten);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe static void Int32ToNumber(int value, ref NumberBuffer number)
		{
			number.DigitsCount = 10;
			if (value >= 0)
			{
				number.IsNegative = false;
			}
			else
			{
				number.IsNegative = true;
				value = -value;
			}
			byte* digitsPointer = number.GetDigitsPointer();
			byte* ptr = UInt32ToDecChars(digitsPointer + 10, (uint)value, 0);
			int num = (number.Scale = (number.DigitsCount = (int)(digitsPointer + 10 - ptr)));
			byte* digitsPointer2 = number.GetDigitsPointer();
			while (--num >= 0)
			{
				*(digitsPointer2++) = *(ptr++);
			}
			*digitsPointer2 = 0;
		}

		private unsafe static string NegativeInt32ToDecStr(int value, int digits, string sNegative)
		{
			if (digits < 1)
			{
				digits = 1;
			}
			int num = Math.Max(digits, System.Buffers.Text.FormattingHelpers.CountDigits((uint)(-value))) + sNegative.Length;
			string text = FastAllocateString(num);
			fixed (char* ptr = text)
			{
				char* ptr2 = UInt32ToDecChars(ptr + num, (uint)(-value), digits);
				for (int num2 = sNegative.Length - 1; num2 >= 0; num2--)
				{
					*(--ptr2) = sNegative[num2];
				}
			}
			return text;
		}

		private unsafe static bool TryNegativeInt32ToDecStr(int value, int digits, string sNegative, Span<char> destination, out int charsWritten)
		{
			if (digits < 1)
			{
				digits = 1;
			}
			int num = Math.Max(digits, System.Buffers.Text.FormattingHelpers.CountDigits((uint)(-value))) + sNegative.Length;
			if (num > destination.Length)
			{
				charsWritten = 0;
				return false;
			}
			charsWritten = num;
			fixed (char* ptr = &MemoryMarshal.GetReference(destination))
			{
				char* ptr2 = UInt32ToDecChars(ptr + num, (uint)(-value), digits);
				for (int num2 = sNegative.Length - 1; num2 >= 0; num2--)
				{
					*(--ptr2) = sNegative[num2];
				}
			}
			return true;
		}

		private unsafe static string Int32ToHexStr(int value, char hexBase, int digits)
		{
			if (digits < 1)
			{
				digits = 1;
			}
			int num = Math.Max(digits, System.Buffers.Text.FormattingHelpers.CountHexDigits((uint)value));
			string text = FastAllocateString(num);
			fixed (char* ptr = text)
			{
				Int32ToHexChars(ptr + num, (uint)value, hexBase, digits);
			}
			return text;
		}

		private unsafe static bool TryInt32ToHexStr(int value, char hexBase, int digits, Span<char> destination, out int charsWritten)
		{
			if (digits < 1)
			{
				digits = 1;
			}
			int num = Math.Max(digits, System.Buffers.Text.FormattingHelpers.CountHexDigits((uint)value));
			if (num > destination.Length)
			{
				charsWritten = 0;
				return false;
			}
			charsWritten = num;
			fixed (char* ptr = &MemoryMarshal.GetReference(destination))
			{
				Int32ToHexChars(ptr + num, (uint)value, hexBase, digits);
			}
			return true;
		}

		private unsafe static char* Int32ToHexChars(char* buffer, uint value, int hexBase, int digits)
		{
			while (--digits >= 0 || value != 0)
			{
				byte b = (byte)(value & 0xFu);
				*(--buffer) = (char)(b + ((b < 10) ? 48 : hexBase));
				value >>= 4;
			}
			return buffer;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe static void UInt32ToNumber(uint value, ref NumberBuffer number)
		{
			number.DigitsCount = 10;
			number.IsNegative = false;
			byte* digitsPointer = number.GetDigitsPointer();
			byte* ptr = UInt32ToDecChars(digitsPointer + 10, value, 0);
			int num = (number.Scale = (number.DigitsCount = (int)(digitsPointer + 10 - ptr)));
			byte* digitsPointer2 = number.GetDigitsPointer();
			while (--num >= 0)
			{
				*(digitsPointer2++) = *(ptr++);
			}
			*digitsPointer2 = 0;
		}

		internal unsafe static byte* UInt32ToDecChars(byte* bufferEnd, uint value, int digits)
		{
			while (--digits >= 0 || value != 0)
			{
				value = MathEx.DivRem(value, 10u, out var result);
				*(--bufferEnd) = (byte)(result + 48);
			}
			return bufferEnd;
		}

		internal unsafe static char* UInt32ToDecChars(char* bufferEnd, uint value, int digits)
		{
			while (--digits >= 0 || value != 0)
			{
				value = MathEx.DivRem(value, 10u, out var result);
				*(--bufferEnd) = (char)(result + 48);
			}
			return bufferEnd;
		}

		internal unsafe static string UInt32ToDecStr(uint value, int digits)
		{
			int num = Math.Max(digits, System.Buffers.Text.FormattingHelpers.CountDigits(value));
			if (num == 1)
			{
				return s_singleDigitStringCache[value];
			}
			string text = FastAllocateString(num);
			fixed (char* ptr = text)
			{
				char* ptr2 = ptr + num;
				if (digits <= 1)
				{
					do
					{
						value = MathEx.DivRem(value, 10u, out var result);
						*(--ptr2) = (char)(result + 48);
					}
					while (value != 0);
				}
				else
				{
					ptr2 = UInt32ToDecChars(ptr2, value, digits);
				}
			}
			return text;
		}

		private unsafe static bool TryUInt32ToDecStr(uint value, int digits, Span<char> destination, out int charsWritten)
		{
			int num = Math.Max(digits, System.Buffers.Text.FormattingHelpers.CountDigits(value));
			if (num > destination.Length)
			{
				charsWritten = 0;
				return false;
			}
			charsWritten = num;
			fixed (char* ptr = &MemoryMarshal.GetReference(destination))
			{
				char* ptr2 = ptr + num;
				if (digits <= 1)
				{
					do
					{
						value = MathEx.DivRem(value, 10u, out var result);
						*(--ptr2) = (char)(result + 48);
					}
					while (value != 0);
				}
				else
				{
					ptr2 = UInt32ToDecChars(ptr2, value, digits);
				}
			}
			return true;
		}

		private unsafe static void Int64ToNumber(long input, ref NumberBuffer number)
		{
			ulong value = (ulong)input;
			number.IsNegative = input < 0;
			number.DigitsCount = 19;
			if (number.IsNegative)
			{
				value = (ulong)(-input);
			}
			byte* digitsPointer = number.GetDigitsPointer();
			byte* bufferEnd = digitsPointer + 19;
			while (High32(value) != 0)
			{
				bufferEnd = UInt32ToDecChars(bufferEnd, Int64DivMod1E9(ref value), 9);
			}
			bufferEnd = UInt32ToDecChars(bufferEnd, Low32(value), 0);
			int num = (number.Scale = (number.DigitsCount = (int)(digitsPointer + 19 - bufferEnd)));
			byte* digitsPointer2 = number.GetDigitsPointer();
			while (--num >= 0)
			{
				*(digitsPointer2++) = *(bufferEnd++);
			}
			*digitsPointer2 = 0;
		}

		private unsafe static string NegativeInt64ToDecStr(long input, int digits, string sNegative)
		{
			if (digits < 1)
			{
				digits = 1;
			}
			ulong value = (ulong)(-input);
			int num = Math.Max(digits, System.Buffers.Text.FormattingHelpers.CountDigits(value)) + sNegative.Length;
			string text = FastAllocateString(num);
			fixed (char* ptr = text)
			{
				char* bufferEnd = ptr + num;
				while (High32(value) != 0)
				{
					bufferEnd = UInt32ToDecChars(bufferEnd, Int64DivMod1E9(ref value), 9);
					digits -= 9;
				}
				bufferEnd = UInt32ToDecChars(bufferEnd, Low32(value), digits);
				for (int num2 = sNegative.Length - 1; num2 >= 0; num2--)
				{
					*(--bufferEnd) = sNegative[num2];
				}
			}
			return text;
		}

		private unsafe static bool TryNegativeInt64ToDecStr(long input, int digits, string sNegative, Span<char> destination, out int charsWritten)
		{
			if (digits < 1)
			{
				digits = 1;
			}
			ulong value = (ulong)(-input);
			int num = Math.Max(digits, System.Buffers.Text.FormattingHelpers.CountDigits((ulong)(-input))) + sNegative.Length;
			if (num > destination.Length)
			{
				charsWritten = 0;
				return false;
			}
			charsWritten = num;
			fixed (char* ptr = &MemoryMarshal.GetReference(destination))
			{
				char* bufferEnd = ptr + num;
				while (High32(value) != 0)
				{
					bufferEnd = UInt32ToDecChars(bufferEnd, Int64DivMod1E9(ref value), 9);
					digits -= 9;
				}
				bufferEnd = UInt32ToDecChars(bufferEnd, Low32(value), digits);
				for (int num2 = sNegative.Length - 1; num2 >= 0; num2--)
				{
					*(--bufferEnd) = sNegative[num2];
				}
			}
			return true;
		}

		private unsafe static string Int64ToHexStr(long value, char hexBase, int digits)
		{
			int num = Math.Max(digits, System.Buffers.Text.FormattingHelpers.CountHexDigits((ulong)value));
			string text = FastAllocateString(num);
			fixed (char* ptr = text)
			{
				char* buffer = ptr + num;
				if (High32((ulong)value) != 0)
				{
					buffer = Int32ToHexChars(buffer, Low32((ulong)value), hexBase, 8);
					buffer = Int32ToHexChars(buffer, High32((ulong)value), hexBase, digits - 8);
				}
				else
				{
					buffer = Int32ToHexChars(buffer, Low32((ulong)value), hexBase, Math.Max(digits, 1));
				}
			}
			return text;
		}

		private unsafe static bool TryInt64ToHexStr(long value, char hexBase, int digits, Span<char> destination, out int charsWritten)
		{
			int num = Math.Max(digits, System.Buffers.Text.FormattingHelpers.CountHexDigits((ulong)value));
			if (num > destination.Length)
			{
				charsWritten = 0;
				return false;
			}
			charsWritten = num;
			fixed (char* ptr = &MemoryMarshal.GetReference(destination))
			{
				char* buffer = ptr + num;
				if (High32((ulong)value) != 0)
				{
					buffer = Int32ToHexChars(buffer, Low32((ulong)value), hexBase, 8);
					buffer = Int32ToHexChars(buffer, High32((ulong)value), hexBase, digits - 8);
				}
				else
				{
					buffer = Int32ToHexChars(buffer, Low32((ulong)value), hexBase, Math.Max(digits, 1));
				}
			}
			return true;
		}

		private unsafe static void UInt64ToNumber(ulong value, ref NumberBuffer number)
		{
			number.DigitsCount = 20;
			number.IsNegative = false;
			byte* digitsPointer = number.GetDigitsPointer();
			byte* bufferEnd = digitsPointer + 20;
			while (High32(value) != 0)
			{
				bufferEnd = UInt32ToDecChars(bufferEnd, Int64DivMod1E9(ref value), 9);
			}
			bufferEnd = UInt32ToDecChars(bufferEnd, Low32(value), 0);
			int num = (number.Scale = (number.DigitsCount = (int)(digitsPointer + 20 - bufferEnd)));
			byte* digitsPointer2 = number.GetDigitsPointer();
			while (--num >= 0)
			{
				*(digitsPointer2++) = *(bufferEnd++);
			}
			*digitsPointer2 = 0;
		}

		internal unsafe static string UInt64ToDecStr(ulong value, int digits)
		{
			if (digits < 1)
			{
				digits = 1;
			}
			int num = Math.Max(digits, System.Buffers.Text.FormattingHelpers.CountDigits(value));
			if (num == 1)
			{
				return s_singleDigitStringCache[value];
			}
			string text = FastAllocateString(num);
			fixed (char* ptr = text)
			{
				char* bufferEnd = ptr + num;
				while (High32(value) != 0)
				{
					bufferEnd = UInt32ToDecChars(bufferEnd, Int64DivMod1E9(ref value), 9);
					digits -= 9;
				}
				bufferEnd = UInt32ToDecChars(bufferEnd, Low32(value), digits);
			}
			return text;
		}

		private unsafe static bool TryUInt64ToDecStr(ulong value, int digits, Span<char> destination, out int charsWritten)
		{
			if (digits < 1)
			{
				digits = 1;
			}
			int num = Math.Max(digits, System.Buffers.Text.FormattingHelpers.CountDigits(value));
			if (num > destination.Length)
			{
				charsWritten = 0;
				return false;
			}
			charsWritten = num;
			fixed (char* ptr = &MemoryMarshal.GetReference(destination))
			{
				char* bufferEnd = ptr + num;
				while (High32(value) != 0)
				{
					bufferEnd = UInt32ToDecChars(bufferEnd, Int64DivMod1E9(ref value), 9);
					digits -= 9;
				}
				bufferEnd = UInt32ToDecChars(bufferEnd, Low32(value), digits);
			}
			return true;
		}

		internal static char ParseFormatSpecifier(ReadOnlySpan<char> format, out int digits)
		{
			char c = '\0';
			if (format.Length > 0)
			{
				c = format[0];
				if ((uint)(c - 65) <= 25u || (uint)(c - 97) <= 25u)
				{
					if (format.Length == 1)
					{
						digits = -1;
						return c;
					}
					if (format.Length == 2)
					{
						int num = format[1] - 48;
						if ((uint)num < 10u)
						{
							digits = num;
							return c;
						}
					}
					else if (format.Length == 3)
					{
						int num2 = format[1] - 48;
						int num3 = format[2] - 48;
						if ((uint)num2 < 10u && (uint)num3 < 10u)
						{
							digits = num2 * 10 + num3;
							return c;
						}
					}
					int num4 = 0;
					int num5 = 1;
					while (num5 < format.Length && (uint)(format[num5] - 48) < 10u && num4 < 10)
					{
						num4 = num4 * 10 + format[num5++] - 48;
					}
					if (num5 == format.Length || format[num5] == '\0')
					{
						digits = num4;
						return c;
					}
				}
			}
			digits = -1;
			if (format.Length != 0 && c != 0)
			{
				return '\0';
			}
			return 'G';
		}

		internal static void NumberToString(ref System.Text.ValueStringBuilder sb, ref NumberBuffer number, char format, int nMaxDigits, NumberFormatInfo info)
		{
			bool isCorrectlyRounded = number.Kind == NumberBufferKind.FloatingPoint;
			bool bSuppressScientific;
			switch (format)
			{
			case 'C':
			case 'c':
				if (nMaxDigits < 0)
				{
					nMaxDigits = info.CurrencyDecimalDigits;
				}
				RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded);
				FormatCurrency(ref sb, ref number, nMaxDigits, info);
				return;
			case 'F':
			case 'f':
				if (nMaxDigits < 0)
				{
					nMaxDigits = info.NumberDecimalDigits;
				}
				RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded);
				if (number.IsNegative)
				{
					sb.Append(info.NegativeSign);
				}
				FormatFixed(ref sb, ref number, nMaxDigits, null, info.NumberDecimalSeparator, null);
				return;
			case 'N':
			case 'n':
				if (nMaxDigits < 0)
				{
					nMaxDigits = info.NumberDecimalDigits;
				}
				RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded);
				FormatNumber(ref sb, ref number, nMaxDigits, info);
				return;
			case 'E':
			case 'e':
				if (nMaxDigits < 0)
				{
					nMaxDigits = 6;
				}
				nMaxDigits++;
				RoundNumber(ref number, nMaxDigits, isCorrectlyRounded);
				if (number.IsNegative)
				{
					sb.Append(info.NegativeSign);
				}
				FormatScientific(ref sb, ref number, nMaxDigits, info, format);
				return;
			case 'G':
			case 'g':
				bSuppressScientific = false;
				if (nMaxDigits < 1)
				{
					if (number.Kind == NumberBufferKind.Decimal && nMaxDigits == -1)
					{
						bSuppressScientific = true;
						if (number.Digits[0] != 0)
						{
							goto IL_0189;
						}
						goto IL_019e;
					}
					nMaxDigits = number.DigitsCount;
				}
				RoundNumber(ref number, nMaxDigits, isCorrectlyRounded);
				goto IL_0189;
			case 'P':
			case 'p':
				if (nMaxDigits < 0)
				{
					nMaxDigits = info.PercentDecimalDigits;
				}
				number.Scale += 2;
				RoundNumber(ref number, number.Scale + nMaxDigits, isCorrectlyRounded);
				FormatPercent(ref sb, ref number, nMaxDigits, info);
				return;
			case 'R':
			case 'r':
				{
					if (number.Kind != NumberBufferKind.FloatingPoint)
					{
						break;
					}
					format = (char)(format - 11);
					goto case 'G';
				}
				IL_0189:
				if (number.IsNegative)
				{
					sb.Append(info.NegativeSign);
				}
				goto IL_019e;
				IL_019e:
				FormatGeneral(ref sb, ref number, nMaxDigits, info, (char)(format - 2), bSuppressScientific);
				return;
			}
			throw new FormatException("SR.Argument_BadFormatSpecifier");
		}

		internal unsafe static void NumberToStringFormat(ref System.Text.ValueStringBuilder sb, ref NumberBuffer number, ReadOnlySpan<char> format, NumberFormatInfo info)
		{
			int num = 0;
			byte* digitsPointer = number.GetDigitsPointer();
			int num2 = FindSection(format, (*digitsPointer == 0) ? 2 : (number.IsNegative ? 1 : 0));
			int num3;
			int num4;
			bool flag;
			bool flag2;
			int num5;
			int num6;
			int num9;
			while (true)
			{
				num3 = 0;
				num4 = -1;
				num5 = int.MaxValue;
				num6 = 0;
				flag = false;
				int num7 = -1;
				flag2 = false;
				int num8 = 0;
				num9 = num2;
				fixed (char* ptr = &MemoryMarshal.GetReference(format))
				{
					char c;
					while (num9 < format.Length && (c = ptr[num9++]) != 0)
					{
						switch (c)
						{
						case ';':
							break;
						case '#':
							num3++;
							continue;
						case '0':
							if (num5 == int.MaxValue)
							{
								num5 = num3;
							}
							num3++;
							num6 = num3;
							continue;
						case '.':
							if (num4 < 0)
							{
								num4 = num3;
							}
							continue;
						case ',':
							if (num3 <= 0 || num4 >= 0)
							{
								continue;
							}
							if (num7 >= 0)
							{
								if (num7 == num3)
								{
									num++;
									continue;
								}
								flag2 = true;
							}
							num7 = num3;
							num = 1;
							continue;
						case '%':
							num8 += 2;
							continue;
						case '‰':
							num8 += 3;
							continue;
						case '"':
						case '\'':
							while (num9 < format.Length && ptr[num9] != 0 && ptr[num9++] != c)
							{
							}
							continue;
						case '\\':
							if (num9 < format.Length && ptr[num9] != 0)
							{
								num9++;
							}
							continue;
						case 'E':
						case 'e':
							if ((num9 < format.Length && ptr[num9] == '0') || (num9 + 1 < format.Length && (ptr[num9] == '+' || ptr[num9] == '-') && ptr[num9 + 1] == '0'))
							{
								while (++num9 < format.Length && ptr[num9] == '0')
								{
								}
								flag = true;
							}
							continue;
						default:
							continue;
						}
						break;
					}
				}
				if (num4 < 0)
				{
					num4 = num3;
				}
				if (num7 >= 0)
				{
					if (num7 == num4)
					{
						num8 -= num * 3;
					}
					else
					{
						flag2 = true;
					}
				}
				if (*digitsPointer != 0)
				{
					number.Scale += num8;
					int pos = (flag ? num3 : (number.Scale + num3 - num4));
					RoundNumber(ref number, pos, isCorrectlyRounded: false);
					if (*digitsPointer != 0)
					{
						break;
					}
					num9 = FindSection(format, 2);
					if (num9 == num2)
					{
						break;
					}
					num2 = num9;
					continue;
				}
				if (number.Kind != NumberBufferKind.FloatingPoint)
				{
					number.IsNegative = false;
				}
				number.Scale = 0;
				break;
			}
			num5 = ((num5 < num4) ? (num4 - num5) : 0);
			num6 = ((num6 > num4) ? (num4 - num6) : 0);
			int num10;
			int num11;
			if (flag)
			{
				num10 = num4;
				num11 = 0;
			}
			else
			{
				num10 = ((number.Scale > num4) ? number.Scale : num4);
				num11 = number.Scale - num4;
			}
			num9 = num2;
			Span<int> span = stackalloc int[4];
			int num12 = -1;
			if (flag2 && info.NumberGroupSeparator.Length > 0)
			{
				int[] numberGroupSizes = info.NumberGroupSizes;
				int num13 = 0;
				int i = 0;
				int num14 = numberGroupSizes.Length;
				if (num14 != 0)
				{
					i = numberGroupSizes[num13];
				}
				int num15 = i;
				int num16 = num10 + ((num11 < 0) ? num11 : 0);
				for (int num17 = ((num5 > num16) ? num5 : num16); num17 > i; i += num15)
				{
					if (num15 == 0)
					{
						break;
					}
					num12++;
					if (num12 >= span.Length)
					{
						int[] array = new int[span.Length * 2];
						span.CopyTo(array);
						span = array;
					}
					span[num12] = i;
					if (num13 < num14 - 1)
					{
						num13++;
						num15 = numberGroupSizes[num13];
					}
				}
			}
			if (number.IsNegative && num2 == 0 && number.Scale != 0)
			{
				sb.Append(info.NegativeSign);
			}
			bool flag3 = false;