PageRenderTime 19ms CodeModel.GetById 14ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 0ms

/luabit.lua

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