/luabit.lua
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