github.com/tunabay/go-bitarray@v1.3.1/bitarray_bitwise_test.go (about) 1 // Copyright (c) 2021 Hirotsuna Mizuno. All rights reserved. 2 // Use of this source code is governed by the MIT license that can be found in 3 // the LICENSE file. 4 5 package bitarray_test 6 7 import ( 8 "testing" 9 10 "github.com/tunabay/go-bitarray" 11 ) 12 13 func TestBitArray_TrailingZeros(t *testing.T) { 14 tcs := []struct { 15 s string 16 n int 17 }{ 18 {"", 0}, 19 {"1", 0}, 20 {"10", 1}, 21 {"110", 1}, 22 {"1110", 1}, 23 {"0", 1}, 24 {"00", 2}, 25 {"000", 3}, 26 {"0000", 4}, 27 {"0000-0", 5}, 28 {"0000-00", 6}, 29 {"0000-000", 7}, 30 {"0000-0000", 8}, 31 {"0000-0000 0", 9}, 32 {"0000-0000 00", 10}, 33 {"0000-0000 000", 11}, 34 {"0000-0000 0000", 12}, 35 {"0000-0000 0000-0000 0000-0000 0000-0000 0000", 36}, 36 {"0000-0000 0000-0000 0000-0000 0000-0000 0000-000", 39}, 37 {"0000-0000 0000-0000 0000-0000 0000-0000 0000-0000", 40}, 38 {"0000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0", 41}, 39 {"0000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0000", 44}, 40 {"0000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0000-0000", 48}, 41 {"0001-000", 3}, 42 {"0001-0000", 4}, 43 {"0001-0000 0", 5}, 44 {"0001-0001", 0}, 45 {"0001-0000 1", 0}, 46 {"0001-0001 00", 2}, 47 {"0001-0000 100", 2}, 48 {"1100-0000 1011-0", 1}, 49 {"1100-0000 1011-00", 2}, 50 {"1100-0000 1011-000", 3}, 51 {"1100-0000 1011-0000", 4}, 52 {"1100-0000 1011-0000 0", 5}, 53 {"1100-0000 1011-0000 1", 0}, 54 {"1100-0000 1011-0000 10", 1}, 55 {"1100-0000 1011-0000 11", 0}, 56 {"1010-0000 0000-0000 00", 15}, 57 {"1010-0000 0000-0000 0000-0000 00", 23}, 58 {"1010-0000 0000-0000 0000-0000 0000-0000", 29}, 59 {"1010-0000 0000-0000 0000-0000 0000-0000 0", 30}, 60 {"1010-0000 0000-0000 0000-0000 0000-0000 00", 31}, 61 {"1", 0}, 62 {"11", 0}, 63 {"111", 0}, 64 {"1111", 0}, 65 {"1111-1", 0}, 66 {"1111-11", 0}, 67 {"1111-111", 0}, 68 {"1111-1111", 0}, 69 {"1111-1111 0", 1}, 70 {"1111-1111 00", 2}, 71 {"1111-1111 1", 0}, 72 {"1111-1111 10", 1}, 73 {"1111-1111 1100-00", 4}, 74 {"1111-1111 1100-000", 5}, 75 {"1111-1111 1100-0000", 6}, 76 {"1111-1111 1100-0000 0", 7}, 77 {"1111-1111 1100-0000 00", 8}, 78 {"1111-1111 1111-111", 0}, 79 {"1111-1111 1111-1111", 0}, 80 {"1111-1111 1111-1111 1", 0}, 81 {"0000-0000 0000-0000 1111-1111 0000-0000 00", 10}, 82 {"0000-0000 0000-0000 1111-1110 0000-0000 00", 11}, 83 {"0000-0000 0000-0000 1111-1111 0000-0000 11", 0}, 84 } 85 for _, tc := range tcs { 86 for i := 0; i < 3; i++ { 87 ba := bitarray.MustParse(tc.s) 88 switch i { 89 case 1: 90 ba = ba.ZExpand() 91 case 2: 92 ba = ba.ZOptimize() 93 } 94 if n := ba.TrailingZeros(); n != tc.n { 95 t.Errorf("unexpected result: got %d, want %d", n, tc.n) 96 t.Logf("data: %#b", ba) 97 t.Logf("data: %s", ba.D()) 98 } 99 } 100 } 101 } 102 103 func TestBitArray_LeadingZeros(t *testing.T) { 104 tcs := []struct { 105 s string 106 n int 107 }{ 108 {"", 0}, 109 {"1", 0}, 110 {"10", 0}, 111 {"110", 0}, 112 {"1110", 0}, 113 {"1110-0000", 0}, 114 {"1110-0000 0", 0}, 115 {"1000-0000 0000-0000", 0}, 116 {"1000-0000 0000-0000 0000-0000 0", 0}, 117 {"1000-0000 0000-0000 0000-0000 1", 0}, 118 {"1000-0000 0000-0000 0000-0000 01", 0}, 119 {"01", 1}, 120 {"001", 2}, 121 {"0001", 3}, 122 {"0", 1}, 123 {"00", 2}, 124 {"000", 3}, 125 {"0000", 4}, 126 {"0000-0", 5}, 127 {"0000-00", 6}, 128 {"0000-000", 7}, 129 {"0000-0000", 8}, 130 {"0000-0000 0", 9}, 131 {"0000-0000 00", 10}, 132 {"0000-0000 000", 11}, 133 {"0000-0000 0000", 12}, 134 {"0000-0000 0000-0000 0000-0000 0000-0000 0000", 36}, 135 {"0000-0000 0000-0000 0000-0000 0000-0000 0000-000", 39}, 136 {"0000-0000 0000-0000 0000-0000 0000-0000 0000-0000", 40}, 137 {"0000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0", 41}, 138 {"0000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0000", 44}, 139 {"0000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0000-0000", 48}, 140 {"0001-000", 3}, 141 {"0001-0000", 3}, 142 {"0001-0000 0", 3}, 143 {"0001-0001", 3}, 144 {"0001-0000 1", 3}, 145 {"0000-0000 0111-0", 9}, 146 {"0000-0000 1111-0", 8}, 147 {"0000-0001 0111-0", 7}, 148 {"0000-0010 0111-0", 6}, 149 {"0000-0100 0111-0", 5}, 150 {"0000-0000 0000-0000 0000-0000 01", 25}, 151 {"0000-0000 0000-0000 0000-0000 10", 24}, 152 {"0000-0000 0000-0000 0000-0001 00", 23}, 153 {"0000-0000 0000-0000 0001-0000 00", 19}, 154 {"0000-0000 0000-0000 1000-0000 00", 16}, 155 {"0000-0000 0000-0001 0000-0000 00", 15}, 156 {"0000-0000 0000-0000 0000-0000 0000-0000", 32}, 157 {"0000-0000 0000-0000 0000-0000 0000-0001", 31}, 158 {"0000-0000 0000-0000 0000-0000 0000-0010", 30}, 159 {"0000-0000 0000-0000 0000-0000 0001-0000", 27}, 160 {"0000-0000 0000-0000 0000-0000 1000-0000", 24}, 161 } 162 for _, tc := range tcs { 163 for i := 0; i < 3; i++ { 164 ba := bitarray.MustParse(tc.s) 165 switch i { 166 case 1: 167 ba = ba.ZExpand() 168 case 2: 169 ba = ba.ZOptimize() 170 } 171 if n := ba.LeadingZeros(); n != tc.n { 172 t.Errorf("unexpected result: got %d, want %d", n, tc.n) 173 t.Logf("data: %#b", ba) 174 t.Logf("data: %s", ba.D()) 175 } 176 } 177 } 178 } 179 180 func TestBitArray_OnesCount(t *testing.T) { 181 tcs := []struct { 182 s string 183 n int 184 }{ 185 {"", 0}, 186 {"1", 1}, 187 {"10", 1}, 188 {"01", 1}, 189 {"000", 0}, 190 {"100", 1}, 191 {"001", 1}, 192 {"111", 3}, 193 {"0010", 1}, 194 {"0011-1100", 4}, 195 {"0100-0010 0", 2}, 196 {"1000-0011 1", 4}, 197 {"0000-0110 0011-1000", 5}, 198 {"0000-0000 0000-0000 0000-0000 00", 0}, 199 {"0000-0000 0000-0000 0000-0000 0000-0000", 0}, 200 {"0000-0000 0000-0000 0000-0000 01", 1}, 201 {"0010-0000 0000-1000 0001-0000 10", 4}, 202 {"0000-1111 1111-1111 1111-1111 1111-1111", 28}, 203 {"1111-1111 1111-1111 1111-1111 1111-1111", 32}, 204 {"1111-1111 1111-1111 1111-1111 1111-1111 111", 35}, 205 {"0111-1111 1111-1111 1111-1111 1111-1111 110", 33}, 206 {"0x_ffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff_fff", 156}, 207 {"0x_ffff_0000_ffff_ffff_ffff_ffff_ffff_ffff_00ff_ff", 128}, 208 } 209 for _, tc := range tcs { 210 for i := 0; i < 3; i++ { 211 ba := bitarray.MustParse(tc.s) 212 switch i { 213 case 1: 214 ba = ba.ZExpand() 215 case 2: 216 ba = ba.ZOptimize() 217 } 218 if n := ba.OnesCount(); n != tc.n { 219 t.Errorf("unexpected result: got %d, want %d", n, tc.n) 220 t.Logf("data: %#b", ba) 221 t.Logf("data: %s", ba.D()) 222 } 223 } 224 } 225 } 226 227 func TestBitArray_And(t *testing.T) { 228 tdt := []string{ 229 "", "", "", 230 "0", "0", "0", 231 "1", "0", "0", 232 "0", "1", "0", 233 "1", "1", "1", 234 "0101-0101", "0000-1010", "0000-0000", 235 "0101-0101", "1100-0011", "0100-0001", 236 "0000-0000 0000-0000", "0000-0000 0000-0000", "0000-0000 0000-0000", 237 "0000-0000 0000-0000", "1111-1111 1111-1111", "0000-0000 0000-0000", 238 "1111-1111 1111-1111", "0000-0000 0000-0000", "0000-0000 0000-0000", 239 "0000-0000 0000-0000 0", "0000-0000 0000-0000 0", "0000-0000 0000-0000 0", 240 "0000-0000 0000-0000 0", "0000-0000 1111-1111 0", "0000-0000 0000-0000 0", 241 "0000-0000 0101-0101 0", "0000-0000 0000-0000 0", "0000-0000 0000-0000 0", 242 "1111-1111 1111-1111 1", "1111-1111 1111-1111 1", "1111-1111 1111-1111 1", 243 "1010-1010 1010-1010 1", "0101-0101 0101-0101 0", "0000-0000 0000-0000 0", 244 245 "0x_00ff_ff00_0000_ffff_0000_00ff_ff00_ffff_0000_ffff_0000_ffff_000f_f0", 246 "0x_0000_ffff_0000_0000_0000_ffff_0000_0000_0000_cafe_0000_39f0_0055_01", 247 "0x_0000_ff00_0000_0000_0000_00ff_0000_0000_0000_cafe_0000_39f0_0005_00", 248 // TODO: more test cases 249 } 250 chk := func(got, want *bitarray.BitArray) { 251 t.Helper() 252 got.V() 253 if !got.Equal(want) { 254 t.Error("unexpected result:") 255 t.Logf(" got: %#b", got) 256 t.Logf(" got: %s", got.D()) 257 t.Logf("want: %#b", want) 258 t.FailNow() 259 } 260 } 261 for i := 0; i < len(tdt); i += 3 { 262 ba0 := bitarray.MustParse(tdt[i]).ZOptimize() 263 ba1 := bitarray.MustParse(tdt[i+1]).ZOptimize() 264 ba2 := bitarray.MustParse(tdt[i+2]) 265 ba0E := ba0.ZExpand() 266 ba1E := ba1.ZExpand() 267 chk(ba0.And(ba1), ba2) 268 chk(ba0.And(ba1E), ba2) 269 chk(ba0E.And(ba1), ba2) 270 chk(ba0E.And(ba1E), ba2) 271 chk(ba1.And(ba0), ba2) 272 chk(ba1.And(ba0E), ba2) 273 chk(ba1E.And(ba0), ba2) 274 chk(ba1E.And(ba0E), ba2) 275 } 276 func() { 277 var ba *bitarray.BitArray 278 defer func() { 279 if recover() == nil { 280 t.Errorf("panic expected: got %#b", ba) 281 } 282 }() 283 ba0 := bitarray.MustParse("0101-0101 01") 284 ba1 := bitarray.MustParse("0101-01") 285 ba = ba0.And(ba1) 286 }() 287 } 288 289 func TestBitArray_Or(t *testing.T) { 290 tdt := []string{ 291 "", "", "", 292 "0", "0", "0", 293 "1", "0", "1", 294 "0", "1", "1", 295 "1", "1", "1", 296 "0101-0101", "0000-1010", "0101-1111", 297 "0101-0101", "1100-0011", "1101-0111", 298 "0000-0000 0000-0000", "0000-0000 0000-0000", "0000-0000 0000-0000", 299 "0000-0000 0000-0000", "1111-1111 1111-1111", "1111-1111 1111-1111", 300 "1111-1111 1111-1111", "0000-0000 0000-0000", "1111-1111 1111-1111", 301 "0000-0000 0000-0000 0", "0000-0000 0000-0000 0", "0000-0000 0000-0000 0", 302 "0000-0000 0000-0000 0", "0000-0000 1111-1111 0", "0000-0000 1111-1111 0", 303 "0000-0000 0101-0101 0", "0000-0000 0000-0000 0", "0000-0000 0101-0101 0", 304 "1111-1111 1111-1111 1", "1111-1111 1111-1111 1", "1111-1111 1111-1111 1", 305 "1010-1010 1010-1010 1", "0101-0101 0101-0101 0", "1111-1111 1111-1111 1", 306 307 "0x_0000_0000_0000_ffff_0000_0000_0000_ffff_0000_0000_0000_ffff_0000_00", 308 "0x_0000_ffff_0000_0000_0000_ffff_0000_0000_0000_cafe_0000_0000_0055_01", 309 "0x_0000_ffff_0000_ffff_0000_ffff_0000_ffff_0000_cafe_0000_ffff_0055_01", 310 // TODO: more test cases 311 } 312 chk := func(got, want *bitarray.BitArray) { 313 t.Helper() 314 got.V() 315 if !got.Equal(want) { 316 t.Error("unexpected result:") 317 t.Logf(" got: %#b", got) 318 t.Logf(" got: %s", got.D()) 319 t.Logf("want: %#b", want) 320 t.FailNow() 321 } 322 } 323 for i := 0; i < len(tdt); i += 3 { 324 ba0 := bitarray.MustParse(tdt[i]).ZOptimize() 325 ba1 := bitarray.MustParse(tdt[i+1]).ZOptimize() 326 ba2 := bitarray.MustParse(tdt[i+2]) 327 ba0E := ba0.ZExpand() 328 ba1E := ba1.ZExpand() 329 chk(ba0.Or(ba1), ba2) 330 chk(ba0.Or(ba1E), ba2) 331 chk(ba0E.Or(ba1), ba2) 332 chk(ba0E.Or(ba1E), ba2) 333 chk(ba1.Or(ba0), ba2) 334 chk(ba1.Or(ba0E), ba2) 335 chk(ba1E.Or(ba0), ba2) 336 chk(ba1E.Or(ba0E), ba2) 337 } 338 func() { 339 var ba *bitarray.BitArray 340 defer func() { 341 if recover() == nil { 342 t.Errorf("panic expected: got %#b", ba) 343 } 344 }() 345 ba0 := bitarray.MustParse("0101-0101 01") 346 ba1 := bitarray.MustParse("0101-01") 347 ba = ba0.Or(ba1) 348 }() 349 } 350 351 func TestBitArray_Xor(t *testing.T) { 352 tdt := []string{ 353 "", "", "", 354 "0", "0", "0", 355 "1", "0", "1", 356 "0", "1", "1", 357 "1", "1", "0", 358 "0101-0101", "0000-1010", "0101-1111", 359 "0101-0101", "1100-0011", "1001-0110", 360 "0000-0000 0000-0000", "0000-0000 0000-0000", "0000-0000 0000-0000", 361 "0000-0000 0000-0000", "1111-1111 1111-1111", "1111-1111 1111-1111", 362 "1111-1111 1111-1111", "0000-0000 0000-0000", "1111-1111 1111-1111", 363 "0000-0000 0000-0000 0", "0000-0000 0000-0000 0", "0000-0000 0000-0000 0", 364 "0000-0000 0000-0000 0", "0000-0000 1111-1111 0", "0000-0000 1111-1111 0", 365 "0000-0000 0101-0101 0", "0000-0000 0000-0000 0", "0000-0000 0101-0101 0", 366 "1111-1111 1111-1111 1", "1111-1111 1111-1111 1", "0000-0000 0000-0000 0", 367 "1010-1010 1010-1010 1", "0101-0101 0101-0101 0", "1111-1111 1111-1111 1", 368 "1010-1010 1010-1010 1", "1111-0000 1111-1111 1", "0101-1010 0101-0101 0", 369 370 "0x_0000_00ff_0000_ffff_0000_00ff_0000_ffff_0000_0000_0000_ffff_00f0_ff", 371 "0x_0000_ffff_0000_0000_0000_ffff_0000_f0f0_f0f0_cafe_0000_0000_0055_01", 372 "0x_0000_ff00_0000_ffff_0000_ff00_0000_0f0f_f0f0_cafe_0000_ffff_00a5_fe", 373 // TODO: more test cases 374 } 375 chk := func(got, want *bitarray.BitArray) { 376 t.Helper() 377 got.V() 378 if !got.Equal(want) { 379 t.Error("unexpected result:") 380 t.Logf(" got: %#b", got) 381 t.Logf(" got: %s", got.D()) 382 t.Logf("want: %#b", want) 383 t.FailNow() 384 } 385 } 386 for i := 0; i < len(tdt); i += 3 { 387 ba0 := bitarray.MustParse(tdt[i]).ZOptimize() 388 ba1 := bitarray.MustParse(tdt[i+1]).ZOptimize() 389 ba2 := bitarray.MustParse(tdt[i+2]) 390 ba0E := ba0.ZExpand() 391 ba1E := ba1.ZExpand() 392 chk(ba0.Xor(ba1), ba2) 393 chk(ba0.Xor(ba1E), ba2) 394 chk(ba0E.Xor(ba1), ba2) 395 chk(ba0E.Xor(ba1E), ba2) 396 chk(ba1.Xor(ba0), ba2) 397 chk(ba1.Xor(ba0E), ba2) 398 chk(ba1E.Xor(ba0), ba2) 399 chk(ba1E.Xor(ba0E), ba2) 400 } 401 func() { 402 var ba *bitarray.BitArray 403 defer func() { 404 if recover() == nil { 405 t.Errorf("panic expected: got %#b", ba) 406 } 407 }() 408 ba0 := bitarray.MustParse("0101-0101 01") 409 ba1 := bitarray.MustParse("0101-01") 410 ba = ba0.Xor(ba1) 411 }() 412 } 413 414 func TestBitArray_Not(t *testing.T) { 415 tdt := []string{ 416 "", "", 417 "0", "1", 418 "1", "0", 419 "000", "111", 420 "111", "000", 421 "0101-0101", "1010-1010", 422 "0101-0101 11", "1010-1010 00", 423 "0000-0000 0000-000", "1111-1111 1111-111", 424 "0000-0000 0000-0000", "1111-1111 1111-1111", 425 "0000-0000 0000-0000 0", "1111-1111 1111-1111 1", 426 "1111-1111 1111-111", "0000-0000 0000-000", 427 "1111-1111 1111-1111", "0000-0000 0000-0000", 428 "1111-1111 1111-1111 1", "0000-0000 0000-0000 0", 429 "0000-1111 1111-0000 00", "1111-0000 0000-1111 11", 430 "1010-1010 1010-1010 1010-1", "0101-0101 0101-0101 0101-0", 431 "0x_f0f0_f0f0 0x_6969_6969 101", "0x_0f0f_0f0f 0x_9696_9696 010", 432 // TODO: more test cases 433 } 434 chk := func(got, want *bitarray.BitArray) { 435 t.Helper() 436 got.V() 437 if !got.Equal(want) { 438 t.Error("unexpected result:") 439 t.Logf(" got: %#b", got) 440 t.Logf(" got: %s", got.D()) 441 t.Logf("want: %#b", want) 442 t.FailNow() 443 } 444 } 445 for i := 0; i < len(tdt); i += 2 { 446 ba0 := bitarray.MustParse(tdt[i]).ZOptimize() 447 exp := bitarray.MustParse(tdt[i+1]) 448 ba0E := ba0.ZExpand() 449 chk(ba0.Not(), exp) 450 chk(ba0E.Not(), exp) 451 } 452 } 453 454 func TestBitArray_AndAt(t *testing.T) { 455 tcs := []struct { 456 off int 457 src, mask, dst string 458 }{ 459 {0, "", "", ""}, 460 {3, "1111", "0", "1110"}, 461 {4, "1010", "", "1010"}, 462 {0, "0101-0101 01", "", "0101-0101 01"}, 463 {1, "0000-0000 00", "1111-1111", "0000-0000 00"}, 464 {2, "1111-1111 11", "0000", "1100-0011 11"}, 465 {10, "0101-0101 01", "", "0101-0101 01"}, 466 {1, "1111-0101 01", "0", "1011-0101 01"}, 467 {9, "1111-1111 11", "0", "1111-1111 10"}, 468 {6, "0000-0000 0000-0000 000", "1111-1111 1", "0000-0000 0000-0000 000"}, 469 {6, "1111-1111 1111-1111 111", "0000-0000 0", "1111-1100 0000-0001 111"}, 470 {7, "1111-1111 1111-1111 111", "0", "1111-1110 1111-1111 111"}, 471 {8, "1111-1111 1111-1111 111", "0", "1111-1111 0111-1111 111"}, 472 {9, "1111-1111 1111-1111 111", "0", "1111-1111 1011-1111 111"}, 473 {5, "1111-1111 1111-1111 111", "000", "1111-1000 1111-1111 111"}, 474 {6, "1111-1111 1111-1111 111", "000", "1111-1100 0111-1111 111"}, 475 {7, "1111-1111 1111-1111 111", "000", "1111-1110 0011-1111 111"}, 476 {8, "1111-1111 1111-1111 111", "000", "1111-1111 0001-1111 111"}, 477 {5, "1111-1111 1111-1111 1111-1111", "0000-0000 0000-0000", "1111-1000 0000-0000 0000-0111"}, 478 {5, "1111-1111 1111-1010 1111-1111", "0000-0000 1111-0000", "1111-1000 0000-0010 1000-0111"}, 479 {8, "1111-1111 0101-1010 1111-1111 11", "0000-1111", "1111-1111 0000-1010 1111-1111 11"}, 480 // TODO: more test cases 481 } 482 chk := func(got, want *bitarray.BitArray) { 483 t.Helper() 484 got.V() 485 if !got.Equal(want) { 486 t.Error("unexpected result:") 487 t.Logf(" got: %#b", got) 488 t.Logf(" got: %s", got.D()) 489 t.Logf("want: %#b", want) 490 } 491 } 492 for _, tc := range tcs { 493 ba0 := bitarray.MustParse(tc.src).ZOptimize() 494 ba0E := ba0.ZExpand() 495 ba1 := bitarray.MustParse(tc.mask).ZOptimize() 496 ba1E := ba1.ZExpand() 497 want := bitarray.MustParse(tc.dst) 498 chk(ba0.AndAt(tc.off, ba1), want) 499 chk(ba0.AndAt(tc.off, ba1E), want) 500 chk(ba0E.AndAt(tc.off, ba1), want) 501 chk(ba0E.AndAt(tc.off, ba1E), want) 502 } 503 // panics 504 bap := bitarray.MustParse("1111") 505 chkpanic := func(off int, xs string) { 506 t.Helper() 507 var ba *bitarray.BitArray 508 x := bitarray.MustParse(xs) 509 defer func() { 510 t.Helper() 511 if recover() == nil { 512 t.Errorf("panic expected: off=%d, x=%#b: got %#b", off, x, ba) 513 } 514 }() 515 ba = bap.AndAt(off, x) 516 } 517 chkpanic(-1, "010") 518 chkpanic(0, "01010") 519 chkpanic(3, "01") 520 } 521 522 func TestBitArray_OrAt(t *testing.T) { 523 tcs := []struct { 524 off int 525 src, mask, dst string 526 }{ 527 {0, "", "", ""}, 528 {3, "1111", "0", "1111"}, 529 {4, "1010", "", "1010"}, 530 {0, "0101-0101 01", "", "0101-0101 01"}, 531 {1, "0000-0000 00", "1111-1111", "0111-1111 10"}, 532 {2, "1111-1111 11", "0000", "1111-1111 11"}, 533 {3, "1100-1010 11", "1010", "1101-1110 11"}, 534 {10, "0101-0101 01", "", "0101-0101 01"}, 535 {1, "1000-0101 01", "1", "1100-0101 01"}, 536 {9, "1111-1111 10", "1", "1111-1111 11"}, 537 {6, "0000-0000 0000-0000 000", "1111-1111 1", "0000-0011 1111-1110 000"}, 538 {6, "1111-1111 1111-1111 111", "0000-0000 0", "1111-1111 1111-1111 111"}, 539 {7, "0000-0000 0000-0000 000", "1", "0000-0001 0000-0000 000"}, 540 {8, "0000-0000 0000-0000 000", "1", "0000-0000 1000-0000 000"}, 541 {9, "0000-0000 0000-0000 000", "1", "0000-0000 0100-0000 000"}, 542 {5, "0000-0000 0000-0000 000", "111", "0000-0111 0000-0000 000"}, 543 {6, "0000-0000 0000-0000 000", "111", "0000-0011 1000-0000 000"}, 544 {7, "0000-0000 0000-0000 000", "111", "0000-0001 1100-0000 000"}, 545 {8, "0000-0000 0000-0000 000", "111", "0000-0000 1110-0000 000"}, 546 {5, "0000-0000 0000-0000 0000-0000", "1111-1111 1111-1111", "0000-0111 1111-1111 1111-1000"}, 547 {6, "0000-0000 0000-0000 0000-0000", "1111-1111 1111-1111", "0000-0011 1111-1111 1111-1100"}, 548 {8, "0000-0000 1010-0101 0000-0000 00", "1111-0000", "0000-0000 1111-0101 0000-0000 00"}, 549 // TODO: more test cases 550 } 551 chk := func(got, want *bitarray.BitArray) { 552 t.Helper() 553 got.V() 554 if !got.Equal(want) { 555 t.Error("unexpected result:") 556 t.Logf(" got: %#b", got) 557 t.Logf(" got: %s", got.D()) 558 t.Logf("want: %#b", want) 559 } 560 } 561 for _, tc := range tcs { 562 ba0 := bitarray.MustParse(tc.src).ZOptimize() 563 ba0E := ba0.ZExpand() 564 ba1 := bitarray.MustParse(tc.mask).ZOptimize() 565 ba1E := ba1.ZExpand() 566 want := bitarray.MustParse(tc.dst) 567 chk(ba0.OrAt(tc.off, ba1), want) 568 chk(ba0.OrAt(tc.off, ba1E), want) 569 chk(ba0E.OrAt(tc.off, ba1), want) 570 chk(ba0E.OrAt(tc.off, ba1E), want) 571 } 572 // panics 573 bap := bitarray.MustParse("1111") 574 chkpanic := func(off int, xs string) { 575 t.Helper() 576 var ba *bitarray.BitArray 577 x := bitarray.MustParse(xs) 578 defer func() { 579 t.Helper() 580 if recover() == nil { 581 t.Errorf("panic expected: off=%d, x=%#b: got %#b", off, x, ba) 582 } 583 }() 584 ba = bap.OrAt(off, x) 585 } 586 chkpanic(-1, "010") 587 chkpanic(0, "01010") 588 chkpanic(3, "01") 589 } 590 591 func TestBitArray_XorAt(t *testing.T) { 592 tcs := []struct { 593 off int 594 src, mask, dst string 595 }{ 596 {0, "", "", ""}, 597 {3, "1111", "0", "1111"}, 598 {4, "1010", "", "1010"}, 599 {0, "0101-0101 01", "", "0101-0101 01"}, 600 {1, "0000-0000 00", "1111-1111", "0111-1111 10"}, 601 {2, "1111-1111 11", "0011", "1111-0011 11"}, 602 {3, "1100-1010 11", "1010", "1101-1110 11"}, 603 {10, "0101-0101 01", "", "0101-0101 01"}, 604 {1, "1111-0101 01", "1", "1011-0101 01"}, 605 {9, "1111-1111 11", "1", "1111-1111 10"}, 606 {6, "0000-0000 0000-0000 000", "1111-1111 1", "0000-0011 1111-1110 000"}, 607 {6, "1111-1111 1111-1111 111", "1111-1111 1", "1111-1100 0000-0001 111"}, 608 {7, "1111-1111 1111-1111 111", "1", "1111-1110 1111-1111 111"}, 609 {8, "1111-1111 1111-1111 111", "1", "1111-1111 0111-1111 111"}, 610 {9, "1111-1111 1111-1111 111", "1", "1111-1111 1011-1111 111"}, 611 {5, "0000-1111 0000-0000 000", "111", "0000-1000 0000-0000 000"}, 612 {6, "0000-1111 0000-0000 000", "111", "0000-1100 1000-0000 000"}, 613 {7, "0000-1111 0000-0000 000", "111", "0000-1110 1100-0000 000"}, 614 {8, "0000-1111 0000-0000 000", "111", "0000-1111 1110-0000 000"}, 615 {5, "1111-0000 1111-0000 1111-0000", "1111-1111 1111-1111", "1111-0111 0000-1111 0000-1000"}, 616 {6, "1111-0000 1111-0000 1111-0000", "1111-1111 1111-1111", "1111-0011 0000-1111 0000-1100"}, 617 {8, "0000-0000 1010-0101 0000-0000 00", "1111-0000", "0000-0000 0101-0101 0000-0000 00"}, 618 // TODO: more test cases 619 } 620 chk := func(got, want *bitarray.BitArray) { 621 t.Helper() 622 got.V() 623 if !got.Equal(want) { 624 t.Error("unexpected result:") 625 t.Logf(" got: %#b", got) 626 t.Logf(" got: %s", got.D()) 627 t.Logf("want: %#b", want) 628 } 629 } 630 for _, tc := range tcs { 631 ba0 := bitarray.MustParse(tc.src).ZOptimize() 632 ba0E := ba0.ZExpand() 633 ba1 := bitarray.MustParse(tc.mask).ZOptimize() 634 ba1E := ba1.ZExpand() 635 want := bitarray.MustParse(tc.dst) 636 chk(ba0.XorAt(tc.off, ba1), want) 637 chk(ba0.XorAt(tc.off, ba1E), want) 638 chk(ba0E.XorAt(tc.off, ba1), want) 639 chk(ba0E.XorAt(tc.off, ba1E), want) 640 } 641 // panics 642 bap := bitarray.MustParse("1111") 643 chkpanic := func(off int, xs string) { 644 t.Helper() 645 var ba *bitarray.BitArray 646 x := bitarray.MustParse(xs) 647 defer func() { 648 t.Helper() 649 if recover() == nil { 650 t.Errorf("panic expected: off=%d, x=%#b: got %#b", off, x, ba) 651 } 652 }() 653 ba = bap.XorAt(off, x) 654 } 655 chkpanic(-1, "010") 656 chkpanic(0, "01010") 657 chkpanic(3, "01") 658 }