diff options
Diffstat (limited to 'testes/bitwise.lua')
-rwxr-xr-x | testes/bitwise.lua | 328 |
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 | |||
4 | print("testing bitwise operations") | ||
5 | |||
6 | local numbits = string.packsize('j') * 8 | ||
7 | |||
8 | assert(~0 == -1) | ||
9 | |||
10 | assert((1 << (numbits - 1)) == math.mininteger) | ||
11 | |||
12 | -- basic tests for bitwise operators; | ||
13 | -- use variables to avoid constant folding | ||
14 | local a, b, c, d | ||
15 | a = 0xFFFFFFFFFFFFFFFF | ||
16 | assert(a == -1 and a & -1 == a and a & 35 == 35) | ||
17 | a = 0xF0F0F0F0F0F0F0F0 | ||
18 | assert(a | -1 == -1) | ||
19 | assert(a ~ a == 0 and a ~ 0 == a and a ~ ~a == -1) | ||
20 | assert(a >> 4 == ~a) | ||
21 | a = 0xF0; b = 0xCC; c = 0xAA; d = 0xFD | ||
22 | assert(a | b ~ c & d == 0xF4) | ||
23 | |||
24 | a = 0xF0.0; b = 0xCC.0; c = "0xAA.0"; d = "0xFD.0" | ||
25 | assert(a | b ~ c & d == 0xF4) | ||
26 | |||
27 | a = 0xF0000000; b = 0xCC000000; | ||
28 | c = 0xAA000000; d = 0xFD000000 | ||
29 | assert(a | b ~ c & d == 0xF4000000) | ||
30 | assert(~~a == a and ~a == -1 ~ a and -d == ~d + 1) | ||
31 | |||
32 | a = a << 32 | ||
33 | b = b << 32 | ||
34 | c = c << 32 | ||
35 | d = d << 32 | ||
36 | assert(a | b ~ c & d == 0xF4000000 << 32) | ||
37 | assert(~~a == a and ~a == -1 ~ a and -d == ~d + 1) | ||
38 | |||
39 | assert(-1 >> 1 == (1 << (numbits - 1)) - 1 and 1 << 31 == 0x80000000) | ||
40 | assert(-1 >> (numbits - 1) == 1) | ||
41 | assert(-1 >> numbits == 0 and | ||
42 | -1 >> -numbits == 0 and | ||
43 | -1 << numbits == 0 and | ||
44 | -1 << -numbits == 0) | ||
45 | |||
46 | assert((2^30 - 1) << 2^30 == 0) | ||
47 | assert((2^30 - 1) >> 2^30 == 0) | ||
48 | |||
49 | assert(1 >> -3 == 1 << 3 and 1000 >> 5 == 1000 << -5) | ||
50 | |||
51 | |||
52 | -- coercion from strings to integers | ||
53 | assert("0xffffffffffffffff" | 0 == -1) | ||
54 | assert("0xfffffffffffffffe" & "-1" == -2) | ||
55 | assert(" \t-0xfffffffffffffffe\n\t" & "-1" == 2) | ||
56 | assert(" \n -45 \t " >> " -2 " == -45 * 4) | ||
57 | |||
58 | -- out of range number | ||
59 | assert(not pcall(function () return "0xffffffffffffffff.0" | 0 end)) | ||
60 | |||
61 | -- embedded zeros | ||
62 | assert(not pcall(function () return "0xffffffffffffffff\0" | 0 end)) | ||
63 | |||
64 | print'+' | ||
65 | |||
66 | |||
67 | package.preload.bit32 = function () --{ | ||
68 | |||
69 | -- no built-in 'bit32' library: implement it using bitwise operators | ||
70 | |||
71 | local bit = {} | ||
72 | |||
73 | function bit.bnot (a) | ||
74 | return ~a & 0xFFFFFFFF | ||
75 | end | ||
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 | |||
83 | function 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 | ||
92 | end | ||
93 | |||
94 | function 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 | ||
103 | end | ||
104 | |||
105 | function 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 | ||
114 | end | ||
115 | |||
116 | function bit.btest (...) | ||
117 | return bit.band(...) ~= 0 | ||
118 | end | ||
119 | |||
120 | function bit.lshift (a, b) | ||
121 | return ((a & 0xFFFFFFFF) << b) & 0xFFFFFFFF | ||
122 | end | ||
123 | |||
124 | function bit.rshift (a, b) | ||
125 | return ((a & 0xFFFFFFFF) >> b) & 0xFFFFFFFF | ||
126 | end | ||
127 | |||
128 | function 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 | ||
135 | end | ||
136 | |||
137 | function bit.lrotate (a ,b) | ||
138 | b = b & 31 | ||
139 | a = a & 0xFFFFFFFF | ||
140 | a = (a << b) | (a >> (32 - b)) | ||
141 | return a & 0xFFFFFFFF | ||
142 | end | ||
143 | |||
144 | function bit.rrotate (a, b) | ||
145 | return bit.lrotate(a, -b) | ||
146 | end | ||
147 | |||
148 | local 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) | ||
154 | end | ||
155 | |||
156 | function bit.extract (a, f, w) | ||
157 | local f, mask = checkfield(f, w) | ||
158 | return (a >> f) & mask | ||
159 | end | ||
160 | |||
161 | function 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 | ||
166 | end | ||
167 | |||
168 | return bit | ||
169 | |||
170 | end --} | ||
171 | |||
172 | |||
173 | print("testing bitwise library") | ||
174 | |||
175 | local bit32 = require'bit32' | ||
176 | |||
177 | assert(bit32.band() == bit32.bnot(0)) | ||
178 | assert(bit32.btest() == true) | ||
179 | assert(bit32.bor() == 0) | ||
180 | assert(bit32.bxor() == 0) | ||
181 | |||
182 | assert(bit32.band() == bit32.band(0xffffffff)) | ||
183 | assert(bit32.band(1,2) == 0) | ||
184 | |||
185 | |||
186 | -- out-of-range numbers | ||
187 | assert(bit32.band(-1) == 0xffffffff) | ||
188 | assert(bit32.band((1 << 33) - 1) == 0xffffffff) | ||
189 | assert(bit32.band(-(1 << 33) - 1) == 0xffffffff) | ||
190 | assert(bit32.band((1 << 33) + 1) == 1) | ||
191 | assert(bit32.band(-(1 << 33) + 1) == 1) | ||
192 | assert(bit32.band(-(1 << 40)) == 0) | ||
193 | assert(bit32.band(1 << 40) == 0) | ||
194 | assert(bit32.band(-(1 << 40) - 2) == 0xfffffffe) | ||
195 | assert(bit32.band((1 << 40) - 4) == 0xfffffffc) | ||
196 | |||
197 | assert(bit32.lrotate(0, -1) == 0) | ||
198 | assert(bit32.lrotate(0, 7) == 0) | ||
199 | assert(bit32.lrotate(0x12345678, 0) == 0x12345678) | ||
200 | assert(bit32.lrotate(0x12345678, 32) == 0x12345678) | ||
201 | assert(bit32.lrotate(0x12345678, 4) == 0x23456781) | ||
202 | assert(bit32.rrotate(0x12345678, -4) == 0x23456781) | ||
203 | assert(bit32.lrotate(0x12345678, -8) == 0x78123456) | ||
204 | assert(bit32.rrotate(0x12345678, 8) == 0x78123456) | ||
205 | assert(bit32.lrotate(0xaaaaaaaa, 2) == 0xaaaaaaaa) | ||
206 | assert(bit32.lrotate(0xaaaaaaaa, -2) == 0xaaaaaaaa) | ||
207 | for i = -50, 50 do | ||
208 | assert(bit32.lrotate(0x89abcdef, i) == bit32.lrotate(0x89abcdef, i%32)) | ||
209 | end | ||
210 | |||
211 | assert(bit32.lshift(0x12345678, 4) == 0x23456780) | ||
212 | assert(bit32.lshift(0x12345678, 8) == 0x34567800) | ||
213 | assert(bit32.lshift(0x12345678, -4) == 0x01234567) | ||
214 | assert(bit32.lshift(0x12345678, -8) == 0x00123456) | ||
215 | assert(bit32.lshift(0x12345678, 32) == 0) | ||
216 | assert(bit32.lshift(0x12345678, -32) == 0) | ||
217 | assert(bit32.rshift(0x12345678, 4) == 0x01234567) | ||
218 | assert(bit32.rshift(0x12345678, 8) == 0x00123456) | ||
219 | assert(bit32.rshift(0x12345678, 32) == 0) | ||
220 | assert(bit32.rshift(0x12345678, -32) == 0) | ||
221 | assert(bit32.arshift(0x12345678, 0) == 0x12345678) | ||
222 | assert(bit32.arshift(0x12345678, 1) == 0x12345678 // 2) | ||
223 | assert(bit32.arshift(0x12345678, -1) == 0x12345678 * 2) | ||
224 | assert(bit32.arshift(-1, 1) == 0xffffffff) | ||
225 | assert(bit32.arshift(-1, 24) == 0xffffffff) | ||
226 | assert(bit32.arshift(-1, 32) == 0xffffffff) | ||
227 | assert(bit32.arshift(-1, -1) == bit32.band(-1 * 2, 0xffffffff)) | ||
228 | |||
229 | assert(0x12345678 << 4 == 0x123456780) | ||
230 | assert(0x12345678 << 8 == 0x1234567800) | ||
231 | assert(0x12345678 << -4 == 0x01234567) | ||
232 | assert(0x12345678 << -8 == 0x00123456) | ||
233 | assert(0x12345678 << 32 == 0x1234567800000000) | ||
234 | assert(0x12345678 << -32 == 0) | ||
235 | assert(0x12345678 >> 4 == 0x01234567) | ||
236 | assert(0x12345678 >> 8 == 0x00123456) | ||
237 | assert(0x12345678 >> 32 == 0) | ||
238 | assert(0x12345678 >> -32 == 0x1234567800000000) | ||
239 | |||
240 | print("+") | ||
241 | -- some special cases | ||
242 | local c = {0, 1, 2, 3, 10, 0x80000000, 0xaaaaaaaa, 0x55555555, | ||
243 | 0xffffffff, 0x7fffffff} | ||
244 | |||
245 | for _, 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))) | ||
271 | end | ||
272 | |||
273 | -- for this test, use at most 24 bits (mantissa of a single float) | ||
274 | c = {0, 1, 2, 3, 10, 0x800000, 0xaaaaaa, 0x555555, 0xffffff, 0x7fffff} | ||
275 | for _, 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 | ||
281 | end | ||
282 | |||
283 | assert(not pcall(bit32.band, {})) | ||
284 | assert(not pcall(bit32.bnot, "a")) | ||
285 | assert(not pcall(bit32.lshift, 45)) | ||
286 | assert(not pcall(bit32.lshift, 45, print)) | ||
287 | assert(not pcall(bit32.rshift, 45, print)) | ||
288 | |||
289 | print("+") | ||
290 | |||
291 | |||
292 | -- testing extract/replace | ||
293 | |||
294 | assert(bit32.extract(0x12345678, 0, 4) == 8) | ||
295 | assert(bit32.extract(0x12345678, 4, 4) == 7) | ||
296 | assert(bit32.extract(0xa0001111, 28, 4) == 0xa) | ||
297 | assert(bit32.extract(0xa0001111, 31, 1) == 1) | ||
298 | assert(bit32.extract(0x50000111, 31, 1) == 0) | ||
299 | assert(bit32.extract(0xf2345679, 0, 32) == 0xf2345679) | ||
300 | |||
301 | assert(not pcall(bit32.extract, 0, -1)) | ||
302 | assert(not pcall(bit32.extract, 0, 32)) | ||
303 | assert(not pcall(bit32.extract, 0, 0, 33)) | ||
304 | assert(not pcall(bit32.extract, 0, 31, 2)) | ||
305 | |||
306 | assert(bit32.replace(0x12345678, 5, 28, 4) == 0x52345678) | ||
307 | assert(bit32.replace(0x12345678, 0x87654321, 0, 32) == 0x87654321) | ||
308 | assert(bit32.replace(0, 1, 2) == 2^2) | ||
309 | assert(bit32.replace(0, -1, 4) == 2^4) | ||
310 | assert(bit32.replace(-1, 0, 31) == (1 << 31) - 1) | ||
311 | assert(bit32.replace(-1, 0, 1, 2) == (1 << 32) - 7) | ||
312 | |||
313 | |||
314 | -- testing conversion of floats | ||
315 | |||
316 | assert(bit32.bor(3.0) == 3) | ||
317 | assert(bit32.bor(-4.0) == 0xfffffffc) | ||
318 | |||
319 | -- large floats and large-enough integers? | ||
320 | if 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) | ||
325 | end | ||
326 | |||
327 | print'OK' | ||
328 | |||