@@ -4,6 +4,15 @@ LUA MODULE
4
4
5
5
bit.numberlua - Bitwise operations implemented in pure Lua as numbers.
6
6
7
+ SYNOPSIS
8
+
9
+ local bit = require 'bit.numberlua'
10
+ print(bit.band(0xff00ff00, 0x00ff00ff)) --> 0xffffffff
11
+
12
+ -- Interface providing strong Lua 5.2 'bit32' compatibility
13
+ local bit32 = require 'bit.numberlua'.bit32
14
+ assert(bit32.band(-1) == 0xffffffff)
15
+
7
16
DESCRIPTION
8
17
9
18
This library implements bitwise operations entirely in Lua.
@@ -24,6 +33,11 @@ DESCRIPTION
24
33
The `xor` function in this module is based partly on Roberto Ierusalimschy's
25
34
post in http://lua-users.org/lists/lua-l/2002-09/msg00134.html .
26
35
36
+ The included BIT.bit32 sublibrary aims to provide 100% compatibility with
37
+ the Lua 5.2 "bit32" library. This compatbility is at the cost of some
38
+ efficiency since inputted numbers are normalized and more general
39
+ forms (e.g. multi-argument bitwise operators) are supported.
40
+
27
41
STATUS
28
42
29
43
WARNING: Not all corner cases have been tested and documented.
32
46
are currently some differences. Addressing these differences may
33
47
be improved in the future but it is not yet fully determined how to
34
48
resolve these differences.
49
+
50
+ The BIT.bit32 library passes the Lua 5.2 test suite (bitwise.lua)
51
+ http://www.lua.org/tests/5.2/ .
35
52
36
53
API
37
54
45
62
46
63
BIT.band(x, y) --> z
47
64
48
- Similar to function in Lua 5.2 and BitOp but required two arguments.
65
+ Similar to function in Lua 5.2 and BitOp but requires two arguments.
49
66
50
67
BIT.bor(x, y) --> z
51
68
52
- Similar to function in Lua 5.2 and BitOp but required two arguments.
69
+ Similar to function in Lua 5.2 and BitOp but requires two arguments.
53
70
54
71
BIT.bxor(x, y) --> z
55
72
56
- Similar to function in Lua 5.2 and BitOp but required two arguments.
73
+ Similar to function in Lua 5.2 and BitOp but requires two arguments.
57
74
58
75
BIT.bnot(x) --> z
59
76
91
108
92
109
BIT.arshift
93
110
94
- NOT IMPLEMENTED yet. Similar to function in Lua 5.2 and BitOp.
111
+ Similar to function in Lua 5.2 and BitOp.
95
112
96
113
BIT.btest
97
114
98
- NOT IMPLEMENTED yet. Similar to function in Lua 5.2.
115
+ Similar to function in Lua 5.2 with requires two arguments .
99
116
117
+ BIT.bit32
118
+
119
+ This table contains functions that aim to provide 100% compatibility
120
+ with the Lua 5.2 "bit32" library.
121
+
122
+ bit32.arshift (x, disp) --> z
123
+ bit32.band (...) --> z
124
+ bit32.bnot (x) --> z
125
+ bit32.bor (...) --> z
126
+ bit32.btest (...) --> true | false
127
+ bit32.bxor (...) --> z
128
+ bit32.extract (x, field [, width]) --> z
129
+ bit32.replace (x, v, field [, width]) --> z
130
+ bit32.lrotate (x, disp) --> z
131
+ bit32.lshift (x, disp) --> z
132
+ bit32.rrotate (x, disp) --> z
133
+ bit32.rshift (x, disp) --> z
134
+
100
135
DEPENDENCIES
101
136
102
137
None (other than Lua 5.1 or 5.2).
@@ -140,6 +175,9 @@ local M = {_TYPE='module', _NAME='bit.numberlua', _VERSION='000.003.2011-11-29'}
140
175
141
176
local floor = math.floor
142
177
178
+ local MOD = 2 ^ 32
179
+ local MODM = MOD - 1
180
+
143
181
local function memoize (f )
144
182
local mt = {}
145
183
local t = setmetatable ({}, mt )
@@ -184,24 +222,24 @@ end
184
222
M .bxor = make_bitop {[0 ]= {[0 ]= 0 ,[1 ]= 1 },[1 ]= {[0 ]= 1 ,[1 ]= 0 }, n = 4 }
185
223
local bxor = M .bxor
186
224
187
- local F8 = 2 ^ 32 - 1
188
- function M .bnot (a ) return F8 - a end
225
+ function M .bnot (a ) return MODM - a end
189
226
local bnot = M .bnot
190
227
191
228
function M .band (a ,b ) return ((a + b ) - bxor (a ,b ))/ 2 end
192
229
local band = M .band
193
230
194
- function M .bor (a ,b ) return F8 - band (F8 - a , F8 - b ) end
231
+ function M .bor (a ,b ) return MODM - band (MODM - a , MODM - b ) end
232
+ local bor = M .bor
195
233
196
234
local lshift , rshift -- forward declare
197
235
198
- function M .rshift (a ,disp ) -- Lua5.2 style
236
+ function M .rshift (a ,disp ) -- Lua5.2 insipred
199
237
if disp < 0 then return lshift (a ,- disp ) end
200
238
return floor (a % 2 ^ 32 / 2 ^ disp )
201
239
end
202
240
rshift = M .rshift
203
241
204
- function M .lshift (a ,disp ) -- Lua5.2 style
242
+ function M .lshift (a ,disp ) -- Lua5.2 inspired
205
243
if disp < 0 then return rshift (a ,- disp ) end
206
244
return (a * 2 ^ disp ) % 2 ^ 32
207
245
end
@@ -218,18 +256,20 @@ function M.tohex(x, n) -- BitOp style
218
256
return (' %0' .. n .. (up and ' X' or ' x' )):format (x )
219
257
end
220
258
221
- function M .extract (n , field , width ) -- Lua5.2 style
259
+ function M .extract (n , field , width ) -- Lua5.2 inspired
222
260
width = width or 1
223
261
return band (rshift (n , field ), 2 ^ width - 1 )
224
262
end
263
+ local extract = M .extract
225
264
226
- function M .replace (n , v , field , width ) -- Lua5.2 style
265
+ function M .replace (n , v , field , width ) -- Lua5.2 inspired
227
266
width = width or 1
228
267
local mask1 = 2 ^ width - 1
229
268
v = band (v , mask1 ) -- required by spec?
230
269
local mask = bnot (lshift (mask1 , field ))
231
270
return band (n , mask ) + lshift (v , field )
232
271
end
272
+ local replace = M .replace
233
273
234
274
function M .bswap (x ) -- BitOp style
235
275
local a = band (x , 0xff ); x = rshift (x , 8 )
@@ -239,18 +279,153 @@ function M.bswap(x) -- BitOp style
239
279
return lshift (lshift (lshift (a , 8 ) + b , 8 ) + c , 8 ) + d
240
280
end
241
281
242
- function M .rrotate (x , disp ) -- Lua5.2 style
282
+ function M .rrotate (x , disp ) -- Lua5.2 inspired
243
283
disp = disp % 32
244
284
local low = band (x , 2 ^ disp - 1 )
245
285
return rshift (x , disp ) + lshift (low , 32 - disp )
246
286
end
247
287
local rrotate = M .rrotate
248
288
249
- function M .lrotate (x , disp ) -- Lua5.2 style
289
+ function M .lrotate (x , disp ) -- Lua5.2 inspired
250
290
return rrotate (x , - disp )
251
291
end
292
+ local lrotate = M .lrotate
293
+
294
+ M .rol = M .lrotate -- LuaOp inspired
295
+ M .ror = M .rrotate -- LuaOp insipred
296
+
297
+
298
+ function M .arshift (x , disp ) -- Lua5.2 inspired
299
+ local z = rshift (x , disp )
300
+ if x >= 0x80000000 then z = z + lshift (2 ^ disp - 1 , 32 - disp ) end
301
+ return z
302
+ end
303
+
304
+ function M .btest (x , y ) -- Lua5.2 inspired
305
+ return band (x , y ) ~= 0
306
+ end
307
+
308
+ --
309
+ -- Start Lua 5.2 "bit32" compat section.
310
+ --
311
+
312
+ M .bit32 = {} -- Lua 5.2 'bit32' compatibility
313
+
314
+
315
+ local function bit32_bnot (x )
316
+ return (- 1 - x ) % MOD
317
+ end
318
+ M .bit32 .bnot = bit32_bnot
319
+
320
+ local function bit32_bxor (a , b , c , ...)
321
+ local z
322
+ if b then
323
+ a = a % MOD
324
+ b = b % MOD
325
+ z = bxor (a , b )
326
+ if c then
327
+ z = bxor (z , c , ... )
328
+ end
329
+ return z
330
+ elseif a then
331
+ return a % MOD
332
+ else
333
+ return 0
334
+ end
335
+ end
336
+ M .bit32 .bxor = bit32_bxor
337
+
338
+ local function bit32_band (a , b , c , ...)
339
+ local z
340
+ if b then
341
+ a = a % MOD
342
+ b = b % MOD
343
+ z = ((a + b ) - bxor (a ,b )) / 2
344
+ if c then
345
+ z = band (z , c , ... )
346
+ end
347
+ return z
348
+ elseif a then
349
+ return a % MOD
350
+ else
351
+ return MODM
352
+ end
353
+ end
354
+ M .bit32 .band = bit32_band
355
+
356
+ local function bit32_bor (a , b , c , ...)
357
+ local z
358
+ if b then
359
+ a = a % MOD
360
+ b = b % MOD
361
+ z = MODM - band (MODM - a , MODM - b )
362
+ if c then
363
+ z = bor (z , c , ... )
364
+ end
365
+ return z
366
+ elseif a then
367
+ return a % MOD
368
+ else
369
+ return 0
370
+ end
371
+ end
372
+ M .bit32 .bor = bit32_bor
373
+
374
+ function M .bit32 .btest (...)
375
+ return bit32_band (... ) ~= 0
376
+ end
377
+
378
+ function M .bit32 .lrotate (x , disp )
379
+ return lrotate (x % MOD , disp )
380
+ end
381
+
382
+ function M .bit32 .rrotate (x , disp )
383
+ return rrotate (x % MOD , disp )
384
+ end
385
+
386
+ function M .bit32 .lshift (x ,disp )
387
+ if disp > 31 or disp < - 31 then return 0 end
388
+ return lshift (x % MOD , disp )
389
+ end
390
+
391
+ function M .bit32 .rshift (x ,disp )
392
+ if disp > 31 or disp < - 31 then return 0 end
393
+ return rshift (x % MOD , disp )
394
+ end
395
+
396
+ function M .bit32 .arshift (x ,disp )
397
+ x = x % MOD
398
+ if disp >= 0 then
399
+ if disp > 31 then
400
+ return (x >= 0x80000000 ) and MODM or 0
401
+ else
402
+ local z = rshift (x , disp )
403
+ if x >= 0x80000000 then z = z + lshift (2 ^ disp - 1 , 32 - disp ) end
404
+ return z
405
+ end
406
+ else
407
+ return lshift (x , - disp )
408
+ end
409
+ end
410
+
411
+ function M .bit32 .extract (x , field , ...)
412
+ local width = ... or 1
413
+ if field < 0 or field > 31 or width < 0 or field + width > 32 then error ' out of range' end
414
+ x = x % MOD
415
+ return extract (x , field , ... )
416
+ end
417
+
418
+ function M .bit32 .replace (x , v , field , ...)
419
+ local width = ... or 1
420
+ if field < 0 or field > 31 or width < 0 or field + width > 32 then error ' out of range' end
421
+ x = x % MOD
422
+ v = v % MOD
423
+ return replace (x , v , field , ... )
424
+ end
425
+
426
+
427
+ -- TODO? Likewise add LuaOp "bit" compat section?
428
+ -- M.bit32 = {} -- LuaOp "bit" compatibility
252
429
253
- M .rol = M .lrotate -- LuaOp style
254
- M .ror = M .rrotate -- LuaOp style
255
430
256
431
return M
0 commit comments