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