1-- $Id: testes/bitwise.lua $
  2-- See Copyright Notice in file all.lua
  3
  4print("testing bitwise operations")
  5
  6require "bwcoercion"
  7
  8local numbits = string.packsize('j') * 8
  9
 10assert(~0 == -1)
 11
 12assert((1 << (numbits - 1)) == math.mininteger)
 13
 14-- basic tests for bitwise operators;
 15-- use variables to avoid constant folding
 16local a, b, c, d
 17a = 0xFFFFFFFFFFFFFFFF
 18assert(a == -1 and a & -1 == a and a & 35 == 35)
 19a = 0xF0F0F0F0F0F0F0F0
 20assert(a | -1 == -1)
 21assert(a ~ a == 0 and a ~ 0 == a and a ~ ~a == -1)
 22assert(a >> 4 == ~a)
 23a = 0xF0; b = 0xCC; c = 0xAA; d = 0xFD
 24assert(a | b ~ c & d == 0xF4)
 25
 26a = 0xF0.0; b = 0xCC.0; c = "0xAA.0"; d = "0xFD.0"
 27assert(a | b ~ c & d == 0xF4)
 28
 29a = 0xF0000000; b = 0xCC000000;
 30c = 0xAA000000; d = 0xFD000000
 31assert(a | b ~ c & d == 0xF4000000)
 32assert(~~a == a and ~a == -1 ~ a and -d == ~d + 1)
 33
 34a = a << 32
 35b = b << 32
 36c = c << 32
 37d = d << 32
 38assert(a | b ~ c & d == 0xF4000000 << 32)
 39assert(~~a == a and ~a == -1 ~ a and -d == ~d + 1)
 40
 41
 42do   -- constant folding
 43  local code = string.format("return -1 >> %d", math.maxinteger)
 44  assert(load(code)() == 0)
 45  local code = string.format("return -1 >> %d", math.mininteger)
 46  assert(load(code)() == 0)
 47  local code = string.format("return -1 << %d", math.maxinteger)
 48  assert(load(code)() == 0)
 49  local code = string.format("return -1 << %d", math.mininteger)
 50  assert(load(code)() == 0)
 51end
 52
 53assert(-1 >> 1 == (1 << (numbits - 1)) - 1 and 1 << 31 == 0x80000000)
 54assert(-1 >> (numbits - 1) == 1)
 55assert(-1 >> numbits == 0 and
 56       -1 >> -numbits == 0 and
 57       -1 << numbits == 0 and
 58       -1 << -numbits == 0)
 59
 60assert(1 >> math.mininteger == 0)
 61assert(1 >> math.maxinteger == 0)
 62assert(1 << math.mininteger == 0)
 63assert(1 << math.maxinteger == 0)
 64
 65assert((2^30 - 1) << 2^30 == 0)
 66assert((2^30 - 1) >> 2^30 == 0)
 67
 68assert(1 >> -3 == 1 << 3 and 1000 >> 5 == 1000 << -5)
 69
 70
 71-- coercion from strings to integers
 72assert("0xffffffffffffffff" | 0 == -1)
 73assert("0xfffffffffffffffe" & "-1" == -2)
 74assert(" \t-0xfffffffffffffffe\n\t" & "-1" == 2)
 75assert("   \n  -45  \t " >> "  -2  " == -45 * 4)
 76assert("1234.0" << "5.0" == 1234 * 32)
 77assert("0xffff.0" ~ "0xAAAA" == 0x5555)
 78assert(~"0x0.000p4" == -1)
 79
 80assert(("7" .. 3) << 1 == 146)
 81assert(0xffffffff >> (1 .. "9") == 0x1fff)
 82assert(10 | (1 .. "9") == 27)
 83
 84do
 85  local st, msg = pcall(function () return 4 & "a" end)
 86  assert(string.find(msg, "'band'"))
 87
 88  local st, msg = pcall(function () return ~"a" end)
 89  assert(string.find(msg, "'bnot'"))
 90end
 91
 92
 93-- out of range number
 94assert(not pcall(function () return "0xffffffffffffffff.0" | 0 end))
 95
 96-- embedded zeros
 97assert(not pcall(function () return "0xffffffffffffffff\0" | 0 end))
 98
 99print'+'
100
101
102package.preload.bit32 = function ()     --{
103
104-- no built-in 'bit32' library: implement it using bitwise operators
105
106local bit = {}
107
108function bit.bnot (a)
109  return ~a & 0xFFFFFFFF
110end
111
112
113--
114-- in all vararg functions, avoid creating 'arg' table when there are
115-- only 2 (or less) parameters, as 2 parameters is the common case
116--
117
118function bit.band (x, y, z, ...)
119  if not z then
120    return ((x or -1) & (y or -1)) & 0xFFFFFFFF
121  else
122    local arg = {...}
123    local res = x & y & z
124    for i = 1, #arg do res = res & arg[i] end
125    return res & 0xFFFFFFFF
126  end
127end
128
129function bit.bor (x, y, z, ...)
130  if not z then
131    return ((x or 0) | (y or 0)) & 0xFFFFFFFF
132  else
133    local arg = {...}
134    local res = x | y | z
135    for i = 1, #arg do res = res | arg[i] end
136    return res & 0xFFFFFFFF
137  end
138end
139
140function bit.bxor (x, y, z, ...)
141  if not z then
142    return ((x or 0) ~ (y or 0)) & 0xFFFFFFFF
143  else
144    local arg = {...}
145    local res = x ~ y ~ z
146    for i = 1, #arg do res = res ~ arg[i] end
147    return res & 0xFFFFFFFF
148  end
149end
150
151function bit.btest (...)
152  return bit.band(...) ~= 0
153end
154
155function bit.lshift (a, b)
156  return ((a & 0xFFFFFFFF) << b) & 0xFFFFFFFF
157end
158
159function bit.rshift (a, b)
160  return ((a & 0xFFFFFFFF) >> b) & 0xFFFFFFFF
161end
162
163function bit.arshift (a, b)
164  a = a & 0xFFFFFFFF
165  if b <= 0 or (a & 0x80000000) == 0 then
166    return (a >> b) & 0xFFFFFFFF
167  else
168    return ((a >> b) | ~(0xFFFFFFFF >> b)) & 0xFFFFFFFF
169  end
170end
171
172function bit.lrotate (a ,b)
173  b = b & 31
174  a = a & 0xFFFFFFFF
175  a = (a << b) | (a >> (32 - b))
176  return a & 0xFFFFFFFF
177end
178
179function bit.rrotate (a, b)
180  return bit.lrotate(a, -b)
181end
182
183local function checkfield (f, w)
184  w = w or 1
185  assert(f >= 0, "field cannot be negative")
186  assert(w > 0, "width must be positive")
187  assert(f + w <= 32, "trying to access non-existent bits")
188  return f, ~(-1 << w)
189end
190
191function bit.extract (a, f, w)
192  local f, mask = checkfield(f, w)
193  return (a >> f) & mask
194end
195
196function bit.replace (a, v, f, w)
197  local f, mask = checkfield(f, w)
198  v = v & mask
199  a = (a & ~(mask << f)) | (v << f)
200  return a & 0xFFFFFFFF
201end
202
203return bit
204
205end  --}
206
207
208print("testing bitwise library")
209
210local bit32 = require'bit32'
211
212assert(bit32.band() == bit32.bnot(0))
213assert(bit32.btest() == true)
214assert(bit32.bor() == 0)
215assert(bit32.bxor() == 0)
216
217assert(bit32.band() == bit32.band(0xffffffff))
218assert(bit32.band(1,2) == 0)
219
220
221-- out-of-range numbers
222assert(bit32.band(-1) == 0xffffffff)
223assert(bit32.band((1 << 33) - 1) == 0xffffffff)
224assert(bit32.band(-(1 << 33) - 1) == 0xffffffff)
225assert(bit32.band((1 << 33) + 1) == 1)
226assert(bit32.band(-(1 << 33) + 1) == 1)
227assert(bit32.band(-(1 << 40)) == 0)
228assert(bit32.band(1 << 40) == 0)
229assert(bit32.band(-(1 << 40) - 2) == 0xfffffffe)
230assert(bit32.band((1 << 40) - 4) == 0xfffffffc)
231
232assert(bit32.lrotate(0, -1) == 0)
233assert(bit32.lrotate(0, 7) == 0)
234assert(bit32.lrotate(0x12345678, 0) == 0x12345678)
235assert(bit32.lrotate(0x12345678, 32) == 0x12345678)
236assert(bit32.lrotate(0x12345678, 4) == 0x23456781)
237assert(bit32.rrotate(0x12345678, -4) == 0x23456781)
238assert(bit32.lrotate(0x12345678, -8) == 0x78123456)
239assert(bit32.rrotate(0x12345678, 8) == 0x78123456)
240assert(bit32.lrotate(0xaaaaaaaa, 2) == 0xaaaaaaaa)
241assert(bit32.lrotate(0xaaaaaaaa, -2) == 0xaaaaaaaa)
242for i = -50, 50 do
243  assert(bit32.lrotate(0x89abcdef, i) == bit32.lrotate(0x89abcdef, i%32))
244end
245
246assert(bit32.lshift(0x12345678, 4) == 0x23456780)
247assert(bit32.lshift(0x12345678, 8) == 0x34567800)
248assert(bit32.lshift(0x12345678, -4) == 0x01234567)
249assert(bit32.lshift(0x12345678, -8) == 0x00123456)
250assert(bit32.lshift(0x12345678, 32) == 0)
251assert(bit32.lshift(0x12345678, -32) == 0)
252assert(bit32.rshift(0x12345678, 4) == 0x01234567)
253assert(bit32.rshift(0x12345678, 8) == 0x00123456)
254assert(bit32.rshift(0x12345678, 32) == 0)
255assert(bit32.rshift(0x12345678, -32) == 0)
256assert(bit32.arshift(0x12345678, 0) == 0x12345678)
257assert(bit32.arshift(0x12345678, 1) == 0x12345678 // 2)
258assert(bit32.arshift(0x12345678, -1) == 0x12345678 * 2)
259assert(bit32.arshift(-1, 1) == 0xffffffff)
260assert(bit32.arshift(-1, 24) == 0xffffffff)
261assert(bit32.arshift(-1, 32) == 0xffffffff)
262assert(bit32.arshift(-1, -1) == bit32.band(-1 * 2, 0xffffffff))
263
264assert(0x12345678 << 4 == 0x123456780)
265assert(0x12345678 << 8 == 0x1234567800)
266assert(0x12345678 << -4 == 0x01234567)
267assert(0x12345678 << -8 == 0x00123456)
268assert(0x12345678 << 32 == 0x1234567800000000)
269assert(0x12345678 << -32 == 0)
270assert(0x12345678 >> 4 == 0x01234567)
271assert(0x12345678 >> 8 == 0x00123456)
272assert(0x12345678 >> 32 == 0)
273assert(0x12345678 >> -32 == 0x1234567800000000)
274
275print("+")
276-- some special cases
277local c = {0, 1, 2, 3, 10, 0x80000000, 0xaaaaaaaa, 0x55555555,
278           0xffffffff, 0x7fffffff}
279
280for _, b in pairs(c) do
281  assert(bit32.band(b) == b)
282  assert(bit32.band(b, b) == b)
283  assert(bit32.band(b, b, b, b) == b)
284  assert(bit32.btest(b, b) == (b ~= 0))
285  assert(bit32.band(b, b, b) == b)
286  assert(bit32.band(b, b, b, ~b) == 0)
287  assert(bit32.btest(b, b, b) == (b ~= 0))
288  assert(bit32.band(b, bit32.bnot(b)) == 0)
289  assert(bit32.bor(b, bit32.bnot(b)) == bit32.bnot(0))
290  assert(bit32.bor(b) == b)
291  assert(bit32.bor(b, b) == b)
292  assert(bit32.bor(b, b, b) == b)
293  assert(bit32.bor(b, b, 0, ~b) == 0xffffffff)
294  assert(bit32.bxor(b) == b)
295  assert(bit32.bxor(b, b) == 0)
296  assert(bit32.bxor(b, b, b) == b)
297  assert(bit32.bxor(b, b, b, b) == 0)
298  assert(bit32.bxor(b, 0) == b)
299  assert(bit32.bnot(b) ~= b)
300  assert(bit32.bnot(bit32.bnot(b)) == b)
301  assert(bit32.bnot(b) == (1 << 32) - 1 - b)
302  assert(bit32.lrotate(b, 32) == b)
303  assert(bit32.rrotate(b, 32) == b)
304  assert(bit32.lshift(bit32.lshift(b, -4), 4) == bit32.band(b, bit32.bnot(0xf)))
305  assert(bit32.rshift(bit32.rshift(b, 4), -4) == bit32.band(b, bit32.bnot(0xf)))
306end
307
308-- for this test, use at most 24 bits (mantissa of a single float)
309c = {0, 1, 2, 3, 10, 0x800000, 0xaaaaaa, 0x555555, 0xffffff, 0x7fffff}
310for _, b in pairs(c) do
311  for i = -40, 40 do
312    local x = bit32.lshift(b, i)
313    local y = math.floor(math.fmod(b * 2.0^i, 2.0^32))
314    assert(math.fmod(x - y, 2.0^32) == 0)
315  end
316end
317
318assert(not pcall(bit32.band, {}))
319assert(not pcall(bit32.bnot, "a"))
320assert(not pcall(bit32.lshift, 45))
321assert(not pcall(bit32.lshift, 45, print))
322assert(not pcall(bit32.rshift, 45, print))
323
324print("+")
325
326
327-- testing extract/replace
328
329assert(bit32.extract(0x12345678, 0, 4) == 8)
330assert(bit32.extract(0x12345678, 4, 4) == 7)
331assert(bit32.extract(0xa0001111, 28, 4) == 0xa)
332assert(bit32.extract(0xa0001111, 31, 1) == 1)
333assert(bit32.extract(0x50000111, 31, 1) == 0)
334assert(bit32.extract(0xf2345679, 0, 32) == 0xf2345679)
335
336assert(not pcall(bit32.extract, 0, -1))
337assert(not pcall(bit32.extract, 0, 32))
338assert(not pcall(bit32.extract, 0, 0, 33))
339assert(not pcall(bit32.extract, 0, 31, 2))
340
341assert(bit32.replace(0x12345678, 5, 28, 4) == 0x52345678)
342assert(bit32.replace(0x12345678, 0x87654321, 0, 32) == 0x87654321)
343assert(bit32.replace(0, 1, 2) == 2^2)
344assert(bit32.replace(0, -1, 4) == 2^4)
345assert(bit32.replace(-1, 0, 31) == (1 << 31) - 1)
346assert(bit32.replace(-1, 0, 1, 2) == (1 << 32) - 7)
347
348
349-- testing conversion of floats
350
351assert(bit32.bor(3.0) == 3)
352assert(bit32.bor(-4.0) == 0xfffffffc)
353
354-- large floats and large-enough integers?
355if 2.0^50 < 2.0^50 + 1.0 and 2.0^50 < (-1 >> 1) then
356  assert(bit32.bor(2.0^32 - 5.0) == 0xfffffffb)
357  assert(bit32.bor(-2.0^32 - 6.0) == 0xfffffffa)
358  assert(bit32.bor(2.0^48 - 5.0) == 0xfffffffb)
359  assert(bit32.bor(-2.0^48 - 6.0) == 0xfffffffa)
360end
361
362print'OK'
363