bit.lua 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. --[[
  2. LUA MODULE
  3. bit.numberlua - Bitwise operations implemented in pure Lua as numbers,
  4. with Lua 5.2 'bit32' and (LuaJIT) LuaBitOp 'bit' compatibility interfaces.
  5. SYNOPSIS
  6. local bit = require 'bit.numberlua'
  7. print(bit.band(0xff00ff00, 0x00ff00ff)) --> 0xffffffff
  8. -- Interface providing strong Lua 5.2 'bit32' compatibility
  9. local bit32 = require 'bit.numberlua'.bit32
  10. assert(bit32.band(-1) == 0xffffffff)
  11. -- Interface providing strong (LuaJIT) LuaBitOp 'bit' compatibility
  12. local bit = require 'bit.numberlua'.bit
  13. assert(bit.tobit(0xffffffff) == -1)
  14. DESCRIPTION
  15. This library implements bitwise operations entirely in Lua.
  16. This module is typically intended if for some reasons you don't want
  17. to or cannot install a popular C based bit library like BitOp 'bit' [1]
  18. (which comes pre-installed with LuaJIT) or 'bit32' (which comes
  19. pre-installed with Lua 5.2) but want a similar interface.
  20. This modules represents bit arrays as non-negative Lua numbers. [1]
  21. It can represent 32-bit bit arrays when Lua is compiled
  22. with lua_Number as double-precision IEEE 754 floating point.
  23. The module is nearly the most efficient it can be but may be a few times
  24. slower than the C based bit libraries and is orders or magnitude
  25. slower than LuaJIT bit operations, which compile to native code. Therefore,
  26. this library is inferior in performane to the other modules.
  27. The `xor` function in this module is based partly on Roberto Ierusalimschy's
  28. post in http://lua-users.org/lists/lua-l/2002-09/msg00134.html .
  29. The included BIT.bit32 and BIT.bit sublibraries aims to provide 100%
  30. compatibility with the Lua 5.2 "bit32" and (LuaJIT) LuaBitOp "bit" library.
  31. This compatbility is at the cost of some efficiency since inputted
  32. numbers are normalized and more general forms (e.g. multi-argument
  33. bitwise operators) are supported.
  34. STATUS
  35. WARNING: Not all corner cases have been tested and documented.
  36. Some attempt was made to make these similar to the Lua 5.2 [2]
  37. and LuaJit BitOp [3] libraries, but this is not fully tested and there
  38. are currently some differences. Addressing these differences may
  39. be improved in the future but it is not yet fully determined how to
  40. resolve these differences.
  41. The BIT.bit32 library passes the Lua 5.2 test suite (bitwise.lua)
  42. http://www.lua.org/tests/5.2/ . The BIT.bit library passes the LuaBitOp
  43. test suite (bittest.lua). However, these have not been tested on
  44. platforms with Lua compiled with 32-bit integer numbers.
  45. API
  46. BIT.tobit(x) --> z
  47. Similar to function in BitOp.
  48. BIT.tohex(x, n)
  49. Similar to function in BitOp.
  50. BIT.band(x, y) --> z
  51. Similar to function in Lua 5.2 and BitOp but requires two arguments.
  52. BIT.bor(x, y) --> z
  53. Similar to function in Lua 5.2 and BitOp but requires two arguments.
  54. BIT.bxor(x, y) --> z
  55. Similar to function in Lua 5.2 and BitOp but requires two arguments.
  56. BIT.bnot(x) --> z
  57. Similar to function in Lua 5.2 and BitOp.
  58. BIT.lshift(x, disp) --> z
  59. Similar to function in Lua 5.2 (warning: BitOp uses unsigned lower 5 bits of shift),
  60. BIT.rshift(x, disp) --> z
  61. Similar to function in Lua 5.2 (warning: BitOp uses unsigned lower 5 bits of shift),
  62. BIT.extract(x, field [, width]) --> z
  63. Similar to function in Lua 5.2.
  64. BIT.replace(x, v, field, width) --> z
  65. Similar to function in Lua 5.2.
  66. BIT.bswap(x) --> z
  67. Similar to function in Lua 5.2.
  68. BIT.rrotate(x, disp) --> z
  69. BIT.ror(x, disp) --> z
  70. Similar to function in Lua 5.2 and BitOp.
  71. BIT.lrotate(x, disp) --> z
  72. BIT.rol(x, disp) --> z
  73. Similar to function in Lua 5.2 and BitOp.
  74. BIT.arshift
  75. Similar to function in Lua 5.2 and BitOp.
  76. BIT.btest
  77. Similar to function in Lua 5.2 with requires two arguments.
  78. BIT.bit32
  79. This table contains functions that aim to provide 100% compatibility
  80. with the Lua 5.2 "bit32" library.
  81. bit32.arshift (x, disp) --> z
  82. bit32.band (...) --> z
  83. bit32.bnot (x) --> z
  84. bit32.bor (...) --> z
  85. bit32.btest (...) --> true | false
  86. bit32.bxor (...) --> z
  87. bit32.extract (x, field [, width]) --> z
  88. bit32.replace (x, v, field [, width]) --> z
  89. bit32.lrotate (x, disp) --> z
  90. bit32.lshift (x, disp) --> z
  91. bit32.rrotate (x, disp) --> z
  92. bit32.rshift (x, disp) --> z
  93. BIT.bit
  94. This table contains functions that aim to provide 100% compatibility
  95. with the LuaBitOp "bit" library (from LuaJIT).
  96. bit.tobit(x) --> y
  97. bit.tohex(x [,n]) --> y
  98. bit.bnot(x) --> y
  99. bit.bor(x1 [,x2...]) --> y
  100. bit.band(x1 [,x2...]) --> y
  101. bit.bxor(x1 [,x2...]) --> y
  102. bit.lshift(x, n) --> y
  103. bit.rshift(x, n) --> y
  104. bit.arshift(x, n) --> y
  105. bit.rol(x, n) --> y
  106. bit.ror(x, n) --> y
  107. bit.bswap(x) --> y
  108. DEPENDENCIES
  109. None (other than Lua 5.1 or 5.2).
  110. DOWNLOAD/INSTALLATION
  111. If using LuaRocks:
  112. luarocks install lua-bit-numberlua
  113. Otherwise, download <https://github.com/davidm/lua-bit-numberlua/zipball/master>.
  114. Alternately, if using git:
  115. git clone git://github.com/davidm/lua-bit-numberlua.git
  116. cd lua-bit-numberlua
  117. Optionally unpack:
  118. ./util.mk
  119. or unpack and install in LuaRocks:
  120. ./util.mk install
  121. REFERENCES
  122. [1] http://lua-users.org/wiki/FloatingPoint
  123. [2] http://www.lua.org/manual/5.2/
  124. [3] http://bitop.luajit.org/
  125. LICENSE
  126. (c) 2008-2011 David Manura. Licensed under the same terms as Lua (MIT).
  127. Permission is hereby granted, free of charge, to any person obtaining a copy
  128. of this software and associated documentation files (the "Software"), to deal
  129. in the Software without restriction, including without limitation the rights
  130. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  131. copies of the Software, and to permit persons to whom the Software is
  132. furnished to do so, subject to the following conditions:
  133. The above copyright notice and this permission notice shall be included in
  134. all copies or substantial portions of the Software.
  135. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  136. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  137. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  138. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  139. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  140. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  141. THE SOFTWARE.
  142. (end license)
  143. --]]
  144. local M = {_TYPE='module', _NAME='bit.numberlua', _VERSION='0.3.1.20120131'}
  145. local floor = math.floor
  146. local MOD = 2^32
  147. local MODM = MOD-1
  148. local function memoize(f)
  149. local mt = {}
  150. local t = setmetatable({}, mt)
  151. function mt:__index(k)
  152. local v = f(k); t[k] = v
  153. return v
  154. end
  155. return t
  156. end
  157. local function make_bitop_uncached(t, m)
  158. local function bitop(a, b)
  159. local res,p = 0,1
  160. while a ~= 0 and b ~= 0 do
  161. local am, bm = a%m, b%m
  162. res = res + t[am][bm]*p
  163. a = (a - am) / m
  164. b = (b - bm) / m
  165. p = p*m
  166. end
  167. res = res + (a+b)*p
  168. return res
  169. end
  170. return bitop
  171. end
  172. local function make_bitop(t)
  173. local op1 = make_bitop_uncached(t,2^1)
  174. local op2 = memoize(function(a)
  175. return memoize(function(b)
  176. return op1(a, b)
  177. end)
  178. end)
  179. return make_bitop_uncached(op2, 2^(t.n or 1))
  180. end
  181. -- ok? probably not if running on a 32-bit int Lua number type platform
  182. function M.tobit(x)
  183. return x % 2^32
  184. end
  185. M.bxor = make_bitop {[0]={[0]=0,[1]=1},[1]={[0]=1,[1]=0}, n=4}
  186. local bxor = M.bxor
  187. function M.bnot(a) return MODM - a end
  188. local bnot = M.bnot
  189. function M.band(a,b) return ((a+b) - bxor(a,b))/2 end
  190. local band = M.band
  191. function M.bor(a,b) return MODM - band(MODM - a, MODM - b) end
  192. local bor = M.bor
  193. local lshift, rshift -- forward declare
  194. function M.rshift(a,disp) -- Lua5.2 insipred
  195. if disp < 0 then return lshift(a,-disp) end
  196. return floor(a % 2^32 / 2^disp)
  197. end
  198. rshift = M.rshift
  199. function M.lshift(a,disp) -- Lua5.2 inspired
  200. if disp < 0 then return rshift(a,-disp) end
  201. return (a * 2^disp) % 2^32
  202. end
  203. lshift = M.lshift
  204. function M.tohex(x, n) -- BitOp style
  205. n = n or 8
  206. local up
  207. if n <= 0 then
  208. if n == 0 then return '' end
  209. up = true
  210. n = - n
  211. end
  212. x = band(x, 16^n-1)
  213. return ('%0'..n..(up and 'X' or 'x')):format(x)
  214. end
  215. local tohex = M.tohex
  216. function M.extract(n, field, width) -- Lua5.2 inspired
  217. width = width or 1
  218. return band(rshift(n, field), 2^width-1)
  219. end
  220. local extract = M.extract
  221. function M.replace(n, v, field, width) -- Lua5.2 inspired
  222. width = width or 1
  223. local mask1 = 2^width-1
  224. v = band(v, mask1) -- required by spec?
  225. local mask = bnot(lshift(mask1, field))
  226. return band(n, mask) + lshift(v, field)
  227. end
  228. local replace = M.replace
  229. function M.bswap(x) -- BitOp style
  230. local a = band(x, 0xff); x = rshift(x, 8)
  231. local b = band(x, 0xff); x = rshift(x, 8)
  232. local c = band(x, 0xff); x = rshift(x, 8)
  233. local d = band(x, 0xff)
  234. return lshift(lshift(lshift(a, 8) + b, 8) + c, 8) + d
  235. end
  236. local bswap = M.bswap
  237. function M.rrotate(x, disp) -- Lua5.2 inspired
  238. disp = disp % 32
  239. local low = band(x, 2^disp-1)
  240. return rshift(x, disp) + lshift(low, 32-disp)
  241. end
  242. local rrotate = M.rrotate
  243. function M.lrotate(x, disp) -- Lua5.2 inspired
  244. return rrotate(x, -disp)
  245. end
  246. local lrotate = M.lrotate
  247. M.rol = M.lrotate -- LuaOp inspired
  248. M.ror = M.rrotate -- LuaOp insipred
  249. function M.arshift(x, disp) -- Lua5.2 inspired
  250. local z = rshift(x, disp)
  251. if x >= 0x80000000 then z = z + lshift(2^disp-1, 32-disp) end
  252. return z
  253. end
  254. local arshift = M.arshift
  255. function M.btest(x, y) -- Lua5.2 inspired
  256. return band(x, y) ~= 0
  257. end
  258. --
  259. -- Start Lua 5.2 "bit32" compat section.
  260. --
  261. M.bit32 = {} -- Lua 5.2 'bit32' compatibility
  262. local function bit32_bnot(x)
  263. return (-1 - x) % MOD
  264. end
  265. M.bit32.bnot = bit32_bnot
  266. local function bit32_bxor(a, b, c, ...)
  267. local z
  268. if b then
  269. a = a % MOD
  270. b = b % MOD
  271. z = bxor(a, b)
  272. if c then
  273. z = bit32_bxor(z, c, ...)
  274. end
  275. return z
  276. elseif a then
  277. return a % MOD
  278. else
  279. return 0
  280. end
  281. end
  282. M.bit32.bxor = bit32_bxor
  283. local function bit32_band(a, b, c, ...)
  284. local z
  285. if b then
  286. a = a % MOD
  287. b = b % MOD
  288. z = ((a+b) - bxor(a,b)) / 2
  289. if c then
  290. z = bit32_band(z, c, ...)
  291. end
  292. return z
  293. elseif a then
  294. return a % MOD
  295. else
  296. return MODM
  297. end
  298. end
  299. M.bit32.band = bit32_band
  300. local function bit32_bor(a, b, c, ...)
  301. local z
  302. if b then
  303. a = a % MOD
  304. b = b % MOD
  305. z = MODM - band(MODM - a, MODM - b)
  306. if c then
  307. z = bit32_bor(z, c, ...)
  308. end
  309. return z
  310. elseif a then
  311. return a % MOD
  312. else
  313. return 0
  314. end
  315. end
  316. M.bit32.bor = bit32_bor
  317. function M.bit32.btest(...)
  318. return bit32_band(...) ~= 0
  319. end
  320. function M.bit32.lrotate(x, disp)
  321. return lrotate(x % MOD, disp)
  322. end
  323. function M.bit32.rrotate(x, disp)
  324. return rrotate(x % MOD, disp)
  325. end
  326. function M.bit32.lshift(x,disp)
  327. if disp > 31 or disp < -31 then return 0 end
  328. return lshift(x % MOD, disp)
  329. end
  330. function M.bit32.rshift(x,disp)
  331. if disp > 31 or disp < -31 then return 0 end
  332. return rshift(x % MOD, disp)
  333. end
  334. function M.bit32.arshift(x,disp)
  335. x = x % MOD
  336. if disp >= 0 then
  337. if disp > 31 then
  338. return (x >= 0x80000000) and MODM or 0
  339. else
  340. local z = rshift(x, disp)
  341. if x >= 0x80000000 then z = z + lshift(2^disp-1, 32-disp) end
  342. return z
  343. end
  344. else
  345. return lshift(x, -disp)
  346. end
  347. end
  348. function M.bit32.extract(x, field, ...)
  349. local width = ... or 1
  350. if field < 0 or field > 31 or width < 0 or field+width > 32 then error 'out of range' end
  351. x = x % MOD
  352. return extract(x, field, ...)
  353. end
  354. function M.bit32.replace(x, v, field, ...)
  355. local width = ... or 1
  356. if field < 0 or field > 31 or width < 0 or field+width > 32 then error 'out of range' end
  357. x = x % MOD
  358. v = v % MOD
  359. return replace(x, v, field, ...)
  360. end
  361. --
  362. -- Start LuaBitOp "bit" compat section.
  363. --
  364. M.bit = {} -- LuaBitOp "bit" compatibility
  365. function M.bit.tobit(x)
  366. x = x % MOD
  367. if x >= 0x80000000 then x = x - MOD end
  368. return x
  369. end
  370. local bit_tobit = M.bit.tobit
  371. function M.bit.tohex(x, ...)
  372. return tohex(x % MOD, ...)
  373. end
  374. function M.bit.bnot(x)
  375. return bit_tobit(bnot(x % MOD))
  376. end
  377. local function bit_bor(a, b, c, ...)
  378. if c then
  379. return bit_bor(bit_bor(a, b), c, ...)
  380. elseif b then
  381. return bit_tobit(bor(a % MOD, b % MOD))
  382. else
  383. return bit_tobit(a)
  384. end
  385. end
  386. M.bit.bor = bit_bor
  387. local function bit_band(a, b, c, ...)
  388. if c then
  389. return bit_band(bit_band(a, b), c, ...)
  390. elseif b then
  391. return bit_tobit(band(a % MOD, b % MOD))
  392. else
  393. return bit_tobit(a)
  394. end
  395. end
  396. M.bit.band = bit_band
  397. local function bit_bxor(a, b, c, ...)
  398. if c then
  399. return bit_bxor(bit_bxor(a, b), c, ...)
  400. elseif b then
  401. return bit_tobit(bxor(a % MOD, b % MOD))
  402. else
  403. return bit_tobit(a)
  404. end
  405. end
  406. M.bit.bxor = bit_bxor
  407. function M.bit.lshift(x, n)
  408. return bit_tobit(lshift(x % MOD, n % 32))
  409. end
  410. function M.bit.rshift(x, n)
  411. return bit_tobit(rshift(x % MOD, n % 32))
  412. end
  413. function M.bit.arshift(x, n)
  414. return bit_tobit(arshift(x % MOD, n % 32))
  415. end
  416. function M.bit.rol(x, n)
  417. return bit_tobit(lrotate(x % MOD, n % 32))
  418. end
  419. function M.bit.ror(x, n)
  420. return bit_tobit(rrotate(x % MOD, n % 32))
  421. end
  422. function M.bit.bswap(x)
  423. return bit_tobit(bswap(x % MOD))
  424. end
  425. return M