【C#】2進数を4桁ごとに区切って表示する

ある整数を2進数に変換し4桁ごとに区切り文字を入れる方法の紹介です。

// こんな数値を
uint value = 0xCACAEFEF;

// こんな風に文字列に変換する
1100 1010 1100 1010 1110 1111 1110 1111

Unity 上での使用を想定して GCAlloc が最小となる & そこそこ高速に動作するように実装します。Linq は使用せずに(処理速度、GCAlloc で劣るため)、Span を使用したいと思います。

確認環境

  • .NET Core 3.1
  • Visual Studuo 2022

コンソールで出力を確認

実装コード

public static class ConvertBinary
{
    public static string ToString(ushort value, char separator = ' ') 
        => Core(value, separator, 9);
    public static string ToString(short value, char separator = ' ') 
        => Core(value, separator, 9);
    public static string ToString(uint value, char separator = ' ') 
        => Core(value, separator, 39);
    public static string ToString(int value, char separator = ' ') 
        => Core(value, separator, 39);
    public static string ToString(ulong value, char separator = ' ') 
        => Core((long)value, separator, 79);
    public static string ToString(long value, char separator = ' ') 
        => Core(value, separator, 79);

    private static string Core(long value, char separator, int length)
    {
        Span<char> array = stackalloc char[length];
        for (int i = array.Length - 1, j = 0, p = 0; i >= 0; i--, j++, p++)
        {
            if (j >= 4)
            {
                array[i] = separator;
                i--;
                j = 0;
            }
            array[i] = (value & (1L << p)) > 0 ? '1' : '0';
        }
        return new string(array);
    }
}

使い方は以下の通りです。

public static void Foo()
{
    for (int i = 0; i < 5; i++)
    {
        string str = ConvertBinary.ToString(i);
        Console.WriteLine($"{i:D4}={str}");
        // > 0000=0000 0000 0000 0000 0000 0000 0000 0000
        // > 0001=0000 0000 0000 0000 0000 0000 0000 0001
        // > 0002=0000 0000 0000 0000 0000 0000 0000 0010
        // > 0003=0000 0000 0000 0000 0000 0000 0000 0011
        // > 0004=0000 0000 0000 0000 0000 0000 0000 0100
    }
}

Unity 上でプロファイルすると 1回 100B で文字列生成したときのみ GCAlloc しています。