pmath.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. package pmath
  2. const (
  3. bitsize = 32 << (^uint(0) >> 63)
  4. maxint = int(1<<(bitsize-1) - 1)
  5. maxintHeadBit = 1 << (bitsize - 2)
  6. )
  7. // LogarithmicRange iterates from ceiled to power of two min to max,
  8. // calling cb on each iteration.
  9. func LogarithmicRange(min, max int, cb func(int)) {
  10. if min == 0 {
  11. min = 1
  12. }
  13. for n := CeilToPowerOfTwo(min); n <= max; n <<= 1 {
  14. cb(n)
  15. }
  16. }
  17. // IsPowerOfTwo reports whether given integer is a power of two.
  18. func IsPowerOfTwo(n int) bool {
  19. return n&(n-1) == 0
  20. }
  21. // Identity is identity.
  22. func Identity(n int) int {
  23. return n
  24. }
  25. // CeilToPowerOfTwo returns the least power of two integer value greater than
  26. // or equal to n.
  27. func CeilToPowerOfTwo(n int) int {
  28. if n&maxintHeadBit != 0 && n > maxintHeadBit {
  29. panic("argument is too large")
  30. }
  31. if n <= 2 {
  32. return n
  33. }
  34. n--
  35. n = fillBits(n)
  36. n++
  37. return n
  38. }
  39. // FloorToPowerOfTwo returns the greatest power of two integer value less than
  40. // or equal to n.
  41. func FloorToPowerOfTwo(n int) int {
  42. if n <= 2 {
  43. return n
  44. }
  45. n = fillBits(n)
  46. n >>= 1
  47. n++
  48. return n
  49. }
  50. func fillBits(n int) int {
  51. n |= n >> 1
  52. n |= n >> 2
  53. n |= n >> 4
  54. n |= n >> 8
  55. n |= n >> 16
  56. n |= n >> 32
  57. return n
  58. }