private static string?FormatBigIntegerToHex(bool targetSpan, BigInteger value, char format, int digits, NumberFormatInfo info, Span <char> destination, out int charsWritten, out bool spanSuccess) { Debug.Assert(format == 'x' || format == 'X'); // Get the bytes that make up the BigInteger. byte[]? arrayToReturnToPool = null; Span <byte> bits = stackalloc byte[64]; // arbitrary threshold if (!value.TryWriteOrCountBytes(bits, out int bytesWrittenOrNeeded)) { bits = arrayToReturnToPool = ArrayPool <byte> .Shared.Rent(bytesWrittenOrNeeded); bool success = value.TryWriteBytes(bits, out bytesWrittenOrNeeded); Debug.Assert(success); } bits = bits.Slice(0, bytesWrittenOrNeeded); var sb = new ValueStringBuilder(stackalloc char[128]); // each byte is typically two chars int cur = bits.Length - 1; if (cur > -1) { // [FF..F8] drop the high F as the two's complement negative number remains clear // [F7..08] retain the high bits as the two's complement number is wrong without it // [07..00] drop the high 0 as the two's complement positive number remains clear bool clearHighF = false; byte head = bits[cur]; if (head > 0xF7) { head -= 0xF0; clearHighF = true; } if (head < 0x08 || clearHighF) { // {0xF8-0xFF} print as {8-F} // {0x00-0x07} print as {0-7} sb.Append(head < 10 ? (char)(head + '0') : format == 'X' ? (char)((head & 0xF) - 10 + 'A') : (char)((head & 0xF) - 10 + 'a')); cur--; } } if (cur > -1) { Span <char> chars = sb.AppendSpan((cur + 1) * 2); int charsPos = 0; string hexValues = format == 'x' ? "0123456789abcdef" : "0123456789ABCDEF"; while (cur > -1) { byte b = bits[cur--]; chars[charsPos++] = hexValues[b >> 4]; chars[charsPos++] = hexValues[b & 0xF]; } } if (digits > sb.Length) { // Insert leading zeros, e.g. user specified "X5" so we create "0ABCD" instead of "ABCD" sb.Insert( 0, value._sign >= 0 ? '0' : (format == 'x') ? 'f' : 'F', digits - sb.Length); } if (arrayToReturnToPool != null) { ArrayPool <byte> .Shared.Return(arrayToReturnToPool); } if (targetSpan) { spanSuccess = sb.TryCopyTo(destination, out charsWritten); return(null); } else { charsWritten = 0; spanSuccess = false; return(sb.ToString()); } }