ある整数を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 しています。