LuaBitOp-1.0.2/0000755000175000017500000000000011752270264011633 5ustar mikemikeLuaBitOp-1.0.2/Makefile0000644000175000017500000000256711752270264013305 0ustar mikemike# Makefile for Lua BitOp -- a bit operations library for Lua 5.1/5.2. # To compile with MSVC please run: msvcbuild.bat # To compile with MinGW please run: mingw32-make -f Makefile.mingw # Include path where lua.h, luaconf.h and lauxlib.h reside: INCLUDES= -I/usr/local/include DEFINES= # Use this for the old ARM ABI with swapped FPA doubles. # Do NOT use this for modern ARM EABI with VFP or soft-float! #DEFINES= -DSWAPPED_DOUBLE # Lua executable name. Used to find the install path and for testing. LUA= lua CC= gcc CCOPT= -O2 -fomit-frame-pointer CCWARN= -Wall SOCC= $(CC) -shared SOCFLAGS= -fPIC $(CCOPT) $(CCWARN) $(DEFINES) $(INCLUDES) $(CFLAGS) SOLDFLAGS= -fPIC $(LDFLAGS) RM= rm -f INSTALL= install -p INSTALLPATH= $(LUA) installpath.lua MODNAME= bit MODSO= $(MODNAME).so all: $(MODSO) # Alternative target for compiling on Mac OS X: macosx: $(MAKE) all "SOCC=MACOSX_DEPLOYMENT_TARGET=10.4 $(CC) -dynamiclib -single_module -undefined dynamic_lookup" $(MODNAME).o: $(MODNAME).c $(CC) $(SOCFLAGS) -c -o $@ $< $(MODSO): $(MODNAME).o $(SOCC) $(SOLDFLAGS) -o $@ $< install: $(MODSO) $(INSTALL) $< `$(INSTALLPATH) $(MODNAME)` test: $(MODSO) @$(LUA) bittest.lua && echo "basic test OK" @$(LUA) nsievebits.lua && echo "nsievebits test OK" @$(LUA) md5test.lua && echo "MD5 test OK" clean: $(RM) *.o *.so *.obj *.lib *.exp *.dll *.manifest .PHONY: all macosx install test clean LuaBitOp-1.0.2/Makefile.mingw0000644000175000017500000000223211752270264014412 0ustar mikemike# Makefile for Lua BitOp -- a bit operations library for Lua 5.1/5.2. # This is a modified Makefile for MinGW. C:\MinGW\bin must be in your PATH. # Compile: mingw32-make -f Makefile.mingw # Install: mingw32-make -f Makefile.mingw install # Lua executable name. Used for testing. LUA= lua # Include path where lua.h, luaconf.h and lauxlib.h reside: INCLUDES= "-I.." # Path of lua51.dll: LUADLLPATH= "..\lua51.dll" # Path where C modules for Lua should be installed: LUACMODPATH= ".." CC= gcc CCOPT= -O2 -fomit-frame-pointer CCWARN = -Wall SOCC= $(CC) -shared SOCFLAGS= $(CCOPT) $(CCWARN) $(INCLUDES) $(CFLAGS) SOLDFLAGS= $(LDFLAGS) RM= del STRIP= strip --strip-unneeded INSTALL= copy MODNAME= bit MODSO= $(MODNAME).dll all: $(MODSO) $(MODNAME).o: $(MODNAME).c $(CC) $(SOCFLAGS) -c -o $@ $< $(MODSO): $(MODNAME).o $(SOCC) $(SOLDFLAGS) -o $@ $< $(LUADLLPATH) $(STRIP) $@ install: $(MODSO) $(INSTALL) $< $(LUACMODPATH) test: $(MODSO) @$(LUA) bittest.lua && echo "basic test OK" @$(LUA) nsievebits.lua && echo "nsievebits test OK" @$(LUA) md5test.lua && echo "MD5 test OK" clean: $(RM) *.o *.so *.obj *.lib *.exp *.dll *.manifest .PHONY: all install test clean LuaBitOp-1.0.2/README0000644000175000017500000000077211752270264012521 0ustar mikemikeREADME for Lua BitOp 1.0.2 -------------------------- Lua BitOp is a C extension module for Lua 5.1/5.2 which adds bitwise operations on numbers. Homepage: http://bitop.luajit.org/ Lua BitOp is Copyright (C) 2008-2012 Mike Pall. Lua BitOp is free software, released under the MIT license. -------------------------- Full documentation for Lua BitOp is available in HTML format. Please point your favourite browser to: doc/index.html Detailed installation instructions are here: doc/install.html LuaBitOp-1.0.2/bit.c0000644000175000017500000001251511752270264012561 0ustar mikemike/* ** Lua BitOp -- a bit operations library for Lua 5.1/5.2. ** http://bitop.luajit.org/ ** ** Copyright (C) 2008-2012 Mike Pall. All rights reserved. ** ** Permission is hereby granted, free of charge, to any person obtaining ** a copy of this software and associated documentation files (the ** "Software"), to deal in the Software without restriction, including ** without limitation the rights to use, copy, modify, merge, publish, ** distribute, sublicense, and/or sell copies of the Software, and to ** permit persons to whom the Software is furnished to do so, subject to ** the following conditions: ** ** The above copyright notice and this permission notice shall be ** included in all copies or substantial portions of the Software. ** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ** ** [ MIT license: http://www.opensource.org/licenses/mit-license.php ] */ #define LUA_BITOP_VERSION "1.0.2" #define LUA_LIB #include "lua.h" #include "lauxlib.h" #ifdef _MSC_VER /* MSVC is stuck in the last century and doesn't have C99's stdint.h. */ typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; #else #include #endif typedef int32_t SBits; typedef uint32_t UBits; typedef union { lua_Number n; #ifdef LUA_NUMBER_DOUBLE uint64_t b; #else UBits b; #endif } BitNum; /* Convert argument to bit type. */ static UBits barg(lua_State *L, int idx) { BitNum bn; UBits b; #if LUA_VERSION_NUM < 502 bn.n = lua_tonumber(L, idx); #else bn.n = luaL_checknumber(L, idx); #endif #if defined(LUA_NUMBER_DOUBLE) bn.n += 6755399441055744.0; /* 2^52+2^51 */ #ifdef SWAPPED_DOUBLE b = (UBits)(bn.b >> 32); #else b = (UBits)bn.b; #endif #elif defined(LUA_NUMBER_INT) || defined(LUA_NUMBER_LONG) || \ defined(LUA_NUMBER_LONGLONG) || defined(LUA_NUMBER_LONG_LONG) || \ defined(LUA_NUMBER_LLONG) if (sizeof(UBits) == sizeof(lua_Number)) b = bn.b; else b = (UBits)(SBits)bn.n; #elif defined(LUA_NUMBER_FLOAT) #error "A 'float' lua_Number type is incompatible with this library" #else #error "Unknown number type, check LUA_NUMBER_* in luaconf.h" #endif #if LUA_VERSION_NUM < 502 if (b == 0 && !lua_isnumber(L, idx)) { luaL_typerror(L, idx, "number"); } #endif return b; } /* Return bit type. */ #define BRET(b) lua_pushnumber(L, (lua_Number)(SBits)(b)); return 1; static int bit_tobit(lua_State *L) { BRET(barg(L, 1)) } static int bit_bnot(lua_State *L) { BRET(~barg(L, 1)) } #define BIT_OP(func, opr) \ static int func(lua_State *L) { int i; UBits b = barg(L, 1); \ for (i = lua_gettop(L); i > 1; i--) b opr barg(L, i); BRET(b) } BIT_OP(bit_band, &=) BIT_OP(bit_bor, |=) BIT_OP(bit_bxor, ^=) #define bshl(b, n) (b << n) #define bshr(b, n) (b >> n) #define bsar(b, n) ((SBits)b >> n) #define brol(b, n) ((b << n) | (b >> (32-n))) #define bror(b, n) ((b << (32-n)) | (b >> n)) #define BIT_SH(func, fn) \ static int func(lua_State *L) { \ UBits b = barg(L, 1); UBits n = barg(L, 2) & 31; BRET(fn(b, n)) } BIT_SH(bit_lshift, bshl) BIT_SH(bit_rshift, bshr) BIT_SH(bit_arshift, bsar) BIT_SH(bit_rol, brol) BIT_SH(bit_ror, bror) static int bit_bswap(lua_State *L) { UBits b = barg(L, 1); b = (b >> 24) | ((b >> 8) & 0xff00) | ((b & 0xff00) << 8) | (b << 24); BRET(b) } static int bit_tohex(lua_State *L) { UBits b = barg(L, 1); SBits n = lua_isnone(L, 2) ? 8 : (SBits)barg(L, 2); const char *hexdigits = "0123456789abcdef"; char buf[8]; int i; if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; } if (n > 8) n = 8; for (i = (int)n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; } lua_pushlstring(L, buf, (size_t)n); return 1; } static const struct luaL_Reg bit_funcs[] = { { "tobit", bit_tobit }, { "bnot", bit_bnot }, { "band", bit_band }, { "bor", bit_bor }, { "bxor", bit_bxor }, { "lshift", bit_lshift }, { "rshift", bit_rshift }, { "arshift", bit_arshift }, { "rol", bit_rol }, { "ror", bit_ror }, { "bswap", bit_bswap }, { "tohex", bit_tohex }, { NULL, NULL } }; /* Signed right-shifts are implementation-defined per C89/C99. ** But the de facto standard are arithmetic right-shifts on two's ** complement CPUs. This behaviour is required here, so test for it. */ #define BAD_SAR (bsar(-8, 2) != (SBits)-2) LUALIB_API int luaopen_bit(lua_State *L) { UBits b; lua_pushnumber(L, (lua_Number)1437217655L); b = barg(L, -1); if (b != (UBits)1437217655L || BAD_SAR) { /* Perform a simple self-test. */ const char *msg = "compiled with incompatible luaconf.h"; #ifdef LUA_NUMBER_DOUBLE #ifdef _WIN32 if (b == (UBits)1610612736L) msg = "use D3DCREATE_FPU_PRESERVE with DirectX"; #endif if (b == (UBits)1127743488L) msg = "not compiled with SWAPPED_DOUBLE"; #endif if (BAD_SAR) msg = "arithmetic right-shift broken"; luaL_error(L, "bit library self-test failed (%s)", msg); } #if LUA_VERSION_NUM < 502 luaL_register(L, "bit", bit_funcs); #else luaL_newlib(L, bit_funcs); #endif return 1; } LuaBitOp-1.0.2/bitbench.lua0000644000175000017500000000317511752270264014122 0ustar mikemike-- Microbenchmark for bit operations library. Public domain. local bit = require"bit" if not bit.rol then -- Replacement function if rotates are missing. local bor, shl, shr = bit.bor, bit.lshift, bit.rshift function bit.rol(a, b) return bor(shl(a, b), shr(a, 32-b)) end end if not bit.bswap then -- Replacement function if bswap is missing. local bor, band, shl, shr = bit.bor, bit.band, bit.lshift, bit.rshift function bit.bswap(a) return bor(shr(a, 24), band(shr(a, 8), 0xff00), shl(band(a, 0xff00), 8), shl(a, 24)); end end local base = 0 local function bench(name, t) local n = 2000000 repeat local tm = os.clock() t(n) tm = os.clock() - tm if tm > 1 then local ns = tm*1000/(n/1000000) io.write(string.format("%-15s %6.1f ns\n", name, ns-base)) return ns end n = n + n until false end -- The overhead for the base loop is subtracted from the other measurements. base = bench("loop baseline", function(n) local x = 0; for i=1,n do x = x + i end end) bench("tobit", function(n) local f = bit.tobit or bit.cast local x = 0; for i=1,n do x = x + f(i) end end) bench("bnot", function(n) local f = bit.bnot local x = 0; for i=1,n do x = x + f(i) end end) bench("bor/band/bxor", function(n) local f = bit.bor local x = 0; for i=1,n do x = x + f(i, 1) end end) bench("shifts", function(n) local f = bit.lshift local x = 0; for i=1,n do x = x + f(i, 1) end end) bench("rotates", function(n) local f = bit.rol local x = 0; for i=1,n do x = x + f(i, 1) end end) bench("bswap", function(n) local f = bit.bswap local x = 0; for i=1,n do x = x + f(i) end end) LuaBitOp-1.0.2/bittest.lua0000644000175000017500000000446111752270264014021 0ustar mikemike-- Test cases for bit operations library. Public domain. local bit = require"bit" local vb = { 0, 1, -1, 2, -2, 0x12345678, 0x87654321, 0x33333333, 0x77777777, 0x55aa55aa, 0xaa55aa55, 0x7fffffff, 0x80000000, 0xffffffff } local function cksum(name, s, r) local z = 0 for i=1,#s do z = (z + string.byte(s, i)*i) % 2147483629 end if z ~= r then error("bit."..name.." test failed (got "..z..", expected "..r..")", 0) end end local function check_unop(name, r) local f = bit[name] local s = "" if pcall(f) or pcall(f, "z") or pcall(f, true) then error("bit."..name.." fails to detect argument errors", 0) end for _,x in ipairs(vb) do s = s..","..tostring(f(x)) end cksum(name, s, r) end local function check_binop(name, r) local f = bit[name] local s = "" if pcall(f) or pcall(f, "z") or pcall(f, true) then error("bit."..name.." fails to detect argument errors", 0) end for _,x in ipairs(vb) do for _,y in ipairs(vb) do s = s..","..tostring(f(x, y)) end end cksum(name, s, r) end local function check_binop_range(name, r, yb, ye) local f = bit[name] local s = "" if pcall(f) or pcall(f, "z") or pcall(f, true) or pcall(f, 1, true) then error("bit."..name.." fails to detect argument errors", 0) end for _,x in ipairs(vb) do for y=yb,ye do s = s..","..tostring(f(x, y)) end end cksum(name, s, r) end local function check_shift(name, r) check_binop_range(name, r, 0, 31) end -- Minimal sanity checks. assert(0x7fffffff == 2147483647, "broken hex literals") assert(0xffffffff == -1 or 0xffffffff == 2^32-1, "broken hex literals") assert(tostring(-1) == "-1", "broken tostring()") assert(tostring(0xffffffff) == "-1" or tostring(0xffffffff) == "4294967295", "broken tostring()") -- Basic argument processing. assert(bit.tobit(1) == 1) assert(bit.band(1) == 1) assert(bit.bxor(1,2) == 3) assert(bit.bor(1,2,4,8,16,32,64,128) == 255) -- Apply operations to test vectors and compare checksums. check_unop("tobit", 277312) check_unop("bnot", 287870) check_unop("bswap", 307611) check_binop("band", 41206764) check_binop("bor", 51253663) check_binop("bxor", 79322427) check_shift("lshift", 325260344) check_shift("rshift", 139061800) check_shift("arshift", 111364720) check_shift("rol", 302401155) check_shift("ror", 302316761) check_binop_range("tohex", 47880306, -8, 8) LuaBitOp-1.0.2/doc/0000755000175000017500000000000011752270264012400 5ustar mikemikeLuaBitOp-1.0.2/doc/api.html0000644000175000017500000002741511752270264014050 0ustar mikemike API Functions
Bit

This list of API functions is not intended to replace a tutorial. If you are not familiar with the terms used, you may want to study the » Wikipedia article on bitwise operations first.

Loading the BitOp Module

The suggested way to use the BitOp module is to add the following to the start of every Lua file that needs one of its functions:

local bit = require("bit")

This makes the dependency explicit, limits the scope to the current file and provides faster access to the bit.* functions, too. It's good programming practice not to rely on the global variable bit being set (assuming some other part of your application has already loaded the module). The require function ensures the module is only loaded once, in any case.

Defining Shortcuts

It's a common (but not a required) practice to cache often used module functions in locals. This serves as a shortcut to save some typing and also speeds up resolving them (only relevant if called hundreds of thousands of times).

local bnot = bit.bnot
local band, bor, bxor = bit.band, bit.bor, bit.bxor
local lshift, rshift, rol = bit.lshift, bit.rshift, bit.rol
-- etc...

-- Example use of the shortcuts:
local function tr_i(a, b, c, d, x, s)
  return rol(bxor(c, bor(b, bnot(d))) + a + x, s) + b
end

Remember that and, or and not are reserved keywords in Lua. They cannot be used for variable names or literal field names. That's why the corresponding bitwise functions have been named band, bor, and bnot (and bxor for consistency).

While we are at it: a common pitfall is to use bit as the name of a local temporary variable — well, don't! :-)

About the Examples

The examples below show small Lua one-liners. Their expected output is shown after -->. This is interpreted as a comment marker by Lua so you can cut & paste the whole line to a Lua prompt and experiment with it.

Note that all bit operations return signed 32 bit numbers (rationale). And these print as signed decimal numbers by default.

For clarity the examples assume the definition of a helper function printx(). This prints its argument as an unsigned 32 bit hexadecimal number on all platforms:

function printx(x)
  print("0x"..bit.tohex(x))
end

Bit Operations

y = bit.tobit(x)

Normalizes a number to the numeric range for bit operations and returns it. This function is usually not needed since all bit operations already normalize all of their input arguments. Check the operational semantics for details.

print(0xffffffff)                --> 4294967295 (*)
print(bit.tobit(0xffffffff))     --> -1
printx(bit.tobit(0xffffffff))    --> 0xffffffff
print(bit.tobit(0xffffffff + 1)) --> 0
print(bit.tobit(2^40 + 1234))    --> 1234

(*) See the treatment of hex literals for an explanation why the printed numbers in the first two lines differ (if your Lua installation uses a double number type).

y = bit.tohex(x [,n])

Converts its first argument to a hex string. The number of hex digits is given by the absolute value of the optional second argument. Positive numbers between 1 and 8 generate lowercase hex digits. Negative numbers generate uppercase hex digits. Only the least-significant 4*|n| bits are used. The default is to generate 8 lowercase hex digits.

print(bit.tohex(1))              --> 00000001
print(bit.tohex(-1))             --> ffffffff
print(bit.tohex(0xffffffff))     --> ffffffff
print(bit.tohex(-1, -8))         --> FFFFFFFF
print(bit.tohex(0x21, 4))        --> 0021
print(bit.tohex(0x87654321, 4))  --> 4321

y = bit.bnot(x)

Returns the bitwise not of its argument.

print(bit.bnot(0))            --> -1
printx(bit.bnot(0))           --> 0xffffffff
print(bit.bnot(-1))           --> 0
print(bit.bnot(0xffffffff))   --> 0
printx(bit.bnot(0x12345678))  --> 0xedcba987

y = bit.bor(x1 [,x2...])
y = bit.band(x1 [,x2...])
y = bit.bxor(x1 [,x2...])

Returns either the bitwise or, bitwise and, or bitwise xor of all of its arguments. Note that more than two arguments are allowed.

print(bit.bor(1, 2, 4, 8))                --> 15
printx(bit.band(0x12345678, 0xff))        --> 0x00000078
printx(bit.bxor(0xa5a5f0f0, 0xaa55ff00))  --> 0x0ff00ff0

y = bit.lshift(x, n)
y = bit.rshift(x, n)
y = bit.arshift(x, n)

Returns either the bitwise logical left-shift, bitwise logical right-shift, or bitwise arithmetic right-shift of its first argument by the number of bits given by the second argument.

Logical shifts treat the first argument as an unsigned number and shift in 0-bits. Arithmetic right-shift treats the most-significant bit as a sign bit and replicates it.
Only the lower 5 bits of the shift count are used (reduces to the range [0..31]).

print(bit.lshift(1, 0))              --> 1
print(bit.lshift(1, 8))              --> 256
print(bit.lshift(1, 40))             --> 256
print(bit.rshift(256, 8))            --> 1
print(bit.rshift(-256, 8))           --> 16777215
print(bit.arshift(256, 8))           --> 1
print(bit.arshift(-256, 8))          --> -1
printx(bit.lshift(0x87654321, 12))   --> 0x54321000
printx(bit.rshift(0x87654321, 12))   --> 0x00087654
printx(bit.arshift(0x87654321, 12))  --> 0xfff87654

y = bit.rol(x, n)
y = bit.ror(x, n)

Returns either the bitwise left rotation, or bitwise right rotation of its first argument by the number of bits given by the second argument. Bits shifted out on one side are shifted back in on the other side.
Only the lower 5 bits of the rotate count are used (reduces to the range [0..31]).

printx(bit.rol(0x12345678, 12))   --> 0x45678123
printx(bit.ror(0x12345678, 12))   --> 0x67812345

y = bit.bswap(x)

Swaps the bytes of its argument and returns it. This can be used to convert little-endian 32 bit numbers to big-endian 32 bit numbers or vice versa.

printx(bit.bswap(0x12345678)) --> 0x78563412
printx(bit.bswap(0x78563412)) --> 0x12345678

Example Program

This is an implementation of the (naïve) Sieve of Eratosthenes algorithm. It counts the number of primes up to some maximum number.

A Lua table is used to hold a bit-vector. Every array index has 32 bits of the vector. Bitwise operations are used to access and modify them. Note that the shift counts don't need to be masked since this is already done by the BitOp shift and rotate functions.

local bit = require("bit")
local band, bxor = bit.band, bit.bxor
local rshift, rol = bit.rshift, bit.rol

local m = tonumber(arg and arg[1]) or 100000
if m < 2 then m = 2 end
local count = 0
local p = {}

for i=0,(m+31)/32 do p[i] = -1 end

for i=2,m do
  if band(rshift(p[rshift(i, 5)], i), 1) ~= 0 then
    count = count + 1
    for j=i+i,m,i do
      local jx = rshift(j, 5)
      p[jx] = band(p[jx], rol(-2, j))
    end
  end
end

io.write(string.format("Found %d primes up to %d\n", count, m))

Lua BitOp is quite fast. This program runs in less than 90 milliseconds on a 3 GHz CPU with a standard Lua installation, but performs more than a million calls to bitwise functions. If you're looking for even more speed, check out » LuaJIT.

Caveats

Signed Results

Returning signed numbers from bitwise operations may be surprising to programmers coming from other programming languages which have both signed and unsigned types. But as long as you treat the results of bitwise operations uniformly everywhere, this shouldn't cause any problems.

Preferably format results with bit.tohex if you want a reliable unsigned string representation. Avoid the "%x" or "%u" formats for string.format. They fail on some architectures for negative numbers and can return more than 8 hex digits on others.

You may also want to avoid the default number to string coercion, since this is a signed conversion. The coercion is used for string concatenation and all standard library functions which accept string arguments (such as print() or io.write()).

Conditionals

If you're transcribing some code from C/C++, watch out for bit operations in conditionals. In C/C++ any non-zero value is implicitly considered as "true". E.g. this C code:
  if (x & 3) ...
must not be turned into this Lua code:
  if band(x, 3) then ... -- wrong!

In Lua all objects except nil and false are considered "true". This includes all numbers. An explicit comparison against zero is required in this case:
  if band(x, 3) ~= 0 then ... -- correct!

Comparing Against Hex Literals

Comparing the results of bitwise operations (signed numbers) against hex literals (unsigned numbers) needs some additional care. The following conditional expression may or may not work right, depending on the platform you run it on:
  bit.bor(x, 1) == 0xffffffff
E.g. it's never true on a Lua installation with the default number type. Some simple solutions:


LuaBitOp-1.0.2/doc/bluequad-print.css0000644000175000017500000000472211752270264016053 0ustar mikemike/* Copyright (C) 2004-2012 Mike Pall. * * You are welcome to use the general ideas of this design for your own sites. * But please do not steal the stylesheet, the layout or the color scheme. */ body { font-family: serif; font-size: 11pt; margin: 0 3em; padding: 0; border: none; } a:link, a:visited, a:hover, a:active { text-decoration: none; background: transparent; color: #0000ff; } h1, h2, h3 { font-family: sans-serif; font-weight: bold; text-align: left; margin: 0.5em 0; padding: 0; } h1 { font-size: 200%; } h2 { font-size: 150%; } h3 { font-size: 125%; } p { margin: 0 0 0.5em 0; padding: 0; } ul, ol { margin: 0.5em 0; padding: 0 0 0 2em; } ul { list-style: outside square; } ol { list-style: outside decimal; } li { margin: 0; padding: 0; } dl { margin: 1em 0; padding: 1em; border: 1px solid black; } dt { font-weight: bold; margin: 0; padding: 0; } dt sup { float: right; margin-left: 1em; } dd { margin: 0.5em 0 0 2em; padding: 0; } table { table-layout: fixed; width: 100%; margin: 1em 0; padding: 0; border: 1px solid black; border-spacing: 0; border-collapse: collapse; } tr { margin: 0; padding: 0; border: none; } td { text-align: left; margin: 0; padding: 0.2em 0.5em; border-top: 1px solid black; border-bottom: 1px solid black; } tr.separate td { border-top: double; } tt, pre, code, kbd, samp { font-family: monospace; font-size: 75%; } kbd { font-weight: bolder; } blockquote, pre { margin: 1em 2em; padding: 0; } img { border: none; vertical-align: baseline; margin: 0; padding: 0; } img.left { float: left; margin: 0.5em 1em 0.5em 0; } img.right { float: right; margin: 0.5em 0 0.5em 1em; } .flush { clear: both; visibility: hidden; } .hide, .noprint, #nav { display: none !important; } .pagebreak { page-break-before: always; } #site { text-align: right; font-family: sans-serif; font-weight: bold; margin: 0 1em; border-bottom: 1pt solid black; } #site a { font-size: 1.2em; } #site a:link, #site a:visited { text-decoration: none; font-weight: bold; background: transparent; color: #ffffff; } #logo { color: #ff8000; } #head { clear: both; margin: 0 1em; } #main { line-height: 1.3; text-align: justify; margin: 1em; } #foot { clear: both; font-size: 80%; text-align: center; margin: 0 1.25em; padding: 0.5em 0 0 0; border-top: 1pt solid black; page-break-before: avoid; page-break-after: avoid; } LuaBitOp-1.0.2/doc/bluequad.css0000644000175000017500000001207611752270264014722 0ustar mikemike/* Copyright (C) 2004-2012 Mike Pall. * * You are welcome to use the general ideas of this design for your own sites. * But please do not steal the stylesheet, the layout or the color scheme. */ /* colorscheme: * * site | head #4162bf/white | #6078bf/#e6ecff * ------+------ ----------------+------------------- * nav | main #bfcfff | #e6ecff/black * * nav: hiback loback #c5d5ff #b9c9f9 * hiborder loborder #e6ecff #97a7d7 * link hover #2142bf #ff0000 * * link: link visited hover #2142bf #8122bf #ff0000 * * main: boxback boxborder #f0f4ff #bfcfff */ body { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt; margin: 0; padding: 0; border: none; background: #e0e0e0; color: #000000; } a:link { text-decoration: none; background: transparent; color: #2142bf; } a:visited { text-decoration: none; background: transparent; color: #8122bf; } a:hover, a:active { text-decoration: underline; background: transparent; color: #ff0000; } h1, h2, h3 { font-weight: bold; text-align: left; margin: 0.5em 0; padding: 0; background: transparent; } h1 { font-size: 200%; line-height: 3em; /* really 6em relative to body, match #site span */ margin: 0; } h2 { font-size: 150%; color: #606060; } h3 { font-size: 125%; color: #404040; } p { max-width: 600px; margin: 0 0 0.5em 0; padding: 0; } ul, ol { max-width: 600px; margin: 0.5em 0; padding: 0 0 0 2em; } ul { list-style: outside square; } ol { list-style: outside decimal; } li { margin: 0; padding: 0; } dl { max-width: 600px; margin: 1em 0; padding: 1em; border: 1px solid #bfcfff; background: #f0f4ff; } dt { font-weight: bold; margin: 0; padding: 0; } dt sup { float: right; margin-left: 1em; color: #808080; } dt a:visited { text-decoration: none; color: #2142bf; } dt a:hover, dt a:active { text-decoration: none; color: #ff0000; } dd { margin: 0.5em 0 0 2em; padding: 0; } div.tablewrap { /* for IE *sigh* */ max-width: 600px; } table { table-layout: fixed; border-spacing: 0; border-collapse: collapse; max-width: 600px; width: 100%; margin: 1em 0; padding: 0; border: 1px solid #bfcfff; } tr { margin: 0; padding: 0; border: none; } tr.odd { background: #f0f4ff; } tr.separate td { border-top: 1px solid #bfcfff; } td { text-align: left; margin: 0; padding: 0.2em 0.5em; border: none; } tt, code, kbd, samp { font-family: Courier New, Courier, monospace; font-size: 110%; } kbd { font-weight: bolder; } blockquote, pre { max-width: 600px; margin: 1em 2em; padding: 0; } pre { line-height: 1.1; } pre.code { line-height: 1.4; margin: 0.5em 0 1em 0.5em; padding: 0.5em 1em; border: 1px solid #bfcfff; background: #f0f4ff; } img { border: none; vertical-align: baseline; margin: 0; padding: 0; } img.left { float: left; margin: 0.5em 1em 0.5em 0; } img.right { float: right; margin: 0.5em 0 0.5em 1em; } .indent { padding-left: 1em; } .flush { clear: both; visibility: hidden; } .hide, .noscreen { display: none !important; } .ext { color: #ff8000; } #site { clear: both; float: left; width: 13em; text-align: center; font-weight: bold; margin: 0; padding: 0; background: transparent; color: #ffffff; } #site a { font-size: 200%; } #site a:link, #site a:visited { text-decoration: none; font-weight: bold; background: transparent; color: #ffffff; } #site span { line-height: 3em; /* really 6em relative to body, match h1 */ } #logo { color: #ffb380; } #head { margin: 0; padding: 0 0 0 2em; border-left: solid 13em #4162bf; border-right: solid 3em #6078bf; background: #6078bf; color: #e6ecff; } #nav { clear: both; float: left; overflow: hidden; text-align: left; line-height: 1.5; width: 13em; padding-top: 1em; background: transparent; } #nav ul { list-style: none outside; margin: 0; padding: 0; } #nav li { margin: 0; padding: 0; } #nav a { display: block; text-decoration: none; font-weight: bold; margin: 0; padding: 2px 1em; border-top: 1px solid transparent; border-bottom: 1px solid transparent; background: transparent; color: #2142bf; } #nav a:hover, #nav a:active { text-decoration: none; border-top: 1px solid #97a7d7; border-bottom: 1px solid #e6ecff; background: #b9c9f9; color: #ff0000; } #nav a.current, #nav a.current:hover, #nav a.current:active { border-top: 1px solid #e6ecff; border-bottom: 1px solid #97a7d7; background: #c5d5ff; color: #2142bf; } #nav ul ul a { padding: 0 1em 0 2em; } #main { line-height: 1.5; text-align: left; margin: 0; padding: 1em 2em; border-left: solid 13em #bfcfff; border-right: solid 3em #e6ecff; background: #e6ecff; } #foot { clear: both; font-size: 80%; text-align: center; margin: 0; padding: 0.5em; background: #6078bf; color: #ffffff; } #foot a:link, #foot a:visited { text-decoration: underline; background: transparent; color: #ffffff; } #foot a:hover, #foot a:active { text-decoration: underline; background: transparent; color: #bfcfff; } LuaBitOp-1.0.2/doc/changes.html0000644000175000017500000000405611752270264014703 0ustar mikemike Change History
Bit

This is a list of changes between the released versions of Lua BitOp. The current release is Lua BitOp 1.0.2.

Please check the » Online Change History to see whether newer versions are available.

Lua BitOp 1.0.2 — 2012-05-08

Lua BitOp 1.0.1 — 2009-01-06

Lua BitOp 1.0.0 — 2008-12-17


LuaBitOp-1.0.2/doc/contact.html0000644000175000017500000000376711752270264014736 0ustar mikemike Contact
Bit

Please send general questions to the » Lua mailing list. You can also send any questions you have directly to me:

Copyright

All documentation is Copyright © 2005-2012 Mike Pall.


LuaBitOp-1.0.2/doc/index.html0000644000175000017500000000555611752270264014410 0ustar mikemike Lua Bit Operations Module
Bit

Lua BitOp is a C extension module for Lua 5.1/5.2 which adds bitwise operations on numbers.

Lua BitOp is Copyright © 2008-2012 Mike Pall. Lua BitOp is free software, released under the » MIT license (same license as the Lua core).

Features

More ...

Please click on one of the links in the navigation bar to your left to learn more.

Click on the Logo in the upper left corner to visit the Lua BitOp project page on the web. All other links to online resources are marked with a '»'.


LuaBitOp-1.0.2/doc/install.html0000644000175000017500000001734411752270264014745 0ustar mikemike Installation
Bit

This page explains how to build Lua BitOp from source, against an existing Lua installation. If you've installed Lua using a package manager (e.g. as part of a Linux distribution), you're advised to check for a pre-built package of Lua BitOp and install this instead.

Prerequisites

To compile Lua BitOp, your Lua 5.1/5.2 installation must include all development files (e.g. include files). If you've installed Lua from source, you already have them (e.g. in /usr/local/include on POSIX systems).

If you've installed Lua using a package manager, you may need to install an extra Lua development package (e.g. liblua5.1-dev on Debian/Ubuntu).

Probably any current C compiler which can compile Lua also works for Lua BitOp. The C99 <stdint.h> include file is mandatory, but the source contains a workaround for MSVC.

Lua is by default configured to use double as its number type. Lua BitOp supports IEEE 754 doubles or alternative configurations with int32_t or int64_t (suitable for embedded systems without floating-point hardware). The float number type is not supported.

Configuration

You may need to modify the build scripts and change the paths to the Lua development files or some compiler flags. Check the start of Makefile (POSIX), Makefile.mingw (MinGW on Windows) or msvcbuild.bat (MSVC on Windows) and follow the instructions in the comments.

E.g. the Lua 5.1 include files are located in /usr/include/lua5.1, if you've installed the Debian/Ubuntu Lua development package.

Build & Install

After » downloading Lua BitOp, unpack the distribution file, open a terminal/command window, change into the newly created directory and follow the instructions below.

Linux, *BSD, Mac OS X

For Linux, *BSD and most other POSIX systems just run:

make

For Mac OS X you need to run this instead:

make macosx

You probably need to be the root user to install the resulting bit.so into the C module directory for your current Lua installation. Most systems provide sudo, so you can run:

sudo make install

MinGW on Windows

Start a command prompt and make sure the MinGW tools are in your PATH. Then run:

mingw32-make -f Makefile.mingw

If you've adjusted the path where C modules for Lua should be installed, you can run:

mingw32-make -f Makefile.mingw install

Otherwise just copy the file bit.dll to the appropriate directory. By default this is the same directory where lua.exe resides.

MSVC on Windows

Open a "Visual Studio .NET Command Prompt", change to the directory where msvcbuild.bat resides and run it:

msvcbuild

If the file bit.dll has been successfully built, copy it to the directory where C modules for your Lua installation are installed. By default this is the same directory where lua.exe resides.

Embedding Lua BitOp

If you're embedding Lua into your application, it's quite simple to add Lua BitOp as a static module:

1. Copy the file bit.c from the Lua BitOp distribution to your Lua source code directory.

2. Add this file to your build script (e.g. modify the Makefile) or import it as a build dependency in your IDE.

3. Edit lualib.h and add the following two lines:

#define LUA_BITLIBNAME "bit"
LUALIB_API int luaopen_bit(lua_State *L);

4. Edit linit.c and add this immediately before the line with {NULL, NULL}:

  {LUA_BITLIBNAME, luaopen_bit},

5. Now recompile and you're done!

Testing

You can optionally test whether the installation of Lua BitOp was successful. Keep the terminal/command window open and run one of the following commands:

For Linux, *BSD and Mac OS X:

make test

For MinGW on Windows:

mingw32-make -f Makefile.mingw test

For MSVC on Windows:

msvctest

If any of the tests fail, please check that you've properly set the paths in the build scripts, compiled with the same headers you've compiled your Lua installation (in particular if you've changed the number type in luaconf.h) and installed the C module into the directory which matches your Lua installation. Double check everything if you've installed multiple Lua interpreters (e.g. both in /usr/bin and in /usr/local/bin).

If you get a warning or a failure about a broken tostring() function or about broken hex literals, then your Lua installation is defective. Check with your distributor, replace/upgrade a broken compiler or C library or re-install Lua yourself with the right configuration settings (in particular see LUA_NUMBER_* and luai_num* in luaconf.h).

Benchmarks

The distribution contains several benchmarks:


LuaBitOp-1.0.2/doc/semantics.html0000644000175000017500000001660411752270264015263 0ustar mikemike Operational Semantics and Rationale
Bit

Lua uses only a single number type which can be redefined at compile-time. By default this is a double, i.e. a floating-point number with 53 bits of precision. Operations in the range of 32 bit numbers (and beyond) are exact. There is no loss of precision, so there is no need to add an extra integer number type. Modern desktop and server CPUs have fast floating-point hardware — FP arithmetic is nearly the same speed as integer arithmetic. Any differences vanish under the overhead of the Lua interpreter itself.

Even today, many embedded systems lack support for fast FP operations. These systems benefit from compiling Lua with an integer number type (with 32 bits or more).

The different possible number types and the use of FP numbers cause some problems when defining bitwise operations on Lua numbers. The following sections define the operational semantics and try to explain the rationale behind them.

Input and Output Ranges

Modular Arithmetic

Arithmetic operations on n-bit integers are usually based on the rules of » modular arithmetic modulo 2n. Numbers wrap around when the mathematical result of operations is outside their defined range. This simplifies hardware implementations and some algorithms actually require this behavior (like many cryptographic functions).

E.g. for 32 bit integers the following holds: 0xffffffff + 1 = 0

Arithmetic modulo 232 is trivially available if the Lua number type is a 32 bit integer. Otherwise normalization steps must be inserted. Modular arithmetic should work the same across all platforms as far as possible:

BTW: The tr_i function shown here is one of the non-linear functions of the (flawed) MD5 cryptographic hash and relies on modular arithmetic for correct operation. The result is fed back to other bitwise operations (not shown) and does not need to be normalized until the last step.

Restricted and Undefined Behavior

The following rules are intended to give a precise and useful definition (for the programmer), yet give the implementation (interpreter and compiler) the maximum flexibility and the freedom to apply advanced optimizations. It's strongly advised not to rely on undefined or implementation-defined behavior.


LuaBitOp-1.0.2/doc/img/0000755000175000017500000000000011752270264013154 5ustar mikemikeLuaBitOp-1.0.2/doc/img/contact.png0000644000175000017500000000304711752270264015321 0ustar mikemikePNG  IHDR PLTEi. zK' 6ZE7  +{F  6v^OZYC~eP?-QIºź 6x  6̺ y\G +O쾄B % +>Z&` ^$?ǪOü.'A V:y=B]3,)1Fi2 & sS@^+.Di ں.H? 'qW +  ƴv^w@G ̼RW=&L8)/ Z ՟O.I2+A@ ZF==;a*W{"W (  5LnJ  5hmɣo8tuel٭ ȤG"D-Oq<_r]Y6k[Sдj\w&* / x: GWC] }1  =N" x6tg#ʧI9Qw 0 ":> IDATHǽ_Qǟz+$+ѕMf5B%{Uge$)읙?Yzy~9s>|眯Ph/h~9O=ԡyp(Sjhh\E>;O,d2)5w-Pw6R5Sc+(;n5j72i׿DtmxXkDw!tܱH G]0.A ] P 蜲~EUB -EcIENDB`LuaBitOp-1.0.2/installpath.lua0000644000175000017500000000067111752270264014665 0ustar mikemike-- Script to find the install path for a C module. Public domain. if not arg or not arg[1] then io.write("Usage: lua installpath.lua modulename\n") os.exit(1) end for p in string.gmatch(package.cpath, "[^;]+") do if string.sub(p, 1, 1) ~= "." then local p2 = string.gsub(arg[1], "%.", string.sub(package.config, 1, 1)) io.write(string.gsub(p, "%?", p2), "\n") return end end error("no suitable installation path found") LuaBitOp-1.0.2/md5test.lua0000644000175000017500000001636111752270264013732 0ustar mikemike-- MD5 test and benchmark. Public domain. local bit = require("bit") local tobit, tohex, bnot = bit.tobit or bit.cast, bit.tohex, bit.bnot local bor, band, bxor = bit.bor, bit.band, bit.bxor local lshift, rshift, rol, bswap = bit.lshift, bit.rshift, bit.rol, bit.bswap local byte, char, sub, rep = string.byte, string.char, string.sub, string.rep if not rol then -- Replacement function if rotates are missing. local bor, shl, shr = bit.bor, bit.lshift, bit.rshift function rol(a, b) return bor(shl(a, b), shr(a, 32-b)) end end if not bswap then -- Replacement function if bswap is missing. local bor, band, shl, shr = bit.bor, bit.band, bit.lshift, bit.rshift function bswap(a) return bor(shr(a, 24), band(shr(a, 8), 0xff00), shl(band(a, 0xff00), 8), shl(a, 24)); end end if not tohex then -- (Unreliable) replacement function if tohex is missing. function tohex(a) return string.sub(string.format("%08x", a), -8) end end local function tr_f(a, b, c, d, x, s) return rol(bxor(d, band(b, bxor(c, d))) + a + x, s) + b end local function tr_g(a, b, c, d, x, s) return rol(bxor(c, band(d, bxor(b, c))) + a + x, s) + b end local function tr_h(a, b, c, d, x, s) return rol(bxor(b, c, d) + a + x, s) + b end local function tr_i(a, b, c, d, x, s) return rol(bxor(c, bor(b, bnot(d))) + a + x, s) + b end local function transform(x, a1, b1, c1, d1) local a, b, c, d = a1, b1, c1, d1 a = tr_f(a, b, c, d, x[ 1] + 0xd76aa478, 7) d = tr_f(d, a, b, c, x[ 2] + 0xe8c7b756, 12) c = tr_f(c, d, a, b, x[ 3] + 0x242070db, 17) b = tr_f(b, c, d, a, x[ 4] + 0xc1bdceee, 22) a = tr_f(a, b, c, d, x[ 5] + 0xf57c0faf, 7) d = tr_f(d, a, b, c, x[ 6] + 0x4787c62a, 12) c = tr_f(c, d, a, b, x[ 7] + 0xa8304613, 17) b = tr_f(b, c, d, a, x[ 8] + 0xfd469501, 22) a = tr_f(a, b, c, d, x[ 9] + 0x698098d8, 7) d = tr_f(d, a, b, c, x[10] + 0x8b44f7af, 12) c = tr_f(c, d, a, b, x[11] + 0xffff5bb1, 17) b = tr_f(b, c, d, a, x[12] + 0x895cd7be, 22) a = tr_f(a, b, c, d, x[13] + 0x6b901122, 7) d = tr_f(d, a, b, c, x[14] + 0xfd987193, 12) c = tr_f(c, d, a, b, x[15] + 0xa679438e, 17) b = tr_f(b, c, d, a, x[16] + 0x49b40821, 22) a = tr_g(a, b, c, d, x[ 2] + 0xf61e2562, 5) d = tr_g(d, a, b, c, x[ 7] + 0xc040b340, 9) c = tr_g(c, d, a, b, x[12] + 0x265e5a51, 14) b = tr_g(b, c, d, a, x[ 1] + 0xe9b6c7aa, 20) a = tr_g(a, b, c, d, x[ 6] + 0xd62f105d, 5) d = tr_g(d, a, b, c, x[11] + 0x02441453, 9) c = tr_g(c, d, a, b, x[16] + 0xd8a1e681, 14) b = tr_g(b, c, d, a, x[ 5] + 0xe7d3fbc8, 20) a = tr_g(a, b, c, d, x[10] + 0x21e1cde6, 5) d = tr_g(d, a, b, c, x[15] + 0xc33707d6, 9) c = tr_g(c, d, a, b, x[ 4] + 0xf4d50d87, 14) b = tr_g(b, c, d, a, x[ 9] + 0x455a14ed, 20) a = tr_g(a, b, c, d, x[14] + 0xa9e3e905, 5) d = tr_g(d, a, b, c, x[ 3] + 0xfcefa3f8, 9) c = tr_g(c, d, a, b, x[ 8] + 0x676f02d9, 14) b = tr_g(b, c, d, a, x[13] + 0x8d2a4c8a, 20) a = tr_h(a, b, c, d, x[ 6] + 0xfffa3942, 4) d = tr_h(d, a, b, c, x[ 9] + 0x8771f681, 11) c = tr_h(c, d, a, b, x[12] + 0x6d9d6122, 16) b = tr_h(b, c, d, a, x[15] + 0xfde5380c, 23) a = tr_h(a, b, c, d, x[ 2] + 0xa4beea44, 4) d = tr_h(d, a, b, c, x[ 5] + 0x4bdecfa9, 11) c = tr_h(c, d, a, b, x[ 8] + 0xf6bb4b60, 16) b = tr_h(b, c, d, a, x[11] + 0xbebfbc70, 23) a = tr_h(a, b, c, d, x[14] + 0x289b7ec6, 4) d = tr_h(d, a, b, c, x[ 1] + 0xeaa127fa, 11) c = tr_h(c, d, a, b, x[ 4] + 0xd4ef3085, 16) b = tr_h(b, c, d, a, x[ 7] + 0x04881d05, 23) a = tr_h(a, b, c, d, x[10] + 0xd9d4d039, 4) d = tr_h(d, a, b, c, x[13] + 0xe6db99e5, 11) c = tr_h(c, d, a, b, x[16] + 0x1fa27cf8, 16) b = tr_h(b, c, d, a, x[ 3] + 0xc4ac5665, 23) a = tr_i(a, b, c, d, x[ 1] + 0xf4292244, 6) d = tr_i(d, a, b, c, x[ 8] + 0x432aff97, 10) c = tr_i(c, d, a, b, x[15] + 0xab9423a7, 15) b = tr_i(b, c, d, a, x[ 6] + 0xfc93a039, 21) a = tr_i(a, b, c, d, x[13] + 0x655b59c3, 6) d = tr_i(d, a, b, c, x[ 4] + 0x8f0ccc92, 10) c = tr_i(c, d, a, b, x[11] + 0xffeff47d, 15) b = tr_i(b, c, d, a, x[ 2] + 0x85845dd1, 21) a = tr_i(a, b, c, d, x[ 9] + 0x6fa87e4f, 6) d = tr_i(d, a, b, c, x[16] + 0xfe2ce6e0, 10) c = tr_i(c, d, a, b, x[ 7] + 0xa3014314, 15) b = tr_i(b, c, d, a, x[14] + 0x4e0811a1, 21) a = tr_i(a, b, c, d, x[ 5] + 0xf7537e82, 6) d = tr_i(d, a, b, c, x[12] + 0xbd3af235, 10) c = tr_i(c, d, a, b, x[ 3] + 0x2ad7d2bb, 15) b = tr_i(b, c, d, a, x[10] + 0xeb86d391, 21) return tobit(a+a1), tobit(b+b1), tobit(c+c1), tobit(d+d1) end -- Note: this is copying the original string and NOT particularly fast. -- A library for struct unpacking would make this task much easier. local function md5(msg) local len = #msg msg = msg.."\128"..rep("\0", 63 - band(len + 8, 63)) ..char(band(lshift(len, 3), 255), band(rshift(len, 5), 255), band(rshift(len, 13), 255), band(rshift(len, 21), 255)) .."\0\0\0\0" local a, b, c, d = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 local x, k = {}, 1 for i=1,#msg,4 do local m0, m1, m2, m3 = byte(msg, i, i+3) x[k] = bor(m0, lshift(m1, 8), lshift(m2, 16), lshift(m3, 24)) if k == 16 then a, b, c, d = transform(x, a, b, c, d) k = 1 else k = k + 1 end end return tohex(bswap(a))..tohex(bswap(b))..tohex(bswap(c))..tohex(bswap(d)) end assert(md5('') == 'd41d8cd98f00b204e9800998ecf8427e') assert(md5('a') == '0cc175b9c0f1b6a831c399e269772661') assert(md5('abc') == '900150983cd24fb0d6963f7d28e17f72') assert(md5('message digest') == 'f96b697d7cb7938d525a2f31aaf161d0') assert(md5('abcdefghijklmnopqrstuvwxyz') == 'c3fcd3d76192e4007dfb496cca67e13b') assert(md5('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') == 'd174ab98d277d9f5a5611c2c9f419d9f') assert(md5('12345678901234567890123456789012345678901234567890123456789012345678901234567890') == '57edf4a22be3c955ac49da2e2107b67a') if arg and arg[1] == "bench" then -- Credits: William Shakespeare, Romeo and Juliet local txt = [[Rebellious subjects, enemies to peace, Profaners of this neighbour-stained steel,-- Will they not hear? What, ho! you men, you beasts, That quench the fire of your pernicious rage With purple fountains issuing from your veins, On pain of torture, from those bloody hands Throw your mistemper'd weapons to the ground, And hear the sentence of your moved prince. Three civil brawls, bred of an airy word, By thee, old Capulet, and Montague, Have thrice disturb'd the quiet of our streets, And made Verona's ancient citizens Cast by their grave beseeming ornaments, To wield old partisans, in hands as old, Canker'd with peace, to part your canker'd hate: If ever you disturb our streets again, Your lives shall pay the forfeit of the peace. For this time, all the rest depart away: You Capulet; shall go along with me: And, Montague, come you this afternoon, To know our further pleasure in this case, To old Free-town, our common judgment-place. Once more, on pain of death, all men depart.]] txt = txt..txt..txt..txt txt = txt..txt..txt..txt local function bench() local n = 80 repeat local tm = os.clock() local res for i=1,n do res = md5(txt) end assert(res == 'a831e91e0f70eddcb70dc61c6f82f6cd') tm = os.clock() - tm if tm > 1 then return tm*(1000000000/(n*#txt)) end n = n + n until false end io.write(string.format("MD5 %7.1f ns/char\n", bench())) end LuaBitOp-1.0.2/msvcbuild.bat0000644000175000017500000000156011752270264014315 0ustar mikemike@rem Script to build Lua BitOp with MSVC. @rem First change the paths to your Lua installation below. @rem Then open a "Visual Studio .NET Command Prompt", cd to this directory @rem and run this script. Afterwards copy the resulting bit.dll to @rem the directory where lua.exe is installed. @if not defined INCLUDE goto :FAIL @setlocal @rem Path to the Lua includes and the library file for the Lua DLL: @set LUA_INC=-I .. @set LUA_LIB=..\lua51.lib @set MYCOMPILE=cl /nologo /MD /O2 /W3 /c %LUA_INC% @set MYLINK=link /nologo @set MYMT=mt /nologo %MYCOMPILE% bit.c %MYLINK% /DLL /export:luaopen_bit /out:bit.dll bit.obj %LUA_LIB% if exist bit.dll.manifest^ %MYMT% -manifest bit.dll.manifest -outputresource:bit.dll;2 del *.obj *.exp *.manifest @goto :END :FAIL @echo You must open a "Visual Studio .NET Command Prompt" to run this script :END LuaBitOp-1.0.2/msvctest.bat0000644000175000017500000000046411752270264014177 0ustar mikemike@rem Script to test Lua BitOp. @setlocal @rem Path to the Lua executable: @set LUA=lua @echo off for %%t in (bittest.lua nsievebits.lua md5test.lua) do ( echo testing %%t %LUA% %%t if errorlevel 1^ goto :FAIL ) echo ****** ALL TESTS OK ****** goto :END :FAIL echo ****** TEST FAILED ****** :END LuaBitOp-1.0.2/nsievebits.lua0000644000175000017500000000134511752270264014514 0ustar mikemike-- This is the (naive) Sieve of Eratosthenes. Public domain. local bit = require("bit") local band, bxor, rshift, rol = bit.band, bit.bxor, bit.rshift, bit.rol local function nsieve(p, m) local count = 0 for i=0,rshift(m, 5) do p[i] = -1 end for i=2,m do if band(rshift(p[rshift(i, 5)], i), 1) ~= 0 then count = count + 1 for j=i+i,m,i do local jx = rshift(j, 5) p[jx] = band(p[jx], rol(-2, j)) end end end return count end if arg and arg[1] then local N = tonumber(arg[1]) or 1 if N < 2 then N = 2 end local primes = {} for i=0,2 do local m = (2^(N-i))*10000 io.write(string.format("Primes up to %8d %8d\n", m, nsieve(primes, m))) end else assert(nsieve({}, 10000) == 1229) end