【筆記】Hacker's Delight - Counting Bits
阿新 • • 發佈:2018-11-10
Counting 1-Bits(二進位制1的個數)
/// <summary> /// <paramref name="n"/>二進位制1的個數 /// </summary> public static int Population(uint n) { n -= (n >> 1) & 0x5555_5555; n = (n & 0x3333_3333) + ((n >> 2) & 0x3333_3333); n = (n + (n >> 4)) & 0x0F0F_0F0F; n += (n >> 8); n += (n >> 16); return (int)(n & 0x0000_003F); } /// <summary> /// <paramref name="n"/>二進位制1的個數 /// </summary> public static int Population(int n) { var un = (uint)n; un -= (un >> 1) & 0x5555_5555; un = (un & 0x3333_3333) + ((un >> 2) & 0x3333_3333); un = (un + (un >> 4)) & 0x0F0F_0F0F; un += (un >> 8); un += (un >> 16); return (int)(un & 0x0000_003F); } /// <summary> /// <paramref name="n"/>二進位制1的個數 /// </summary> public static int Population(ulong n) { var t1 = n >> 32; var t2 = n & 0xFFFF_FFFF; t1 -= (t1 >> 1) & 0x5555_5555; t1 = (t1 & 0x3333_3333) + ((t1 >> 2) & 0x3333_3333); t2 -= (t2 >> 1) & 0x5555_5555; t2 = (t2 & 0x3333_3333) + ((t2 >> 2) & 0x3333_3333); t1 += t2; t1 = (t1 + (t1 >> 4)) & 0x0F0F_0F0F; t1 += (t1 >> 8); t1 += (t1 >> 16); return (int)(t1 & 0x0000_003F); } /// <summary> /// <paramref name="n"/>二進位制1的個數 /// </summary> public static int Population(long n) { var t1 = (ulong)n >> 32; var t2 = (ulong)n & 0xFFFF_FFFF; t1 -= (t1 >> 1) & 0x5555_5555; t1 = (t1 & 0x3333_3333) + ((t1 >> 2) & 0x3333_3333); t2 -= (t2 >> 1) & 0x5555_5555; t2 = (t2 & 0x3333_3333) + ((t2 >> 2) & 0x3333_3333); t1 += t2; t1 = (t1 + (t1 >> 4)) & 0x0F0F_0F0F; t1 += (t1 >> 8); t1 += (t1 >> 16); return (int)(t1 & 0x0000_003F); }
Counting Leading 0’s (二進位制前導0的個數)
/// <summary> /// <paramref name="n"/>二進位制前導0的個數 /// </summary> public static int NumberOfLeadingZeros(this uint n) { if (n == 0u) return 32; var c = 1; if ((n >> 16) == 0u) { c += 16; n <<= 16; } if ((n >> 24) == 0u) { c += 8; n <<= 8; } if ((n >> 28) == 0u) { c += 4; n <<= 4; } if ((n >> 30) == 0u) { c += 2; n <<= 2; } return c - (int)(n >> 31); } /// <summary> /// <paramref name="n"/>二進位制前導0的個數 /// </summary> public static int NumberOfLeadingZeros(this int n) { if (n == 0u) return 32; var c = 1; if (((uint)n >> 16) == 0) { c += 16; n <<= 16; } if (((uint)n >> 24) == 0) { c += 8; n <<= 8; } if (((uint)n >> 28) == 0) { c += 4; n <<= 4; } if (((uint)n >> 30) == 0) { c += 2; n <<= 2; } return c - (int)((uint)n >> 31); } /// <summary> /// <paramref name="n"/>二進位制前導0的個數 /// </summary> public static int NumberOfLeadingZeros(this ulong n) { if (n == 0ul) return 64; var c = 1; if ((n >> 32) == 0ul) { c += 32; n <<= 32; } if ((n >> 48) == 0ul) { c += 16; n <<= 16; } if ((n >> 56) == 0ul) { c += 8; n <<= 8; } if ((n >> 60) == 0ul) { c += 4; n <<= 4; } if ((n >> 62) == 0ul) { c += 2; n <<= 2; } return c - (int)(n >> 63); } /// <summary> /// <paramref name="n"/>二進位制前導0的個數 /// </summary> public static int NumberOfLeadingZeros(this long n) { if (n == 0L) return 64; var c = 1; if (((ulong)n >> 32) == 0L) { c += 32; n <<= 32; } if (((ulong)n >> 48) == 0L) { c += 16; n <<= 16; } if (((ulong)n >> 56) == 0L) { c += 8; n <<= 8; } if (((ulong)n >> 60) == 0L) { c += 4; n <<= 4; } if (((ulong)n >> 62) == 0L) { c += 2; n <<= 2; } return c - (int)((ulong)n >> 63); }
Counting Trailing 0’s(二進位制尾數0的個數)
/// <summary> /// <paramref name="n"/>二進位制尾數0的個數 /// </summary> public static int NumberOfTrailingZeros(this uint n) { if (n == 0) return 32; var c = 31; var t = n << 16; if (t != 0u) { c -= 16; n = t; } t = n << 8; if (t != 0u) { c -= 8; n = t; } t = n << 4; if (t != 0u) { c -= 4; n = t; } t = n << 2; if (t != 0u) { c -= 2; n = t; } t = n << 1; if (t != 0u) { c -= 1; } return c; } /// <summary> /// <paramref name="n"/>二進位制尾數0的個數 /// </summary> public static int NumberOfTrailingZeros(this int n) { if (n == 0) return 32; var c = 31; var t = n << 16; if (t != 0) { c -= 16; n = t; } t = n << 8; if (t != 0) { c -= 8; n = t; } t = n << 4; if (t != 0) { c -= 4; n = t; } t = n << 2; if (t != 0) { c -= 2; n = t; } t = n << 1; if (t != 0) { c -= 1; } return c; } /// <summary> /// <paramref name="n"/>二進位制尾數0的個數 /// </summary> public static int NumberOfTrailingZeros(this ulong n) { if (n == 0) return 64; var c = 63; var t = n << 32; if (t != 0ul) { c -= 32; n = t; } t = n << 16; if (t != 0ul) { c -= 16; n = t; } t = n << 8; if (t != 0ul) { c -= 8; n = t; } t = n << 4; if (t != 0ul) { c -= 4; n = t; } t = n << 2; if (t != 0ul) { c -= 2; n = t; } t = n << 1; if (t != 0ul) { c -= 1; } return c; } /// <summary> /// <paramref name="n"/>二進位制尾數0的個數 /// </summary> public static int NumberOfTrailingZeros(this long n) { if (n == 0) return 64; var c = 63; var t = n << 32; if (t != 0L) { c -= 32; n = t; } t = n << 16; if (t != 0L) { c -= 16; n = t; } t = n << 8; if (t != 0L) { c -= 8; n = t; } t = n << 4; if (t != 0L) { c -= 4; n = t; } t = n << 2; if (t != 0L) { c -= 2; n = t; } t = n << 1; if (t != 0L) { c -= 1; } return c; }