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