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
312013-02-20: Brad Jorsch: Fix to not try messing with globals, doesn't work in Scribunto
32--]]---------------
33
34do
35
36------------------------
37-- bit lib implementions
38
39local function check_int(n)
40 -- checking not float
41 if(n - math.floor(n) > 0) then
42  error("trying to use bitwise operation on non-integer!")
43 end
44end
45
46local function to_bits(n)
47 check_int(n)
48 if(n < 0) then
49  -- negative
50  return to_bits(bit.bnot(math.abs(n)) + 1)
51 end
52 -- to bits table
53 local tbl = {}
54 local cnt = 1
55 while (n > 0) do
56  local last = math.mod(n,2)
57  if(last == 1) then
58   tbl[cnt] = 1
59  else
60   tbl[cnt] = 0
61  end
62  n = (n-last)/2
63  cnt = cnt + 1
64 end
65
66 return tbl
67end
68
69local function tbl_to_number(tbl)
70 local n = table.getn(tbl)
71
72 local rslt = 0
73 local power = 1
74 for i = 1, n do
75  rslt = rslt + tbl[i]*power
76  power = power*2
77 end
78
79 return rslt
80end
81
82local function expand(tbl_m, tbl_n)
83 local big = {}
84 local small = {}
85 if(table.getn(tbl_m) > table.getn(tbl_n)) then
86  big = tbl_m
87  small = tbl_n
88 else
89  big = tbl_n
90  small = tbl_m
91 end
92 -- expand small
93 for i = table.getn(small) + 1, table.getn(big) do
94  small[i] = 0
95 end
96
97end
98
99local function bit_or(m, n)
100 local tbl_m = to_bits(m)
101 local tbl_n = to_bits(n)
102 expand(tbl_m, tbl_n)
103
104 local tbl = {}
105 local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))
106 for i = 1, rslt do
107  if(tbl_m[i]== 0 and tbl_n[i] == 0) then
108   tbl[i] = 0
109  else
110   tbl[i] = 1
111  end
112 end
113
114 return tbl_to_number(tbl)
115end
116
117local function bit_and(m, n)
118 local tbl_m = to_bits(m)
119 local tbl_n = to_bits(n)
120 expand(tbl_m, tbl_n)
121
122 local tbl = {}
123 local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))
124 for i = 1, rslt do
125  if(tbl_m[i]== 0 or tbl_n[i] == 0) then
126   tbl[i] = 0
127  else
128   tbl[i] = 1
129  end
130 end
131
132 return tbl_to_number(tbl)
133end
134
135local function bit_not(n)
136
137 local tbl = to_bits(n)
138 local size = math.max(table.getn(tbl), 32)
139 for i = 1, size do
140  if(tbl[i] == 1) then
141   tbl[i] = 0
142  else
143   tbl[i] = 1
144  end
145 end
146 return tbl_to_number(tbl)
147end
148
149local function bit_xor(m, n)
150 local tbl_m = to_bits(m)
151 local tbl_n = to_bits(n)
152 expand(tbl_m, tbl_n)
153
154 local tbl = {}
155 local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))
156 for i = 1, rslt do
157  if(tbl_m[i] ~= tbl_n[i]) then
158   tbl[i] = 1
159  else
160   tbl[i] = 0
161  end
162 end
163
164 --table.foreach(tbl, print)
165
166 return tbl_to_number(tbl)
167end
168
169local function bit_rshift(n, bits)
170 check_int(n)
171
172 local high_bit = 0
173 if(n < 0) then
174  -- negative
175  n = bit_not(math.abs(n)) + 1
176  high_bit = 2147483648 -- 0x80000000
177 end
178
179 for i=1, bits do
180  n = n/2
181  n = bit_or(math.floor(n), high_bit)
182 end
183 return math.floor(n)
184end
185
186-- logic rightshift assures zero filling shift
187local function bit_logic_rshift(n, bits)
188 check_int(n)
189 if(n < 0) then
190  -- negative
191  n = bit_not(math.abs(n)) + 1
192 end
193 for i=1, bits do
194  n = n/2
195 end
196 return math.floor(n)
197end
198
199local function bit_lshift(n, bits)
200 check_int(n)
201
202 if(n < 0) then
203  -- negative
204  n = bit_not(math.abs(n)) + 1
205 end
206
207 for i=1, bits do
208  n = n*2
209 end
210 return bit_and(n, 4294967295) -- 0xFFFFFFFF
211end
212
213local function bit_xor2(m, n)
214 local rhs = bit_or(bit_not(m), bit_not(n))
215 local lhs = bit_or(m, n)
216 local rslt = bit_and(lhs, rhs)
217 return rslt
218end
219
220--------------------
221-- bit lib interface
222
223local bit = {
224 -- bit operations
225 bnot = bit_not,
226 band = bit_and,
227 bor  = bit_or,
228 bxor = bit_xor,
229 brshift = bit_rshift,
230 blshift = bit_lshift,
231 bxor2 = bit_xor2,
232 blogic_rshift = bit_logic_rshift,
233
234 -- utility func
235 tobits = to_bits,
236 tonumb = tbl_to_number,
237}
238
239return bit
240
241end
242
243--[[
244for i = 1, 100 do
245 for j = 1, 100 do
246  if(bit.bxor(i, j) ~= bit.bxor2(i, j)) then
247   error("bit.xor failed.")
248  end
249 end
250end
251--]]
252
253
254
255
256
257
258
259
260
261
262
263
264
265