You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
1.5 KiB

  1. // Copyright 2013 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package intsets
  5. // From Hacker's Delight, fig 5.2.
  6. func popcountHD(x uint32) int {
  7. x -= (x >> 1) & 0x55555555
  8. x = (x & 0x33333333) + ((x >> 2) & 0x33333333)
  9. x = (x + (x >> 4)) & 0x0f0f0f0f
  10. x = x + (x >> 8)
  11. x = x + (x >> 16)
  12. return int(x & 0x0000003f)
  13. }
  14. var a [1 << 8]byte
  15. func init() {
  16. for i := range a {
  17. var n byte
  18. for x := i; x != 0; x >>= 1 {
  19. if x&1 != 0 {
  20. n++
  21. }
  22. }
  23. a[i] = n
  24. }
  25. }
  26. func popcountTable(x word) int {
  27. return int(a[byte(x>>(0*8))] +
  28. a[byte(x>>(1*8))] +
  29. a[byte(x>>(2*8))] +
  30. a[byte(x>>(3*8))] +
  31. a[byte(x>>(4*8))] +
  32. a[byte(x>>(5*8))] +
  33. a[byte(x>>(6*8))] +
  34. a[byte(x>>(7*8))])
  35. }
  36. // nlz returns the number of leading zeros of x.
  37. // From Hacker's Delight, fig 5.11.
  38. func nlz(x word) int {
  39. x |= (x >> 1)
  40. x |= (x >> 2)
  41. x |= (x >> 4)
  42. x |= (x >> 8)
  43. x |= (x >> 16)
  44. x |= (x >> 32)
  45. return popcount(^x)
  46. }
  47. // ntz returns the number of trailing zeros of x.
  48. // From Hacker's Delight, fig 5.13.
  49. func ntz(x word) int {
  50. if x == 0 {
  51. return bitsPerWord
  52. }
  53. n := 1
  54. if bitsPerWord == 64 {
  55. if (x & 0xffffffff) == 0 {
  56. n = n + 32
  57. x = x >> 32
  58. }
  59. }
  60. if (x & 0x0000ffff) == 0 {
  61. n = n + 16
  62. x = x >> 16
  63. }
  64. if (x & 0x000000ff) == 0 {
  65. n = n + 8
  66. x = x >> 8
  67. }
  68. if (x & 0x0000000f) == 0 {
  69. n = n + 4
  70. x = x >> 4
  71. }
  72. if (x & 0x00000003) == 0 {
  73. n = n + 2
  74. x = x >> 2
  75. }
  76. return n - int(x&1)
  77. }