Advertisement
Alakazard12

bit.numberlua

Mar 25th, 2014
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.62 KB | None | 0 0
  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 <https://github.com/davidm/lua-bit-numberlua/zipball/master>.
  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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement