├── CHANGES.txt ├── COPYRIGHT ├── MANIFEST ├── README.txt ├── contrib └── bittest.lua ├── dist.info ├── lmod └── bit │ └── numberlua.lua ├── rockspec.in ├── test.lua └── util.mk /CHANGES.txt: -------------------------------------------------------------------------------- 1 | 0.3.1.20120131 2 | Fixed multi-argument BIT.bit band, bor, bxor, and btest. 3 | 4 | 0.3.20111129 5 | Added functions: tobit, tohex, rshift, lshift, arshift, extract, replace, bswap, rrotate, lrotate, rol, ror, btest 6 | Added BIT.bit32 Lua 5.2 compatibility submodule. 7 | Added BIT.bit LuaBitOp compatibility submodule. 8 | Added test suite. 9 | 10 | 0.1.20110911 - initial import 11 | 12 | 0.1.2008 - intial version 13 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | lua-bit-numberlua License 2 | 3 | =============================================================================== 4 | 5 | Copyright (C) 2008, David Manura. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | 25 | =============================================================================== 26 | -------------------------------------------------------------------------------- /MANIFEST: -------------------------------------------------------------------------------- 1 | COPYRIGHT 2 | CHANGES.txt 3 | README.txt 4 | MANIFEST 5 | rockspec.in 6 | dist.info 7 | test.lua 8 | util.mk 9 | lmod/bit/numberlua.lua 10 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | Bitwise operations implemented entirely in Lua. 2 | Includes Lua 5.2 'bit32' and (LuaJIT) LuaBitOp 'bit' compatibility interfaces. 3 | 4 | See comments in lmod/bit/numberlua.lua for details. 5 | -------------------------------------------------------------------------------- /contrib/bittest.lua: -------------------------------------------------------------------------------- 1 | -- This file was taken from LuaBitOp http://bitop.luajit.org/ . 2 | -- Test cases for bit operations library. Public domain. 3 | 4 | local bit = require"bit" 5 | 6 | local vb = { 7 | 0, 1, -1, 2, -2, 0x12345678, 0x87654321, 8 | 0x33333333, 0x77777777, 0x55aa55aa, 0xaa55aa55, 9 | 0x7fffffff, 0x80000000, 0xffffffff 10 | } 11 | 12 | local function cksum(name, s, r) 13 | local z = 0 14 | for i=1,#s do z = (z + string.byte(s, i)*i) % 2147483629 end 15 | if z ~= r then 16 | error("bit."..name.." test failed (got "..z..", expected "..r..")", 0) 17 | end 18 | end 19 | 20 | local function check_unop(name, r) 21 | local f = bit[name] 22 | local s = "" 23 | if pcall(f) or pcall(f, "z") or pcall(f, true) then 24 | error("bit."..name.." fails to detect argument errors", 0) 25 | end 26 | for _,x in ipairs(vb) do s = s..","..tostring(f(x)) end 27 | cksum(name, s, r) 28 | end 29 | 30 | local function check_binop(name, r) 31 | local f = bit[name] 32 | local s = "" 33 | if pcall(f) or pcall(f, "z") or pcall(f, true) then 34 | error("bit."..name.." fails to detect argument errors", 0) 35 | end 36 | for _,x in ipairs(vb) do 37 | for _,y in ipairs(vb) do s = s..","..tostring(f(x, y)) end 38 | end 39 | cksum(name, s, r) 40 | end 41 | 42 | local function check_binop_range(name, r, yb, ye) 43 | local f = bit[name] 44 | local s = "" 45 | if pcall(f) or pcall(f, "z") or pcall(f, true) or pcall(f, 1, true) then 46 | error("bit."..name.." fails to detect argument errors", 0) 47 | end 48 | for _,x in ipairs(vb) do 49 | for y=yb,ye do s = s..","..tostring(f(x, y)) end 50 | end 51 | cksum(name, s, r) 52 | end 53 | 54 | local function check_shift(name, r) 55 | check_binop_range(name, r, 0, 31) 56 | end 57 | 58 | -- Minimal sanity checks. 59 | assert(0x7fffffff == 2147483647, "broken hex literals") 60 | assert(0xffffffff == -1 or 0xffffffff == 2^32-1, "broken hex literals") 61 | assert(tostring(-1) == "-1", "broken tostring()") 62 | assert(tostring(0xffffffff) == "-1" or tostring(0xffffffff) == "4294967295", "broken tostring()") 63 | 64 | -- Basic argument processing. 65 | assert(bit.tobit(1) == 1) 66 | assert(bit.band(1) == 1) 67 | assert(bit.bxor(1,2) == 3) 68 | assert(bit.bor(1,2,4,8,16,32,64,128) == 255) 69 | 70 | -- Apply operations to test vectors and compare checksums. 71 | check_unop("tobit", 277312) 72 | check_unop("bnot", 287870) 73 | check_unop("bswap", 307611) 74 | 75 | check_binop("band", 41206764) 76 | check_binop("bor", 51253663) 77 | check_binop("bxor", 79322427) 78 | 79 | check_shift("lshift", 325260344) 80 | check_shift("rshift", 139061800) 81 | check_shift("arshift", 111364720) 82 | check_shift("rol", 302401155) 83 | check_shift("ror", 302316761) 84 | 85 | check_binop_range("tohex", 47880306, -8, 8) 86 | 87 | -------------------------------------------------------------------------------- /dist.info: -------------------------------------------------------------------------------- 1 | type = [[all]] 2 | arch = [[Universal]] 3 | short = [['bit.numberlua' Bitwise operators in pure Lua using Lua numbers]] 4 | author = [[David Manura]] 5 | full = [[Note: use a C binding instead for higher performance.]] 6 | maintainer = [[David Manura ]] 7 | version = [[$(_VERSION)]] 8 | homepage = [[https://github.com/davidm/lua-bit-numberlua]] 9 | license = [[MIT]] 10 | name = [[bit.numberlua]] 11 | dependencies = { 12 | ['lua'] = [[>=5.1]], 13 | } 14 | 15 | -------------------------------------------------------------------------------- /lmod/bit/numberlua.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 3 | LUA MODULE 4 | 5 | bit.numberlua - Bitwise operations implemented in pure Lua as numbers, 6 | with Lua 5.2 'bit32' and (LuaJIT) LuaBitOp 'bit' compatibility interfaces. 7 | 8 | SYNOPSIS 9 | 10 | local bit = require 'bit.numberlua' 11 | print(bit.band(0xff00ff00, 0x00ff00ff)) --> 0xffffffff 12 | 13 | -- Interface providing strong Lua 5.2 'bit32' compatibility 14 | local bit32 = require 'bit.numberlua'.bit32 15 | assert(bit32.band(-1) == 0xffffffff) 16 | 17 | -- Interface providing strong (LuaJIT) LuaBitOp 'bit' compatibility 18 | local bit = require 'bit.numberlua'.bit 19 | assert(bit.tobit(0xffffffff) == -1) 20 | 21 | DESCRIPTION 22 | 23 | This library implements bitwise operations entirely in Lua. 24 | This module is typically intended if for some reasons you don't want 25 | to or cannot install a popular C based bit library like BitOp 'bit' [1] 26 | (which comes pre-installed with LuaJIT) or 'bit32' (which comes 27 | pre-installed with Lua 5.2) but want a similar interface. 28 | 29 | This modules represents bit arrays as non-negative Lua numbers. [1] 30 | It can represent 32-bit bit arrays when Lua is compiled 31 | with lua_Number as double-precision IEEE 754 floating point. 32 | 33 | The module is nearly the most efficient it can be but may be a few times 34 | slower than the C based bit libraries and is orders or magnitude 35 | slower than LuaJIT bit operations, which compile to native code. Therefore, 36 | this library is inferior in performane to the other modules. 37 | 38 | The `xor` function in this module is based partly on Roberto Ierusalimschy's 39 | post in http://lua-users.org/lists/lua-l/2002-09/msg00134.html . 40 | 41 | The included BIT.bit32 and BIT.bit sublibraries aims to provide 100% 42 | compatibility with the Lua 5.2 "bit32" and (LuaJIT) LuaBitOp "bit" library. 43 | This compatbility is at the cost of some efficiency since inputted 44 | numbers are normalized and more general forms (e.g. multi-argument 45 | bitwise operators) are supported. 46 | 47 | STATUS 48 | 49 | WARNING: Not all corner cases have been tested and documented. 50 | Some attempt was made to make these similar to the Lua 5.2 [2] 51 | and LuaJit BitOp [3] libraries, but this is not fully tested and there 52 | are currently some differences. Addressing these differences may 53 | be improved in the future but it is not yet fully determined how to 54 | resolve these differences. 55 | 56 | The BIT.bit32 library passes the Lua 5.2 test suite (bitwise.lua) 57 | http://www.lua.org/tests/5.2/ . The BIT.bit library passes the LuaBitOp 58 | test suite (bittest.lua). However, these have not been tested on 59 | platforms with Lua compiled with 32-bit integer numbers. 60 | 61 | API 62 | 63 | BIT.tobit(x) --> z 64 | 65 | Similar to function in BitOp. 66 | 67 | BIT.tohex(x, n) 68 | 69 | Similar to function in BitOp. 70 | 71 | BIT.band(x, y) --> z 72 | 73 | Similar to function in Lua 5.2 and BitOp but requires two arguments. 74 | 75 | BIT.bor(x, y) --> z 76 | 77 | Similar to function in Lua 5.2 and BitOp but requires two arguments. 78 | 79 | BIT.bxor(x, y) --> z 80 | 81 | Similar to function in Lua 5.2 and BitOp but requires two arguments. 82 | 83 | BIT.bnot(x) --> z 84 | 85 | Similar to function in Lua 5.2 and BitOp. 86 | 87 | BIT.lshift(x, disp) --> z 88 | 89 | Similar to function in Lua 5.2 (warning: BitOp uses unsigned lower 5 bits of shift), 90 | 91 | BIT.rshift(x, disp) --> z 92 | 93 | Similar to function in Lua 5.2 (warning: BitOp uses unsigned lower 5 bits of shift), 94 | 95 | BIT.extract(x, field [, width]) --> z 96 | 97 | Similar to function in Lua 5.2. 98 | 99 | BIT.replace(x, v, field, width) --> z 100 | 101 | Similar to function in Lua 5.2. 102 | 103 | BIT.bswap(x) --> z 104 | 105 | Similar to function in Lua 5.2. 106 | 107 | BIT.rrotate(x, disp) --> z 108 | BIT.ror(x, disp) --> z 109 | 110 | Similar to function in Lua 5.2 and BitOp. 111 | 112 | BIT.lrotate(x, disp) --> z 113 | BIT.rol(x, disp) --> z 114 | 115 | Similar to function in Lua 5.2 and BitOp. 116 | 117 | BIT.arshift 118 | 119 | Similar to function in Lua 5.2 and BitOp. 120 | 121 | BIT.btest 122 | 123 | Similar to function in Lua 5.2 with requires two arguments. 124 | 125 | BIT.bit32 126 | 127 | This table contains functions that aim to provide 100% compatibility 128 | with the Lua 5.2 "bit32" library. 129 | 130 | bit32.arshift (x, disp) --> z 131 | bit32.band (...) --> z 132 | bit32.bnot (x) --> z 133 | bit32.bor (...) --> z 134 | bit32.btest (...) --> true | false 135 | bit32.bxor (...) --> z 136 | bit32.extract (x, field [, width]) --> z 137 | bit32.replace (x, v, field [, width]) --> z 138 | bit32.lrotate (x, disp) --> z 139 | bit32.lshift (x, disp) --> z 140 | bit32.rrotate (x, disp) --> z 141 | bit32.rshift (x, disp) --> z 142 | 143 | BIT.bit 144 | 145 | This table contains functions that aim to provide 100% compatibility 146 | with the LuaBitOp "bit" library (from LuaJIT). 147 | 148 | bit.tobit(x) --> y 149 | bit.tohex(x [,n]) --> y 150 | bit.bnot(x) --> y 151 | bit.bor(x1 [,x2...]) --> y 152 | bit.band(x1 [,x2...]) --> y 153 | bit.bxor(x1 [,x2...]) --> y 154 | bit.lshift(x, n) --> y 155 | bit.rshift(x, n) --> y 156 | bit.arshift(x, n) --> y 157 | bit.rol(x, n) --> y 158 | bit.ror(x, n) --> y 159 | bit.bswap(x) --> y 160 | 161 | DEPENDENCIES 162 | 163 | None (other than Lua 5.1 or 5.2). 164 | 165 | DOWNLOAD/INSTALLATION 166 | 167 | If using LuaRocks: 168 | luarocks install lua-bit-numberlua 169 | 170 | Otherwise, download . 171 | Alternately, if using git: 172 | git clone git://github.com/davidm/lua-bit-numberlua.git 173 | cd lua-bit-numberlua 174 | Optionally unpack: 175 | ./util.mk 176 | or unpack and install in LuaRocks: 177 | ./util.mk install 178 | 179 | REFERENCES 180 | 181 | [1] http://lua-users.org/wiki/FloatingPoint 182 | [2] http://www.lua.org/manual/5.2/ 183 | [3] http://bitop.luajit.org/ 184 | 185 | LICENSE 186 | 187 | (c) 2008-2011 David Manura. Licensed under the same terms as Lua (MIT). 188 | 189 | Permission is hereby granted, free of charge, to any person obtaining a copy 190 | of this software and associated documentation files (the "Software"), to deal 191 | in the Software without restriction, including without limitation the rights 192 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 193 | copies of the Software, and to permit persons to whom the Software is 194 | furnished to do so, subject to the following conditions: 195 | 196 | The above copyright notice and this permission notice shall be included in 197 | all copies or substantial portions of the Software. 198 | 199 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 200 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 201 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 202 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 203 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 204 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 205 | THE SOFTWARE. 206 | (end license) 207 | 208 | --]] 209 | 210 | local M = {_TYPE='module', _NAME='bit.numberlua', _VERSION='0.3.1.20120131'} 211 | 212 | local floor = math.floor 213 | 214 | local MOD = 2^32 215 | local MODM = MOD-1 216 | 217 | local function memoize(f) 218 | local mt = {} 219 | local t = setmetatable({}, mt) 220 | function mt:__index(k) 221 | local v = f(k); t[k] = v 222 | return v 223 | end 224 | return t 225 | end 226 | 227 | local function make_bitop_uncached(t, m) 228 | local function bitop(a, b) 229 | local res,p = 0,1 230 | while a ~= 0 and b ~= 0 do 231 | local am, bm = a%m, b%m 232 | res = res + t[am][bm]*p 233 | a = (a - am) / m 234 | b = (b - bm) / m 235 | p = p*m 236 | end 237 | res = res + (a+b)*p 238 | return res 239 | end 240 | return bitop 241 | end 242 | 243 | local function make_bitop(t) 244 | local op1 = make_bitop_uncached(t,2^1) 245 | local op2 = memoize(function(a) 246 | return memoize(function(b) 247 | return op1(a, b) 248 | end) 249 | end) 250 | return make_bitop_uncached(op2, 2^(t.n or 1)) 251 | end 252 | 253 | -- ok? probably not if running on a 32-bit int Lua number type platform 254 | function M.tobit(x) 255 | return x % 2^32 256 | end 257 | 258 | M.bxor = make_bitop {[0]={[0]=0,[1]=1},[1]={[0]=1,[1]=0}, n=4} 259 | local bxor = M.bxor 260 | 261 | function M.bnot(a) return MODM - a end 262 | local bnot = M.bnot 263 | 264 | function M.band(a,b) return ((a+b) - bxor(a,b))/2 end 265 | local band = M.band 266 | 267 | function M.bor(a,b) return MODM - band(MODM - a, MODM - b) end 268 | local bor = M.bor 269 | 270 | local lshift, rshift -- forward declare 271 | 272 | function M.rshift(a,disp) -- Lua5.2 insipred 273 | if disp < 0 then return lshift(a,-disp) end 274 | return floor(a % 2^32 / 2^disp) 275 | end 276 | rshift = M.rshift 277 | 278 | function M.lshift(a,disp) -- Lua5.2 inspired 279 | if disp < 0 then return rshift(a,-disp) end 280 | return (a * 2^disp) % 2^32 281 | end 282 | lshift = M.lshift 283 | 284 | function M.tohex(x, n) -- BitOp style 285 | n = n or 8 286 | local up 287 | if n <= 0 then 288 | if n == 0 then return '' end 289 | up = true 290 | n = - n 291 | end 292 | x = band(x, 16^n-1) 293 | return ('%0'..n..(up and 'X' or 'x')):format(x) 294 | end 295 | local tohex = M.tohex 296 | 297 | function M.extract(n, field, width) -- Lua5.2 inspired 298 | width = width or 1 299 | return band(rshift(n, field), 2^width-1) 300 | end 301 | local extract = M.extract 302 | 303 | function M.replace(n, v, field, width) -- Lua5.2 inspired 304 | width = width or 1 305 | local mask1 = 2^width-1 306 | v = band(v, mask1) -- required by spec? 307 | local mask = bnot(lshift(mask1, field)) 308 | return band(n, mask) + lshift(v, field) 309 | end 310 | local replace = M.replace 311 | 312 | function M.bswap(x) -- BitOp style 313 | local a = band(x, 0xff); x = rshift(x, 8) 314 | local b = band(x, 0xff); x = rshift(x, 8) 315 | local c = band(x, 0xff); x = rshift(x, 8) 316 | local d = band(x, 0xff) 317 | return lshift(lshift(lshift(a, 8) + b, 8) + c, 8) + d 318 | end 319 | local bswap = M.bswap 320 | 321 | function M.rrotate(x, disp) -- Lua5.2 inspired 322 | disp = disp % 32 323 | local low = band(x, 2^disp-1) 324 | return rshift(x, disp) + lshift(low, 32-disp) 325 | end 326 | local rrotate = M.rrotate 327 | 328 | function M.lrotate(x, disp) -- Lua5.2 inspired 329 | return rrotate(x, -disp) 330 | end 331 | local lrotate = M.lrotate 332 | 333 | M.rol = M.lrotate -- LuaOp inspired 334 | M.ror = M.rrotate -- LuaOp insipred 335 | 336 | 337 | function M.arshift(x, disp) -- Lua5.2 inspired 338 | local z = rshift(x, disp) 339 | if x >= 0x80000000 then z = z + lshift(2^disp-1, 32-disp) end 340 | return z 341 | end 342 | local arshift = M.arshift 343 | 344 | function M.btest(x, y) -- Lua5.2 inspired 345 | return band(x, y) ~= 0 346 | end 347 | 348 | -- 349 | -- Start Lua 5.2 "bit32" compat section. 350 | -- 351 | 352 | M.bit32 = {} -- Lua 5.2 'bit32' compatibility 353 | 354 | 355 | local function bit32_bnot(x) 356 | return (-1 - x) % MOD 357 | end 358 | M.bit32.bnot = bit32_bnot 359 | 360 | local function bit32_bxor(a, b, c, ...) 361 | local z 362 | if b then 363 | a = a % MOD 364 | b = b % MOD 365 | z = bxor(a, b) 366 | if c then 367 | z = bit32_bxor(z, c, ...) 368 | end 369 | return z 370 | elseif a then 371 | return a % MOD 372 | else 373 | return 0 374 | end 375 | end 376 | M.bit32.bxor = bit32_bxor 377 | 378 | local function bit32_band(a, b, c, ...) 379 | local z 380 | if b then 381 | a = a % MOD 382 | b = b % MOD 383 | z = ((a+b) - bxor(a,b)) / 2 384 | if c then 385 | z = bit32_band(z, c, ...) 386 | end 387 | return z 388 | elseif a then 389 | return a % MOD 390 | else 391 | return MODM 392 | end 393 | end 394 | M.bit32.band = bit32_band 395 | 396 | local function bit32_bor(a, b, c, ...) 397 | local z 398 | if b then 399 | a = a % MOD 400 | b = b % MOD 401 | z = MODM - band(MODM - a, MODM - b) 402 | if c then 403 | z = bit32_bor(z, c, ...) 404 | end 405 | return z 406 | elseif a then 407 | return a % MOD 408 | else 409 | return 0 410 | end 411 | end 412 | M.bit32.bor = bit32_bor 413 | 414 | function M.bit32.btest(...) 415 | return bit32_band(...) ~= 0 416 | end 417 | 418 | function M.bit32.lrotate(x, disp) 419 | return lrotate(x % MOD, disp) 420 | end 421 | 422 | function M.bit32.rrotate(x, disp) 423 | return rrotate(x % MOD, disp) 424 | end 425 | 426 | function M.bit32.lshift(x,disp) 427 | if disp > 31 or disp < -31 then return 0 end 428 | return lshift(x % MOD, disp) 429 | end 430 | 431 | function M.bit32.rshift(x,disp) 432 | if disp > 31 or disp < -31 then return 0 end 433 | return rshift(x % MOD, disp) 434 | end 435 | 436 | function M.bit32.arshift(x,disp) 437 | x = x % MOD 438 | if disp >= 0 then 439 | if disp > 31 then 440 | return (x >= 0x80000000) and MODM or 0 441 | else 442 | local z = rshift(x, disp) 443 | if x >= 0x80000000 then z = z + lshift(2^disp-1, 32-disp) end 444 | return z 445 | end 446 | else 447 | return lshift(x, -disp) 448 | end 449 | end 450 | 451 | function M.bit32.extract(x, field, ...) 452 | local width = ... or 1 453 | if field < 0 or field > 31 or width < 0 or field+width > 32 then error 'out of range' end 454 | x = x % MOD 455 | return extract(x, field, ...) 456 | end 457 | 458 | function M.bit32.replace(x, v, field, ...) 459 | local width = ... or 1 460 | if field < 0 or field > 31 or width < 0 or field+width > 32 then error 'out of range' end 461 | x = x % MOD 462 | v = v % MOD 463 | return replace(x, v, field, ...) 464 | end 465 | 466 | 467 | -- 468 | -- Start LuaBitOp "bit" compat section. 469 | -- 470 | 471 | M.bit = {} -- LuaBitOp "bit" compatibility 472 | 473 | function M.bit.tobit(x) 474 | x = x % MOD 475 | if x >= 0x80000000 then x = x - MOD end 476 | return x 477 | end 478 | local bit_tobit = M.bit.tobit 479 | 480 | function M.bit.tohex(x, ...) 481 | return tohex(x % MOD, ...) 482 | end 483 | 484 | function M.bit.bnot(x) 485 | return bit_tobit(bnot(x % MOD)) 486 | end 487 | 488 | local function bit_bor(a, b, c, ...) 489 | if c then 490 | return bit_bor(bit_bor(a, b), c, ...) 491 | elseif b then 492 | return bit_tobit(bor(a % MOD, b % MOD)) 493 | else 494 | return bit_tobit(a) 495 | end 496 | end 497 | M.bit.bor = bit_bor 498 | 499 | local function bit_band(a, b, c, ...) 500 | if c then 501 | return bit_band(bit_band(a, b), c, ...) 502 | elseif b then 503 | return bit_tobit(band(a % MOD, b % MOD)) 504 | else 505 | return bit_tobit(a) 506 | end 507 | end 508 | M.bit.band = bit_band 509 | 510 | local function bit_bxor(a, b, c, ...) 511 | if c then 512 | return bit_bxor(bit_bxor(a, b), c, ...) 513 | elseif b then 514 | return bit_tobit(bxor(a % MOD, b % MOD)) 515 | else 516 | return bit_tobit(a) 517 | end 518 | end 519 | M.bit.bxor = bit_bxor 520 | 521 | function M.bit.lshift(x, n) 522 | return bit_tobit(lshift(x % MOD, n % 32)) 523 | end 524 | 525 | function M.bit.rshift(x, n) 526 | return bit_tobit(rshift(x % MOD, n % 32)) 527 | end 528 | 529 | function M.bit.arshift(x, n) 530 | return bit_tobit(arshift(x % MOD, n % 32)) 531 | end 532 | 533 | function M.bit.rol(x, n) 534 | return bit_tobit(lrotate(x % MOD, n % 32)) 535 | end 536 | 537 | function M.bit.ror(x, n) 538 | return bit_tobit(rrotate(x % MOD, n % 32)) 539 | end 540 | 541 | function M.bit.bswap(x) 542 | return bit_tobit(bswap(x % MOD)) 543 | end 544 | 545 | return M 546 | -------------------------------------------------------------------------------- /rockspec.in: -------------------------------------------------------------------------------- 1 | package = "lua-bit-numberlua" 2 | version = "$(_VERSION)-$(ROCKVERSION)" 3 | source = { 4 | --url = "https://github.com/davidm/lua-bit-numberlua/zipball/v$(_VERSION)", 5 | url = "git://github.com/davidm/lua-bit-numberlua.git", 6 | tag='v$(_VERSION)-$(ROCKVERSION)' 7 | } 8 | description = { 9 | summary = "Bitwise operators in pure Lua using Lua numbers", 10 | detailed = [[ 11 | Note: use a C binding instead for higher performance. 12 | ]], 13 | license = "MIT/X11", 14 | homepage = "https://github.com/davidm/lua-bit-numberlua", 15 | maintainer = "David Manura ", 16 | } 17 | dependencies = { 18 | "lua >= 5.1" -- including 5.2 19 | } 20 | build = { 21 | type = "none", 22 | install = { 23 | lua = { 24 | ["bit.numberlua"] = "lmod/bit/numberlua.lua", 25 | } 26 | } 27 | } 28 | -- VERSIONFROM="lmod/bit/numberlua.lua" 29 | -- ROCKVERSION="1" 30 | -- ROCKSCMVERSION="1" 31 | -------------------------------------------------------------------------------- /test.lua: -------------------------------------------------------------------------------- 1 | -- tests of bit.numberlua' 2 | 3 | package.path = 'lmod/?.lua;' .. package.path 4 | local bit = require 'bit.numberlua' 5 | 6 | local function mystr(o) 7 | if type(o) == 'number' then return '0x'..bit.tohex(o) 8 | else return tostring(o) end 9 | end 10 | local function checkeq(a, b) 11 | if a ~= b then error('not equal\n'..mystr(a)..'\n'..mystr(b), 2) end 12 | end 13 | 14 | -- bit.tobit (not necessarily the same as BitOp currently) 15 | -- examples on http://bitop.luajit.org/api.html 16 | checkeq(bit.tobit(0xffffffff), 0xffffffff) --> -1 * 17 | checkeq(bit.tobit(0xffffffff + 1), 0) --> 0 18 | checkeq(bit.tobit(2^40 + 1234), 1234) --> 1234 19 | 20 | -- bit.tohex 21 | checkeq(bit.tohex(0), '00000000') 22 | checkeq(bit.tohex(0, 1), '0') 23 | -- examples on http://bitop.luajit.org/api.html 24 | checkeq(bit.tohex(1), '00000001') 25 | checkeq(bit.tohex(-1), 'ffffffff') 26 | checkeq(bit.tohex(0xffffffff), 'ffffffff') 27 | checkeq(bit.tohex(-1, -8), 'FFFFFFFF') 28 | checkeq(bit.tohex(0x21, 4), '0021') 29 | checkeq(bit.tohex(0x87654321, 4), '4321') 30 | 31 | -- bit.bnot 32 | checkeq(bit.bnot(0), 0xffffffff) 33 | checkeq(bit.bnot(1), 0xfffffffe) 34 | --checkeq(bit.bnot(-1), 0) --should it normalize? 35 | checkeq(bit.bnot(0xffffffff), 0) 36 | checkeq(bit.bnot(0x13579bdf), 0xeca86420) 37 | 38 | -- bit.band 39 | checkeq(bit.band(0,0), 0) 40 | checkeq(bit.band(0xffffffff,0xffffffff), 0xffffffff) 41 | checkeq(bit.band(0xffffffff,0), 0) 42 | checkeq(bit.band(0xa207f158,0x2e1054c9), 0x22005048) 43 | -- note: multiple args not currently supported 44 | 45 | -- bit.btest 46 | checkeq(bit.btest(0,0), false) 47 | checkeq(bit.btest(0xf000,0xf000), true) 48 | checkeq(bit.btest(0xffffffff,0), false) 49 | 50 | --- bit.bor 51 | checkeq(bit.bor(0,0), 0) 52 | checkeq(bit.bor(0xffffffff,0xffffffff), 0xffffffff) 53 | checkeq(bit.bor(0xffffffff,0), 0xffffffff) 54 | checkeq(bit.bor(0xa207f158,0x2e1054c9), 0xae17f5d9) 55 | -- note: multiple args not currently supported 56 | 57 | -- bit.bxor 58 | checkeq(bit.bxor(0,0), 0) 59 | checkeq(bit.bxor(0xffffffff,0xffffffff), 0) 60 | checkeq(bit.bxor(0xffffffff,0), 0xffffffff) 61 | checkeq(bit.bxor(0xa207f158,0x2e1054c9), 0x8c17a591) 62 | 63 | -- bit.extract 64 | checkeq(bit.extract(0, 0), 0) 65 | checkeq(bit.extract(0, 31,31), 0) 66 | checkeq(bit.extract(0xabcd, 4,8), 0xbc) 67 | checkeq(bit.extract(0xabcd, 0,32), 0xabcd) 68 | 69 | -- bit.replace 70 | checkeq(bit.replace(0xabcd, 0xe, 4,8), 0xa0ed) 71 | checkeq(bit.replace(0xabcd, 0, 0), 0xabcc) 72 | checkeq(bit.replace(0xabcc, 1, 0), 0xabcd) 73 | checkeq(bit.replace(0x2bcdefef, 1, 31), 0xabcdefef) 74 | checkeq(bit.replace(0xabcdefef, 0, 31), 0x2bcdefef) 75 | 76 | -- bit.rol, bit.ror 77 | -- examples on http://bitop.luajit.org/api.html 78 | checkeq(bit.rol(0x12345678, 12), 0x45678123) 79 | checkeq(bit.ror(0x12345678, 12), 0x67812345) 80 | 81 | -- bit.lrotate, bit.rrotate 82 | checkeq(bit.rol, bit.lrotate) 83 | checkeq(bit.ror, bit.rrotate) 84 | 85 | -- bit.bswap 86 | -- examples on http://bitop.luajit.org/api.html 87 | checkeq(bit.bswap(0x12345678), 0x78563412) 88 | checkeq(bit.bswap(0x78563412), 0x12345678) 89 | 90 | -- bit.arshift 91 | checkeq(bit.arshift(0, 0), 0) 92 | checkeq(bit.arshift(0xffffffff, 0), 0xffffffff) 93 | checkeq(bit.arshift(0xffffffff, 4), 0xffffffff) 94 | checkeq(bit.arshift(0xffffffff, 32), 0xffffffff) 95 | checkeq(bit.arshift(0x7fffffff, 4), 0x07ffffff) 96 | checkeq(bit.arshift(0x7fffffff, 31), 0) 97 | checkeq(bit.arshift(0x7fffffff, 32), 0) 98 | 99 | -- BIT.bit32. 100 | -- Optionally run bitwise.lua from Lua test suite. 101 | -- http://www.lua.org/tests/5.2/ 102 | if TEST_BIT32 then 103 | _G.bit32 = require 'bit.numberlua' . bit32 104 | dofile 'contrib/bitwise.lua' 105 | end 106 | -- additional tests: 107 | -- trigger recursion... (once broken) 108 | checkeq(bit.bit32.bor (1,2,4,8,16,2^30,2^31), 0xc000001f) 109 | checkeq(bit.bit32.bxor(1,2,4,8,16,2^30,2^31), 0xc000001f) 110 | checkeq(bit.bit32.bxor(-1,-1,-1,-1,-1), 2^32-1) 111 | checkeq(bit.bit32.band(255,255*2,255*4,255*8,255*16), 255-15) 112 | 113 | -- BIT.bit 114 | -- Optionally run bittest.lua (included) from LuaBitOp test suite. 115 | -- http://bitop.luajit.org/ 116 | --if TEST_BIT then 117 | package.loaded.bit = bit.bit 118 | dofile 'contrib/bittest.lua' 119 | --end 120 | 121 | -- BIT.bit. 122 | 123 | 124 | print 'DONE' 125 | -------------------------------------------------------------------------------- /util.mk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # utility commands for package maintainers 3 | # D.Manura, This util.mk file is public domain. 4 | 5 | VERSIONFROM:=$(shell sed -n 's,.*VERSIONFROM *= *[\"]\(.*\)[\"],\1,p' rockspec.in) 6 | ROCKVERSION:=$(shell sed -n 's,.*ROCKVERSION *= *[\"]\(.*\)[\"],\1,p' rockspec.in) 7 | ROCKSCMVERSION:=$(shell sed -n 's,.*ROCKSCMVERSION *= *[\"]\(.*\)[\"],\1,p' rockspec.in) 8 | VERSION:=$(shell sed -n "s,.*_VERSION='\([^']*\)'.*,\1,p" $(VERSIONFROM)) 9 | SCMVERSION:=scm 10 | NAME:=$(shell sed -n 's,.*package *= *[\"]\(.*\)[\"],\1,p' rockspec.in) 11 | #NAME=$(shell lua -e 'dofile"rockspec.in"; print(package)') 12 | 13 | dist : version 14 | rm -fr tmp/ 15 | for x in `cat MANIFEST`; do install -D $$x tmp/$(NAME)-$(VERSION)-$(ROCKVERSION)/$$x || exit; done 16 | cat rockspec.in | \ 17 | sed 's,$$(_VERSION),$(VERSION),g' | \ 18 | sed 's,$$(ROCKVERSION),$(ROCKVERSION),g' | \ 19 | sed 's,^--URL=, url=,' > tmp/$(NAME)-$(VERSION)-$(ROCKVERSION).rockspec 20 | cat rockspec.in | \ 21 | sed 's,$$(_VERSION),$(SCMVERSION),g' | \ 22 | sed 's,$$(ROCKVERSION),$(ROCKSCMVERSION),g' | \ 23 | sed 's,^--URLSCM=, url=,' | \ 24 | sed '/tag *= */d' > tmp/$(NAME)-$(SCMVERSION)-$(ROCKSCMVERSION).rockspec 25 | cp tmp/$(NAME)-$(VERSION)-$(ROCKVERSION).rockspec tmp/$(NAME)-$(VERSION)-$(ROCKVERSION)/ 26 | cp tmp/$(NAME)-$(SCMVERSION)-$(ROCKSCMVERSION).rockspec tmp/$(NAME)-$(VERSION)-$(ROCKVERSION)/ 27 | cd tmp && zip -r $(NAME)-$(VERSION)-$(ROCKVERSION).zip $(NAME)-$(VERSION)-$(ROCKVERSION) 28 | 29 | install : dist 30 | cd tmp/$(NAME)-$(VERSION)-$(ROCKVERSION) && luarocks make 31 | 32 | test : 33 | @if [ -e test.lua ]; then lua test.lua; fi 34 | @if [ -e test/test.lua ]; then lua test/test.lua; fi 35 | 36 | tag : 37 | git tag -f v$(VERSION)-$(ROCKVERSION) 38 | 39 | version : 40 | @echo $(NAME)-$(VERSION)-$(ROCKVERSION) 41 | @echo $(NAME)-$(SCMVERSION)-$(ROCKSCMVERSION) 42 | 43 | .PHONY : dist install test tag version 44 | --------------------------------------------------------------------------------