BitUtils.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. namespace ARMeilleure.Common
  2. {
  3. static class BitUtils
  4. {
  5. private const int DeBrujinSequence = 0x77cb531;
  6. private static readonly int[] DeBrujinLbsLut;
  7. private static readonly sbyte[] HbsNibbleLut;
  8. static BitUtils()
  9. {
  10. DeBrujinLbsLut = new int[32];
  11. for (int index = 0; index < DeBrujinLbsLut.Length; index++)
  12. {
  13. uint lutIndex = (uint)(DeBrujinSequence * (1 << index)) >> 27;
  14. DeBrujinLbsLut[lutIndex] = index;
  15. }
  16. HbsNibbleLut = new sbyte[] { -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 };
  17. }
  18. public static int CountBits(int value)
  19. {
  20. int count = 0;
  21. while (value != 0)
  22. {
  23. value &= ~(value & -value);
  24. count++;
  25. }
  26. return count;
  27. }
  28. public static long FillWithOnes(int bits)
  29. {
  30. return bits == 64 ? -1L : (1L << bits) - 1;
  31. }
  32. public static int HighestBitSet(int value)
  33. {
  34. if (value == 0)
  35. {
  36. return -1;
  37. }
  38. for (int bit = 31; bit >= 0; bit--)
  39. {
  40. if (((value >> bit) & 1) != 0)
  41. {
  42. return bit;
  43. }
  44. }
  45. return -1;
  46. }
  47. public static int HighestBitSetNibble(int value)
  48. {
  49. return HbsNibbleLut[value];
  50. }
  51. public static int LowestBitSet(int value)
  52. {
  53. if (value == 0)
  54. {
  55. return -1;
  56. }
  57. int lsb = value & -value;
  58. return DeBrujinLbsLut[(uint)(DeBrujinSequence * lsb) >> 27];
  59. }
  60. public static long Replicate(long bits, int size)
  61. {
  62. long output = 0;
  63. for (int bit = 0; bit < 64; bit += size)
  64. {
  65. output |= bits << bit;
  66. }
  67. return output;
  68. }
  69. public static int RotateRight(int bits, int shift, int size)
  70. {
  71. return (int)RotateRight((uint)bits, shift, size);
  72. }
  73. public static uint RotateRight(uint bits, int shift, int size)
  74. {
  75. return (bits >> shift) | (bits << (size - shift));
  76. }
  77. public static long RotateRight(long bits, int shift, int size)
  78. {
  79. return (long)RotateRight((ulong)bits, shift, size);
  80. }
  81. public static ulong RotateRight(ulong bits, int shift, int size)
  82. {
  83. return (bits >> shift) | (bits << (size - shift));
  84. }
  85. }
  86. }