/luabit.lua

http://github.com/kengonakajima/lua-msgpack · Lua · 254 lines · 157 code · 43 blank · 54 comment · 28 complexity · 3e47f87c2e9001777a84d78bfccc3615 MD5 · raw file

  1. --[[---------------
  2. LuaBit v0.4
  3. -------------------
  4. a bitwise operation lib for lua.
  5. http://luaforge.net/projects/bit/
  6. How to use:
  7. -------------------
  8. bit.bnot(n) -- bitwise not (~n)
  9. bit.band(m, n) -- bitwise and (m & n)
  10. bit.bor(m, n) -- bitwise or (m | n)
  11. bit.bxor(m, n) -- bitwise xor (m ^ n)
  12. bit.brshift(n, bits) -- right shift (n >> bits)
  13. bit.blshift(n, bits) -- left shift (n << bits)
  14. bit.blogic_rshift(n, bits) -- logic right shift(zero fill >>>)
  15. Please note that bit.brshift and bit.blshift only support number within
  16. 32 bits.
  17. 2 utility functions are provided too:
  18. bit.tobits(n) -- convert n into a bit table(which is a 1/0 sequence)
  19. -- high bits first
  20. bit.tonumb(bit_tbl) -- convert a bit table into a number
  21. -------------------
  22. Under the MIT license.
  23. copyright(c) 2006~2007 hanzhao (abrash_han@hotmail.com)
  24. --]]---------------
  25. ------------------------
  26. -- bit lib implementions
  27. local function check_int(n)
  28. -- checking not float
  29. if(n - math.floor(n) > 0) then
  30. error("trying to use bitwise operation on non-integer!")
  31. end
  32. end
  33. local function to_bits(n)
  34. check_int(n)
  35. if(n < 0) then
  36. -- negative
  37. return to_bits(bit.bnot(math.abs(n)) + 1)
  38. end
  39. -- to bits table
  40. local tbl = {}
  41. local cnt = 1
  42. while (n > 0) do
  43. local last = math.mod(n,2)
  44. if(last == 1) then
  45. tbl[cnt] = 1
  46. else
  47. tbl[cnt] = 0
  48. end
  49. n = (n-last)/2
  50. cnt = cnt + 1
  51. end
  52. return tbl
  53. end
  54. local function tbl_to_number(tbl)
  55. local n = table.getn(tbl)
  56. local rslt = 0
  57. local power = 1
  58. for i = 1, n do
  59. rslt = rslt + tbl[i]*power
  60. power = power*2
  61. end
  62. return rslt
  63. end
  64. local function expand(tbl_m, tbl_n)
  65. local big = {}
  66. local small = {}
  67. if(table.getn(tbl_m) > table.getn(tbl_n)) then
  68. big = tbl_m
  69. small = tbl_n
  70. else
  71. big = tbl_n
  72. small = tbl_m
  73. end
  74. -- expand small
  75. for i = table.getn(small) + 1, table.getn(big) do
  76. small[i] = 0
  77. end
  78. end
  79. local function bit_or(m, n)
  80. local tbl_m = to_bits(m)
  81. local tbl_n = to_bits(n)
  82. expand(tbl_m, tbl_n)
  83. local tbl = {}
  84. local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))
  85. for i = 1, rslt do
  86. if(tbl_m[i]== 0 and tbl_n[i] == 0) then
  87. tbl[i] = 0
  88. else
  89. tbl[i] = 1
  90. end
  91. end
  92. return tbl_to_number(tbl)
  93. end
  94. local function bit_and(m, n)
  95. local tbl_m = to_bits(m)
  96. local tbl_n = to_bits(n)
  97. expand(tbl_m, tbl_n)
  98. local tbl = {}
  99. local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))
  100. for i = 1, rslt do
  101. if(tbl_m[i]== 0 or tbl_n[i] == 0) then
  102. tbl[i] = 0
  103. else
  104. tbl[i] = 1
  105. end
  106. end
  107. return tbl_to_number(tbl)
  108. end
  109. local function bit_not(n)
  110. local tbl = to_bits(n)
  111. local size = math.max(table.getn(tbl), 32)
  112. for i = 1, size do
  113. if(tbl[i] == 1) then
  114. tbl[i] = 0
  115. else
  116. tbl[i] = 1
  117. end
  118. end
  119. return tbl_to_number(tbl)
  120. end
  121. local function bit_xor(m, n)
  122. local tbl_m = to_bits(m)
  123. local tbl_n = to_bits(n)
  124. expand(tbl_m, tbl_n)
  125. local tbl = {}
  126. local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))
  127. for i = 1, rslt do
  128. if(tbl_m[i] ~= tbl_n[i]) then
  129. tbl[i] = 1
  130. else
  131. tbl[i] = 0
  132. end
  133. end
  134. --table.foreach(tbl, print)
  135. return tbl_to_number(tbl)
  136. end
  137. local function bit_rshift(n, bits)
  138. check_int(n)
  139. local high_bit = 0
  140. if(n < 0) then
  141. -- negative
  142. n = bit_not(math.abs(n)) + 1
  143. high_bit = 2147483648 -- 0x80000000
  144. end
  145. for i=1, bits do
  146. n = n/2
  147. n = bit_or(math.floor(n), high_bit)
  148. end
  149. return math.floor(n)
  150. end
  151. -- logic rightshift assures zero filling shift
  152. local function bit_logic_rshift(n, bits)
  153. check_int(n)
  154. if(n < 0) then
  155. -- negative
  156. n = bit_not(math.abs(n)) + 1
  157. end
  158. for i=1, bits do
  159. n = n/2
  160. end
  161. return math.floor(n)
  162. end
  163. local function bit_lshift(n, bits)
  164. check_int(n)
  165. if(n < 0) then
  166. -- negative
  167. n = bit_not(math.abs(n)) + 1
  168. end
  169. for i=1, bits do
  170. n = n*2
  171. end
  172. return bit_and(n, 4294967295) -- 0xFFFFFFFF
  173. end
  174. local function bit_xor2(m, n)
  175. local rhs = bit_or(bit_not(m), bit_not(n))
  176. local lhs = bit_or(m, n)
  177. local rslt = bit_and(lhs, rhs)
  178. return rslt
  179. end
  180. --------------------
  181. -- bit lib interface
  182. local bit = {
  183. -- bit operations
  184. bnot = bit_not,
  185. band = bit_and,
  186. bor = bit_or,
  187. bxor = bit_xor,
  188. brshift = bit_rshift,
  189. blshift = bit_lshift,
  190. bxor2 = bit_xor2,
  191. blogic_rshift = bit_logic_rshift,
  192. -- utility func
  193. tobits = to_bits,
  194. tonumb = tbl_to_number,
  195. }
  196. return bit
  197. --[[
  198. for i = 1, 100 do
  199. for j = 1, 100 do
  200. if(bit.bxor(i, j) ~= bit.bxor2(i, j)) then
  201. error("bit.xor failed.")
  202. end
  203. end
  204. end
  205. --]]