github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/math/bits/bits_test.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package bits_test 6 7 import ( 8 . "math/bits" 9 "runtime" 10 "testing" 11 "unsafe" 12 ) 13 14 func TestUintSize(t *testing.T) { 15 var x uint 16 if want := unsafe.Sizeof(x) * 8; UintSize != want { 17 t.Fatalf("UintSize = %d; want %d", UintSize, want) 18 } 19 } 20 21 func TestLeadingZeros(t *testing.T) { 22 for i := 0; i < 256; i++ { 23 nlz := tab[i].nlz 24 for k := 0; k < 64-8; k++ { 25 x := uint64(i) << uint(k) 26 if x <= 1<<8-1 { 27 got := LeadingZeros8(uint8(x)) 28 want := nlz - k + (8 - 8) 29 if x == 0 { 30 want = 8 31 } 32 if got != want { 33 t.Fatalf("LeadingZeros8(%#02x) == %d; want %d", x, got, want) 34 } 35 } 36 37 if x <= 1<<16-1 { 38 got := LeadingZeros16(uint16(x)) 39 want := nlz - k + (16 - 8) 40 if x == 0 { 41 want = 16 42 } 43 if got != want { 44 t.Fatalf("LeadingZeros16(%#04x) == %d; want %d", x, got, want) 45 } 46 } 47 48 if x <= 1<<32-1 { 49 got := LeadingZeros32(uint32(x)) 50 want := nlz - k + (32 - 8) 51 if x == 0 { 52 want = 32 53 } 54 if got != want { 55 t.Fatalf("LeadingZeros32(%#08x) == %d; want %d", x, got, want) 56 } 57 if UintSize == 32 { 58 got = LeadingZeros(uint(x)) 59 if got != want { 60 t.Fatalf("LeadingZeros(%#08x) == %d; want %d", x, got, want) 61 } 62 } 63 } 64 65 if x <= 1<<64-1 { 66 got := LeadingZeros64(uint64(x)) 67 want := nlz - k + (64 - 8) 68 if x == 0 { 69 want = 64 70 } 71 if got != want { 72 t.Fatalf("LeadingZeros64(%#016x) == %d; want %d", x, got, want) 73 } 74 if UintSize == 64 { 75 got = LeadingZeros(uint(x)) 76 if got != want { 77 t.Fatalf("LeadingZeros(%#016x) == %d; want %d", x, got, want) 78 } 79 } 80 } 81 } 82 } 83 } 84 85 // Exported (global) variable serving as input for some 86 // of the benchmarks to ensure side-effect free calls 87 // are not optimized away. 88 var Input uint64 = DeBruijn64 89 90 // Exported (global) variable to store function results 91 // during benchmarking to ensure side-effect free calls 92 // are not optimized away. 93 var Output int 94 95 func BenchmarkLeadingZeros(b *testing.B) { 96 var s int 97 for i := 0; i < b.N; i++ { 98 s += LeadingZeros(uint(Input) >> (uint(i) % UintSize)) 99 } 100 Output = s 101 } 102 103 func BenchmarkLeadingZeros8(b *testing.B) { 104 var s int 105 for i := 0; i < b.N; i++ { 106 s += LeadingZeros8(uint8(Input) >> (uint(i) % 8)) 107 } 108 Output = s 109 } 110 111 func BenchmarkLeadingZeros16(b *testing.B) { 112 var s int 113 for i := 0; i < b.N; i++ { 114 s += LeadingZeros16(uint16(Input) >> (uint(i) % 16)) 115 } 116 Output = s 117 } 118 119 func BenchmarkLeadingZeros32(b *testing.B) { 120 var s int 121 for i := 0; i < b.N; i++ { 122 s += LeadingZeros32(uint32(Input) >> (uint(i) % 32)) 123 } 124 Output = s 125 } 126 127 func BenchmarkLeadingZeros64(b *testing.B) { 128 var s int 129 for i := 0; i < b.N; i++ { 130 s += LeadingZeros64(uint64(Input) >> (uint(i) % 64)) 131 } 132 Output = s 133 } 134 135 func TestTrailingZeros(t *testing.T) { 136 for i := 0; i < 256; i++ { 137 ntz := tab[i].ntz 138 for k := 0; k < 64-8; k++ { 139 x := uint64(i) << uint(k) 140 want := ntz + k 141 if x <= 1<<8-1 { 142 got := TrailingZeros8(uint8(x)) 143 if x == 0 { 144 want = 8 145 } 146 if got != want { 147 t.Fatalf("TrailingZeros8(%#02x) == %d; want %d", x, got, want) 148 } 149 } 150 151 if x <= 1<<16-1 { 152 got := TrailingZeros16(uint16(x)) 153 if x == 0 { 154 want = 16 155 } 156 if got != want { 157 t.Fatalf("TrailingZeros16(%#04x) == %d; want %d", x, got, want) 158 } 159 } 160 161 if x <= 1<<32-1 { 162 got := TrailingZeros32(uint32(x)) 163 if x == 0 { 164 want = 32 165 } 166 if got != want { 167 t.Fatalf("TrailingZeros32(%#08x) == %d; want %d", x, got, want) 168 } 169 if UintSize == 32 { 170 got = TrailingZeros(uint(x)) 171 if got != want { 172 t.Fatalf("TrailingZeros(%#08x) == %d; want %d", x, got, want) 173 } 174 } 175 } 176 177 if x <= 1<<64-1 { 178 got := TrailingZeros64(uint64(x)) 179 if x == 0 { 180 want = 64 181 } 182 if got != want { 183 t.Fatalf("TrailingZeros64(%#016x) == %d; want %d", x, got, want) 184 } 185 if UintSize == 64 { 186 got = TrailingZeros(uint(x)) 187 if got != want { 188 t.Fatalf("TrailingZeros(%#016x) == %d; want %d", x, got, want) 189 } 190 } 191 } 192 } 193 } 194 } 195 196 func BenchmarkTrailingZeros(b *testing.B) { 197 var s int 198 for i := 0; i < b.N; i++ { 199 s += TrailingZeros(uint(Input) << (uint(i) % UintSize)) 200 } 201 Output = s 202 } 203 204 func BenchmarkTrailingZeros8(b *testing.B) { 205 var s int 206 for i := 0; i < b.N; i++ { 207 s += TrailingZeros8(uint8(Input) << (uint(i) % 8)) 208 } 209 Output = s 210 } 211 212 func BenchmarkTrailingZeros16(b *testing.B) { 213 var s int 214 for i := 0; i < b.N; i++ { 215 s += TrailingZeros16(uint16(Input) << (uint(i) % 16)) 216 } 217 Output = s 218 } 219 220 func BenchmarkTrailingZeros32(b *testing.B) { 221 var s int 222 for i := 0; i < b.N; i++ { 223 s += TrailingZeros32(uint32(Input) << (uint(i) % 32)) 224 } 225 Output = s 226 } 227 228 func BenchmarkTrailingZeros64(b *testing.B) { 229 var s int 230 for i := 0; i < b.N; i++ { 231 s += TrailingZeros64(uint64(Input) << (uint(i) % 64)) 232 } 233 Output = s 234 } 235 236 func TestOnesCount(t *testing.T) { 237 var x uint64 238 for i := 0; i <= 64; i++ { 239 testOnesCount(t, x, i) 240 x = x<<1 | 1 241 } 242 243 for i := 64; i >= 0; i-- { 244 testOnesCount(t, x, i) 245 x = x << 1 246 } 247 248 for i := 0; i < 256; i++ { 249 for k := 0; k < 64-8; k++ { 250 testOnesCount(t, uint64(i)<<uint(k), tab[i].pop) 251 } 252 } 253 } 254 255 func testOnesCount(t *testing.T, x uint64, want int) { 256 if x <= 1<<8-1 { 257 got := OnesCount8(uint8(x)) 258 if got != want { 259 t.Fatalf("OnesCount8(%#02x) == %d; want %d", uint8(x), got, want) 260 } 261 } 262 263 if x <= 1<<16-1 { 264 got := OnesCount16(uint16(x)) 265 if got != want { 266 t.Fatalf("OnesCount16(%#04x) == %d; want %d", uint16(x), got, want) 267 } 268 } 269 270 if x <= 1<<32-1 { 271 got := OnesCount32(uint32(x)) 272 if got != want { 273 t.Fatalf("OnesCount32(%#08x) == %d; want %d", uint32(x), got, want) 274 } 275 if UintSize == 32 { 276 got = OnesCount(uint(x)) 277 if got != want { 278 t.Fatalf("OnesCount(%#08x) == %d; want %d", uint32(x), got, want) 279 } 280 } 281 } 282 283 if x <= 1<<64-1 { 284 got := OnesCount64(uint64(x)) 285 if got != want { 286 t.Fatalf("OnesCount64(%#016x) == %d; want %d", x, got, want) 287 } 288 if UintSize == 64 { 289 got = OnesCount(uint(x)) 290 if got != want { 291 t.Fatalf("OnesCount(%#016x) == %d; want %d", x, got, want) 292 } 293 } 294 } 295 } 296 297 func BenchmarkOnesCount(b *testing.B) { 298 var s int 299 for i := 0; i < b.N; i++ { 300 s += OnesCount(uint(Input)) 301 } 302 Output = s 303 } 304 305 func BenchmarkOnesCount8(b *testing.B) { 306 var s int 307 for i := 0; i < b.N; i++ { 308 s += OnesCount8(uint8(Input)) 309 } 310 Output = s 311 } 312 313 func BenchmarkOnesCount16(b *testing.B) { 314 var s int 315 for i := 0; i < b.N; i++ { 316 s += OnesCount16(uint16(Input)) 317 } 318 Output = s 319 } 320 321 func BenchmarkOnesCount32(b *testing.B) { 322 var s int 323 for i := 0; i < b.N; i++ { 324 s += OnesCount32(uint32(Input)) 325 } 326 Output = s 327 } 328 329 func BenchmarkOnesCount64(b *testing.B) { 330 var s int 331 for i := 0; i < b.N; i++ { 332 s += OnesCount64(uint64(Input)) 333 } 334 Output = s 335 } 336 337 func TestRotateLeft(t *testing.T) { 338 var m uint64 = DeBruijn64 339 340 for k := uint(0); k < 128; k++ { 341 x8 := uint8(m) 342 got8 := RotateLeft8(x8, int(k)) 343 want8 := x8<<(k&0x7) | x8>>(8-k&0x7) 344 if got8 != want8 { 345 t.Fatalf("RotateLeft8(%#02x, %d) == %#02x; want %#02x", x8, k, got8, want8) 346 } 347 got8 = RotateLeft8(want8, -int(k)) 348 if got8 != x8 { 349 t.Fatalf("RotateLeft8(%#02x, -%d) == %#02x; want %#02x", want8, k, got8, x8) 350 } 351 352 x16 := uint16(m) 353 got16 := RotateLeft16(x16, int(k)) 354 want16 := x16<<(k&0xf) | x16>>(16-k&0xf) 355 if got16 != want16 { 356 t.Fatalf("RotateLeft16(%#04x, %d) == %#04x; want %#04x", x16, k, got16, want16) 357 } 358 got16 = RotateLeft16(want16, -int(k)) 359 if got16 != x16 { 360 t.Fatalf("RotateLeft16(%#04x, -%d) == %#04x; want %#04x", want16, k, got16, x16) 361 } 362 363 x32 := uint32(m) 364 got32 := RotateLeft32(x32, int(k)) 365 want32 := x32<<(k&0x1f) | x32>>(32-k&0x1f) 366 if got32 != want32 { 367 t.Fatalf("RotateLeft32(%#08x, %d) == %#08x; want %#08x", x32, k, got32, want32) 368 } 369 got32 = RotateLeft32(want32, -int(k)) 370 if got32 != x32 { 371 t.Fatalf("RotateLeft32(%#08x, -%d) == %#08x; want %#08x", want32, k, got32, x32) 372 } 373 if UintSize == 32 { 374 x := uint(m) 375 got := RotateLeft(x, int(k)) 376 want := x<<(k&0x1f) | x>>(32-k&0x1f) 377 if got != want { 378 t.Fatalf("RotateLeft(%#08x, %d) == %#08x; want %#08x", x, k, got, want) 379 } 380 got = RotateLeft(want, -int(k)) 381 if got != x { 382 t.Fatalf("RotateLeft(%#08x, -%d) == %#08x; want %#08x", want, k, got, x) 383 } 384 } 385 386 x64 := uint64(m) 387 got64 := RotateLeft64(x64, int(k)) 388 want64 := x64<<(k&0x3f) | x64>>(64-k&0x3f) 389 if got64 != want64 { 390 t.Fatalf("RotateLeft64(%#016x, %d) == %#016x; want %#016x", x64, k, got64, want64) 391 } 392 got64 = RotateLeft64(want64, -int(k)) 393 if got64 != x64 { 394 t.Fatalf("RotateLeft64(%#016x, -%d) == %#016x; want %#016x", want64, k, got64, x64) 395 } 396 if UintSize == 64 { 397 x := uint(m) 398 got := RotateLeft(x, int(k)) 399 want := x<<(k&0x3f) | x>>(64-k&0x3f) 400 if got != want { 401 t.Fatalf("RotateLeft(%#016x, %d) == %#016x; want %#016x", x, k, got, want) 402 } 403 got = RotateLeft(want, -int(k)) 404 if got != x { 405 t.Fatalf("RotateLeft(%#08x, -%d) == %#08x; want %#08x", want, k, got, x) 406 } 407 } 408 } 409 } 410 411 func BenchmarkRotateLeft(b *testing.B) { 412 var s uint 413 for i := 0; i < b.N; i++ { 414 s += RotateLeft(uint(Input), i) 415 } 416 Output = int(s) 417 } 418 419 func BenchmarkRotateLeft8(b *testing.B) { 420 var s uint8 421 for i := 0; i < b.N; i++ { 422 s += RotateLeft8(uint8(Input), i) 423 } 424 Output = int(s) 425 } 426 427 func BenchmarkRotateLeft16(b *testing.B) { 428 var s uint16 429 for i := 0; i < b.N; i++ { 430 s += RotateLeft16(uint16(Input), i) 431 } 432 Output = int(s) 433 } 434 435 func BenchmarkRotateLeft32(b *testing.B) { 436 var s uint32 437 for i := 0; i < b.N; i++ { 438 s += RotateLeft32(uint32(Input), i) 439 } 440 Output = int(s) 441 } 442 443 func BenchmarkRotateLeft64(b *testing.B) { 444 var s uint64 445 for i := 0; i < b.N; i++ { 446 s += RotateLeft64(uint64(Input), i) 447 } 448 Output = int(s) 449 } 450 451 func TestReverse(t *testing.T) { 452 // test each bit 453 for i := uint(0); i < 64; i++ { 454 testReverse(t, uint64(1)<<i, uint64(1)<<(63-i)) 455 } 456 457 // test a few patterns 458 for _, test := range []struct { 459 x, r uint64 460 }{ 461 {0, 0}, 462 {0x1, 0x8 << 60}, 463 {0x2, 0x4 << 60}, 464 {0x3, 0xc << 60}, 465 {0x4, 0x2 << 60}, 466 {0x5, 0xa << 60}, 467 {0x6, 0x6 << 60}, 468 {0x7, 0xe << 60}, 469 {0x8, 0x1 << 60}, 470 {0x9, 0x9 << 60}, 471 {0xa, 0x5 << 60}, 472 {0xb, 0xd << 60}, 473 {0xc, 0x3 << 60}, 474 {0xd, 0xb << 60}, 475 {0xe, 0x7 << 60}, 476 {0xf, 0xf << 60}, 477 {0x5686487, 0xe12616a000000000}, 478 {0x0123456789abcdef, 0xf7b3d591e6a2c480}, 479 } { 480 testReverse(t, test.x, test.r) 481 testReverse(t, test.r, test.x) 482 } 483 } 484 485 func testReverse(t *testing.T, x64, want64 uint64) { 486 x8 := uint8(x64) 487 got8 := Reverse8(x8) 488 want8 := uint8(want64 >> (64 - 8)) 489 if got8 != want8 { 490 t.Fatalf("Reverse8(%#02x) == %#02x; want %#02x", x8, got8, want8) 491 } 492 493 x16 := uint16(x64) 494 got16 := Reverse16(x16) 495 want16 := uint16(want64 >> (64 - 16)) 496 if got16 != want16 { 497 t.Fatalf("Reverse16(%#04x) == %#04x; want %#04x", x16, got16, want16) 498 } 499 500 x32 := uint32(x64) 501 got32 := Reverse32(x32) 502 want32 := uint32(want64 >> (64 - 32)) 503 if got32 != want32 { 504 t.Fatalf("Reverse32(%#08x) == %#08x; want %#08x", x32, got32, want32) 505 } 506 if UintSize == 32 { 507 x := uint(x32) 508 got := Reverse(x) 509 want := uint(want32) 510 if got != want { 511 t.Fatalf("Reverse(%#08x) == %#08x; want %#08x", x, got, want) 512 } 513 } 514 515 got64 := Reverse64(x64) 516 if got64 != want64 { 517 t.Fatalf("Reverse64(%#016x) == %#016x; want %#016x", x64, got64, want64) 518 } 519 if UintSize == 64 { 520 x := uint(x64) 521 got := Reverse(x) 522 want := uint(want64) 523 if got != want { 524 t.Fatalf("Reverse(%#08x) == %#016x; want %#016x", x, got, want) 525 } 526 } 527 } 528 529 func BenchmarkReverse(b *testing.B) { 530 var s uint 531 for i := 0; i < b.N; i++ { 532 s += Reverse(uint(i)) 533 } 534 Output = int(s) 535 } 536 537 func BenchmarkReverse8(b *testing.B) { 538 var s uint8 539 for i := 0; i < b.N; i++ { 540 s += Reverse8(uint8(i)) 541 } 542 Output = int(s) 543 } 544 545 func BenchmarkReverse16(b *testing.B) { 546 var s uint16 547 for i := 0; i < b.N; i++ { 548 s += Reverse16(uint16(i)) 549 } 550 Output = int(s) 551 } 552 553 func BenchmarkReverse32(b *testing.B) { 554 var s uint32 555 for i := 0; i < b.N; i++ { 556 s += Reverse32(uint32(i)) 557 } 558 Output = int(s) 559 } 560 561 func BenchmarkReverse64(b *testing.B) { 562 var s uint64 563 for i := 0; i < b.N; i++ { 564 s += Reverse64(uint64(i)) 565 } 566 Output = int(s) 567 } 568 569 func TestReverseBytes(t *testing.T) { 570 for _, test := range []struct { 571 x, r uint64 572 }{ 573 {0, 0}, 574 {0x01, 0x01 << 56}, 575 {0x0123, 0x2301 << 48}, 576 {0x012345, 0x452301 << 40}, 577 {0x01234567, 0x67452301 << 32}, 578 {0x0123456789, 0x8967452301 << 24}, 579 {0x0123456789ab, 0xab8967452301 << 16}, 580 {0x0123456789abcd, 0xcdab8967452301 << 8}, 581 {0x0123456789abcdef, 0xefcdab8967452301 << 0}, 582 } { 583 testReverseBytes(t, test.x, test.r) 584 testReverseBytes(t, test.r, test.x) 585 } 586 } 587 588 func testReverseBytes(t *testing.T, x64, want64 uint64) { 589 x16 := uint16(x64) 590 got16 := ReverseBytes16(x16) 591 want16 := uint16(want64 >> (64 - 16)) 592 if got16 != want16 { 593 t.Fatalf("ReverseBytes16(%#04x) == %#04x; want %#04x", x16, got16, want16) 594 } 595 596 x32 := uint32(x64) 597 got32 := ReverseBytes32(x32) 598 want32 := uint32(want64 >> (64 - 32)) 599 if got32 != want32 { 600 t.Fatalf("ReverseBytes32(%#08x) == %#08x; want %#08x", x32, got32, want32) 601 } 602 if UintSize == 32 { 603 x := uint(x32) 604 got := ReverseBytes(x) 605 want := uint(want32) 606 if got != want { 607 t.Fatalf("ReverseBytes(%#08x) == %#08x; want %#08x", x, got, want) 608 } 609 } 610 611 got64 := ReverseBytes64(x64) 612 if got64 != want64 { 613 t.Fatalf("ReverseBytes64(%#016x) == %#016x; want %#016x", x64, got64, want64) 614 } 615 if UintSize == 64 { 616 x := uint(x64) 617 got := ReverseBytes(x) 618 want := uint(want64) 619 if got != want { 620 t.Fatalf("ReverseBytes(%#016x) == %#016x; want %#016x", x, got, want) 621 } 622 } 623 } 624 625 func BenchmarkReverseBytes(b *testing.B) { 626 var s uint 627 for i := 0; i < b.N; i++ { 628 s += ReverseBytes(uint(i)) 629 } 630 Output = int(s) 631 } 632 633 func BenchmarkReverseBytes16(b *testing.B) { 634 var s uint16 635 for i := 0; i < b.N; i++ { 636 s += ReverseBytes16(uint16(i)) 637 } 638 Output = int(s) 639 } 640 641 func BenchmarkReverseBytes32(b *testing.B) { 642 var s uint32 643 for i := 0; i < b.N; i++ { 644 s += ReverseBytes32(uint32(i)) 645 } 646 Output = int(s) 647 } 648 649 func BenchmarkReverseBytes64(b *testing.B) { 650 var s uint64 651 for i := 0; i < b.N; i++ { 652 s += ReverseBytes64(uint64(i)) 653 } 654 Output = int(s) 655 } 656 657 func TestLen(t *testing.T) { 658 for i := 0; i < 256; i++ { 659 len := 8 - tab[i].nlz 660 for k := 0; k < 64-8; k++ { 661 x := uint64(i) << uint(k) 662 want := 0 663 if x != 0 { 664 want = len + k 665 } 666 if x <= 1<<8-1 { 667 got := Len8(uint8(x)) 668 if got != want { 669 t.Fatalf("Len8(%#02x) == %d; want %d", x, got, want) 670 } 671 } 672 673 if x <= 1<<16-1 { 674 got := Len16(uint16(x)) 675 if got != want { 676 t.Fatalf("Len16(%#04x) == %d; want %d", x, got, want) 677 } 678 } 679 680 if x <= 1<<32-1 { 681 got := Len32(uint32(x)) 682 if got != want { 683 t.Fatalf("Len32(%#08x) == %d; want %d", x, got, want) 684 } 685 if UintSize == 32 { 686 got := Len(uint(x)) 687 if got != want { 688 t.Fatalf("Len(%#08x) == %d; want %d", x, got, want) 689 } 690 } 691 } 692 693 if x <= 1<<64-1 { 694 got := Len64(uint64(x)) 695 if got != want { 696 t.Fatalf("Len64(%#016x) == %d; want %d", x, got, want) 697 } 698 if UintSize == 64 { 699 got := Len(uint(x)) 700 if got != want { 701 t.Fatalf("Len(%#016x) == %d; want %d", x, got, want) 702 } 703 } 704 } 705 } 706 } 707 } 708 709 const ( 710 _M = 1<<UintSize - 1 711 _M32 = 1<<32 - 1 712 _M64 = 1<<64 - 1 713 ) 714 715 func TestAddSubUint(t *testing.T) { 716 test := func(msg string, f func(x, y, c uint) (z, cout uint), x, y, c, z, cout uint) { 717 z1, cout1 := f(x, y, c) 718 if z1 != z || cout1 != cout { 719 t.Errorf("%s: got z:cout = %#x:%#x; want %#x:%#x", msg, z1, cout1, z, cout) 720 } 721 } 722 for _, a := range []struct{ x, y, c, z, cout uint }{ 723 {0, 0, 0, 0, 0}, 724 {0, 1, 0, 1, 0}, 725 {0, 0, 1, 1, 0}, 726 {0, 1, 1, 2, 0}, 727 {12345, 67890, 0, 80235, 0}, 728 {12345, 67890, 1, 80236, 0}, 729 {_M, 1, 0, 0, 1}, 730 {_M, 0, 1, 0, 1}, 731 {_M, 1, 1, 1, 1}, 732 {_M, _M, 0, _M - 1, 1}, 733 {_M, _M, 1, _M, 1}, 734 } { 735 test("Add", Add, a.x, a.y, a.c, a.z, a.cout) 736 test("Add symmetric", Add, a.y, a.x, a.c, a.z, a.cout) 737 test("Sub", Sub, a.z, a.x, a.c, a.y, a.cout) 738 test("Sub symmetric", Sub, a.z, a.y, a.c, a.x, a.cout) 739 // The above code can't test intrinsic implementation, because the passed function is not called directly. 740 // The following code uses a closure to test the intrinsic version in case the function is intrinsified. 741 test("Add intrinsic", func(x, y, c uint) (uint, uint) { return Add(x, y, c) }, a.x, a.y, a.c, a.z, a.cout) 742 test("Add intrinsic symmetric", func(x, y, c uint) (uint, uint) { return Add(x, y, c) }, a.y, a.x, a.c, a.z, a.cout) 743 test("Sub intrinsic", func(x, y, c uint) (uint, uint) { return Sub(x, y, c) }, a.z, a.x, a.c, a.y, a.cout) 744 test("Sub intrinsic symmetric", func(x, y, c uint) (uint, uint) { return Sub(x, y, c) }, a.z, a.y, a.c, a.x, a.cout) 745 746 } 747 } 748 749 func TestAddSubUint32(t *testing.T) { 750 test := func(msg string, f func(x, y, c uint32) (z, cout uint32), x, y, c, z, cout uint32) { 751 z1, cout1 := f(x, y, c) 752 if z1 != z || cout1 != cout { 753 t.Errorf("%s: got z:cout = %#x:%#x; want %#x:%#x", msg, z1, cout1, z, cout) 754 } 755 } 756 for _, a := range []struct{ x, y, c, z, cout uint32 }{ 757 {0, 0, 0, 0, 0}, 758 {0, 1, 0, 1, 0}, 759 {0, 0, 1, 1, 0}, 760 {0, 1, 1, 2, 0}, 761 {12345, 67890, 0, 80235, 0}, 762 {12345, 67890, 1, 80236, 0}, 763 {_M32, 1, 0, 0, 1}, 764 {_M32, 0, 1, 0, 1}, 765 {_M32, 1, 1, 1, 1}, 766 {_M32, _M32, 0, _M32 - 1, 1}, 767 {_M32, _M32, 1, _M32, 1}, 768 } { 769 test("Add32", Add32, a.x, a.y, a.c, a.z, a.cout) 770 test("Add32 symmetric", Add32, a.y, a.x, a.c, a.z, a.cout) 771 test("Sub32", Sub32, a.z, a.x, a.c, a.y, a.cout) 772 test("Sub32 symmetric", Sub32, a.z, a.y, a.c, a.x, a.cout) 773 } 774 } 775 776 func TestAddSubUint64(t *testing.T) { 777 test := func(msg string, f func(x, y, c uint64) (z, cout uint64), x, y, c, z, cout uint64) { 778 z1, cout1 := f(x, y, c) 779 if z1 != z || cout1 != cout { 780 t.Errorf("%s: got z:cout = %#x:%#x; want %#x:%#x", msg, z1, cout1, z, cout) 781 } 782 } 783 for _, a := range []struct{ x, y, c, z, cout uint64 }{ 784 {0, 0, 0, 0, 0}, 785 {0, 1, 0, 1, 0}, 786 {0, 0, 1, 1, 0}, 787 {0, 1, 1, 2, 0}, 788 {12345, 67890, 0, 80235, 0}, 789 {12345, 67890, 1, 80236, 0}, 790 {_M64, 1, 0, 0, 1}, 791 {_M64, 0, 1, 0, 1}, 792 {_M64, 1, 1, 1, 1}, 793 {_M64, _M64, 0, _M64 - 1, 1}, 794 {_M64, _M64, 1, _M64, 1}, 795 } { 796 test("Add64", Add64, a.x, a.y, a.c, a.z, a.cout) 797 test("Add64 symmetric", Add64, a.y, a.x, a.c, a.z, a.cout) 798 test("Sub64", Sub64, a.z, a.x, a.c, a.y, a.cout) 799 test("Sub64 symmetric", Sub64, a.z, a.y, a.c, a.x, a.cout) 800 // The above code can't test intrinsic implementation, because the passed function is not called directly. 801 // The following code uses a closure to test the intrinsic version in case the function is intrinsified. 802 test("Add64 intrinsic", func(x, y, c uint64) (uint64, uint64) { return Add64(x, y, c) }, a.x, a.y, a.c, a.z, a.cout) 803 test("Add64 intrinsic symmetric", func(x, y, c uint64) (uint64, uint64) { return Add64(x, y, c) }, a.y, a.x, a.c, a.z, a.cout) 804 test("Sub64 intrinsic", func(x, y, c uint64) (uint64, uint64) { return Sub64(x, y, c) }, a.z, a.x, a.c, a.y, a.cout) 805 test("Sub64 intrinsic symmetric", func(x, y, c uint64) (uint64, uint64) { return Sub64(x, y, c) }, a.z, a.y, a.c, a.x, a.cout) 806 } 807 } 808 809 func TestAdd64OverflowPanic(t *testing.T) { 810 // Test that 64-bit overflow panics fire correctly. 811 // These are designed to improve coverage of compiler intrinsics. 812 tests := []func(uint64, uint64) uint64{ 813 func(a, b uint64) uint64 { 814 x, c := Add64(a, b, 0) 815 if c > 0 { 816 panic("overflow") 817 } 818 return x 819 }, 820 func(a, b uint64) uint64 { 821 x, c := Add64(a, b, 0) 822 if c != 0 { 823 panic("overflow") 824 } 825 return x 826 }, 827 func(a, b uint64) uint64 { 828 x, c := Add64(a, b, 0) 829 if c == 1 { 830 panic("overflow") 831 } 832 return x 833 }, 834 func(a, b uint64) uint64 { 835 x, c := Add64(a, b, 0) 836 if c != 1 { 837 return x 838 } 839 panic("overflow") 840 }, 841 func(a, b uint64) uint64 { 842 x, c := Add64(a, b, 0) 843 if c == 0 { 844 return x 845 } 846 panic("overflow") 847 }, 848 } 849 for _, test := range tests { 850 shouldPanic := func(f func()) { 851 defer func() { 852 if err := recover(); err == nil { 853 t.Fatalf("expected panic") 854 } 855 }() 856 f() 857 } 858 859 // overflow 860 shouldPanic(func() { test(_M64, 1) }) 861 shouldPanic(func() { test(1, _M64) }) 862 shouldPanic(func() { test(_M64, _M64) }) 863 864 // no overflow 865 test(_M64, 0) 866 test(0, 0) 867 test(1, 1) 868 } 869 } 870 871 func TestSub64OverflowPanic(t *testing.T) { 872 // Test that 64-bit overflow panics fire correctly. 873 // These are designed to improve coverage of compiler intrinsics. 874 tests := []func(uint64, uint64) uint64{ 875 func(a, b uint64) uint64 { 876 x, c := Sub64(a, b, 0) 877 if c > 0 { 878 panic("overflow") 879 } 880 return x 881 }, 882 func(a, b uint64) uint64 { 883 x, c := Sub64(a, b, 0) 884 if c != 0 { 885 panic("overflow") 886 } 887 return x 888 }, 889 func(a, b uint64) uint64 { 890 x, c := Sub64(a, b, 0) 891 if c == 1 { 892 panic("overflow") 893 } 894 return x 895 }, 896 func(a, b uint64) uint64 { 897 x, c := Sub64(a, b, 0) 898 if c != 1 { 899 return x 900 } 901 panic("overflow") 902 }, 903 func(a, b uint64) uint64 { 904 x, c := Sub64(a, b, 0) 905 if c == 0 { 906 return x 907 } 908 panic("overflow") 909 }, 910 } 911 for _, test := range tests { 912 shouldPanic := func(f func()) { 913 defer func() { 914 if err := recover(); err == nil { 915 t.Fatalf("expected panic") 916 } 917 }() 918 f() 919 } 920 921 // overflow 922 shouldPanic(func() { test(0, 1) }) 923 shouldPanic(func() { test(1, _M64) }) 924 shouldPanic(func() { test(_M64-1, _M64) }) 925 926 // no overflow 927 test(_M64, 0) 928 test(0, 0) 929 test(1, 1) 930 } 931 } 932 933 func TestMulDiv(t *testing.T) { 934 testMul := func(msg string, f func(x, y uint) (hi, lo uint), x, y, hi, lo uint) { 935 hi1, lo1 := f(x, y) 936 if hi1 != hi || lo1 != lo { 937 t.Errorf("%s: got hi:lo = %#x:%#x; want %#x:%#x", msg, hi1, lo1, hi, lo) 938 } 939 } 940 testDiv := func(msg string, f func(hi, lo, y uint) (q, r uint), hi, lo, y, q, r uint) { 941 q1, r1 := f(hi, lo, y) 942 if q1 != q || r1 != r { 943 t.Errorf("%s: got q:r = %#x:%#x; want %#x:%#x", msg, q1, r1, q, r) 944 } 945 } 946 for _, a := range []struct { 947 x, y uint 948 hi, lo, r uint 949 }{ 950 {1 << (UintSize - 1), 2, 1, 0, 1}, 951 {_M, _M, _M - 1, 1, 42}, 952 } { 953 testMul("Mul", Mul, a.x, a.y, a.hi, a.lo) 954 testMul("Mul symmetric", Mul, a.y, a.x, a.hi, a.lo) 955 testDiv("Div", Div, a.hi, a.lo+a.r, a.y, a.x, a.r) 956 testDiv("Div symmetric", Div, a.hi, a.lo+a.r, a.x, a.y, a.r) 957 // The above code can't test intrinsic implementation, because the passed function is not called directly. 958 // The following code uses a closure to test the intrinsic version in case the function is intrinsified. 959 testMul("Mul intrinsic", func(x, y uint) (uint, uint) { return Mul(x, y) }, a.x, a.y, a.hi, a.lo) 960 testMul("Mul intrinsic symmetric", func(x, y uint) (uint, uint) { return Mul(x, y) }, a.y, a.x, a.hi, a.lo) 961 testDiv("Div intrinsic", func(hi, lo, y uint) (uint, uint) { return Div(hi, lo, y) }, a.hi, a.lo+a.r, a.y, a.x, a.r) 962 testDiv("Div intrinsic symmetric", func(hi, lo, y uint) (uint, uint) { return Div(hi, lo, y) }, a.hi, a.lo+a.r, a.x, a.y, a.r) 963 } 964 } 965 966 func TestMulDiv32(t *testing.T) { 967 testMul := func(msg string, f func(x, y uint32) (hi, lo uint32), x, y, hi, lo uint32) { 968 hi1, lo1 := f(x, y) 969 if hi1 != hi || lo1 != lo { 970 t.Errorf("%s: got hi:lo = %#x:%#x; want %#x:%#x", msg, hi1, lo1, hi, lo) 971 } 972 } 973 testDiv := func(msg string, f func(hi, lo, y uint32) (q, r uint32), hi, lo, y, q, r uint32) { 974 q1, r1 := f(hi, lo, y) 975 if q1 != q || r1 != r { 976 t.Errorf("%s: got q:r = %#x:%#x; want %#x:%#x", msg, q1, r1, q, r) 977 } 978 } 979 for _, a := range []struct { 980 x, y uint32 981 hi, lo, r uint32 982 }{ 983 {1 << 31, 2, 1, 0, 1}, 984 {0xc47dfa8c, 50911, 0x98a4, 0x998587f4, 13}, 985 {_M32, _M32, _M32 - 1, 1, 42}, 986 } { 987 testMul("Mul32", Mul32, a.x, a.y, a.hi, a.lo) 988 testMul("Mul32 symmetric", Mul32, a.y, a.x, a.hi, a.lo) 989 testDiv("Div32", Div32, a.hi, a.lo+a.r, a.y, a.x, a.r) 990 testDiv("Div32 symmetric", Div32, a.hi, a.lo+a.r, a.x, a.y, a.r) 991 } 992 } 993 994 func TestMulDiv64(t *testing.T) { 995 testMul := func(msg string, f func(x, y uint64) (hi, lo uint64), x, y, hi, lo uint64) { 996 hi1, lo1 := f(x, y) 997 if hi1 != hi || lo1 != lo { 998 t.Errorf("%s: got hi:lo = %#x:%#x; want %#x:%#x", msg, hi1, lo1, hi, lo) 999 } 1000 } 1001 testDiv := func(msg string, f func(hi, lo, y uint64) (q, r uint64), hi, lo, y, q, r uint64) { 1002 q1, r1 := f(hi, lo, y) 1003 if q1 != q || r1 != r { 1004 t.Errorf("%s: got q:r = %#x:%#x; want %#x:%#x", msg, q1, r1, q, r) 1005 } 1006 } 1007 for _, a := range []struct { 1008 x, y uint64 1009 hi, lo, r uint64 1010 }{ 1011 {1 << 63, 2, 1, 0, 1}, 1012 {0x3626229738a3b9, 0xd8988a9f1cc4a61, 0x2dd0712657fe8, 0x9dd6a3364c358319, 13}, 1013 {_M64, _M64, _M64 - 1, 1, 42}, 1014 } { 1015 testMul("Mul64", Mul64, a.x, a.y, a.hi, a.lo) 1016 testMul("Mul64 symmetric", Mul64, a.y, a.x, a.hi, a.lo) 1017 testDiv("Div64", Div64, a.hi, a.lo+a.r, a.y, a.x, a.r) 1018 testDiv("Div64 symmetric", Div64, a.hi, a.lo+a.r, a.x, a.y, a.r) 1019 // The above code can't test intrinsic implementation, because the passed function is not called directly. 1020 // The following code uses a closure to test the intrinsic version in case the function is intrinsified. 1021 testMul("Mul64 intrinsic", func(x, y uint64) (uint64, uint64) { return Mul64(x, y) }, a.x, a.y, a.hi, a.lo) 1022 testMul("Mul64 intrinsic symmetric", func(x, y uint64) (uint64, uint64) { return Mul64(x, y) }, a.y, a.x, a.hi, a.lo) 1023 testDiv("Div64 intrinsic", func(hi, lo, y uint64) (uint64, uint64) { return Div64(hi, lo, y) }, a.hi, a.lo+a.r, a.y, a.x, a.r) 1024 testDiv("Div64 intrinsic symmetric", func(hi, lo, y uint64) (uint64, uint64) { return Div64(hi, lo, y) }, a.hi, a.lo+a.r, a.x, a.y, a.r) 1025 } 1026 } 1027 1028 const ( 1029 divZeroError = "runtime error: integer divide by zero" 1030 overflowError = "runtime error: integer overflow" 1031 ) 1032 1033 func TestDivPanicOverflow(t *testing.T) { 1034 // Expect a panic 1035 defer func() { 1036 if err := recover(); err == nil { 1037 t.Error("Div should have panicked when y<=hi") 1038 } else if e, ok := err.(runtime.Error); !ok || e.Error() != overflowError { 1039 t.Errorf("Div expected panic: %q, got: %q ", overflowError, e.Error()) 1040 } 1041 }() 1042 q, r := Div(1, 0, 1) 1043 t.Errorf("undefined q, r = %v, %v calculated when Div should have panicked", q, r) 1044 } 1045 1046 func TestDiv32PanicOverflow(t *testing.T) { 1047 // Expect a panic 1048 defer func() { 1049 if err := recover(); err == nil { 1050 t.Error("Div32 should have panicked when y<=hi") 1051 } else if e, ok := err.(runtime.Error); !ok || e.Error() != overflowError { 1052 t.Errorf("Div32 expected panic: %q, got: %q ", overflowError, e.Error()) 1053 } 1054 }() 1055 q, r := Div32(1, 0, 1) 1056 t.Errorf("undefined q, r = %v, %v calculated when Div32 should have panicked", q, r) 1057 } 1058 1059 func TestDiv64PanicOverflow(t *testing.T) { 1060 // Expect a panic 1061 defer func() { 1062 if err := recover(); err == nil { 1063 t.Error("Div64 should have panicked when y<=hi") 1064 } else if e, ok := err.(runtime.Error); !ok || e.Error() != overflowError { 1065 t.Errorf("Div64 expected panic: %q, got: %q ", overflowError, e.Error()) 1066 } 1067 }() 1068 q, r := Div64(1, 0, 1) 1069 t.Errorf("undefined q, r = %v, %v calculated when Div64 should have panicked", q, r) 1070 } 1071 1072 func TestDivPanicZero(t *testing.T) { 1073 // Expect a panic 1074 defer func() { 1075 if err := recover(); err == nil { 1076 t.Error("Div should have panicked when y==0") 1077 } else if e, ok := err.(runtime.Error); !ok || e.Error() != divZeroError { 1078 t.Errorf("Div expected panic: %q, got: %q ", divZeroError, e.Error()) 1079 } 1080 }() 1081 q, r := Div(1, 1, 0) 1082 t.Errorf("undefined q, r = %v, %v calculated when Div should have panicked", q, r) 1083 } 1084 1085 func TestDiv32PanicZero(t *testing.T) { 1086 // Expect a panic 1087 defer func() { 1088 if err := recover(); err == nil { 1089 t.Error("Div32 should have panicked when y==0") 1090 } else if e, ok := err.(runtime.Error); !ok || e.Error() != divZeroError { 1091 t.Errorf("Div32 expected panic: %q, got: %q ", divZeroError, e.Error()) 1092 } 1093 }() 1094 q, r := Div32(1, 1, 0) 1095 t.Errorf("undefined q, r = %v, %v calculated when Div32 should have panicked", q, r) 1096 } 1097 1098 func TestDiv64PanicZero(t *testing.T) { 1099 // Expect a panic 1100 defer func() { 1101 if err := recover(); err == nil { 1102 t.Error("Div64 should have panicked when y==0") 1103 } else if e, ok := err.(runtime.Error); !ok || e.Error() != divZeroError { 1104 t.Errorf("Div64 expected panic: %q, got: %q ", divZeroError, e.Error()) 1105 } 1106 }() 1107 q, r := Div64(1, 1, 0) 1108 t.Errorf("undefined q, r = %v, %v calculated when Div64 should have panicked", q, r) 1109 } 1110 1111 func TestRem32(t *testing.T) { 1112 // Sanity check: for non-oveflowing dividends, the result is the 1113 // same as the rem returned by Div32 1114 hi, lo, y := uint32(510510), uint32(9699690), uint32(510510+1) // ensure hi < y 1115 for i := 0; i < 1000; i++ { 1116 r := Rem32(hi, lo, y) 1117 _, r2 := Div32(hi, lo, y) 1118 if r != r2 { 1119 t.Errorf("Rem32(%v, %v, %v) returned %v, but Div32 returned rem %v", hi, lo, y, r, r2) 1120 } 1121 y += 13 1122 } 1123 } 1124 1125 func TestRem32Overflow(t *testing.T) { 1126 // To trigger a quotient overflow, we need y <= hi 1127 hi, lo, y := uint32(510510), uint32(9699690), uint32(7) 1128 for i := 0; i < 1000; i++ { 1129 r := Rem32(hi, lo, y) 1130 _, r2 := Div64(0, uint64(hi)<<32|uint64(lo), uint64(y)) 1131 if r != uint32(r2) { 1132 t.Errorf("Rem32(%v, %v, %v) returned %v, but Div64 returned rem %v", hi, lo, y, r, r2) 1133 } 1134 y += 13 1135 } 1136 } 1137 1138 func TestRem64(t *testing.T) { 1139 // Sanity check: for non-oveflowing dividends, the result is the 1140 // same as the rem returned by Div64 1141 hi, lo, y := uint64(510510), uint64(9699690), uint64(510510+1) // ensure hi < y 1142 for i := 0; i < 1000; i++ { 1143 r := Rem64(hi, lo, y) 1144 _, r2 := Div64(hi, lo, y) 1145 if r != r2 { 1146 t.Errorf("Rem64(%v, %v, %v) returned %v, but Div64 returned rem %v", hi, lo, y, r, r2) 1147 } 1148 y += 13 1149 } 1150 } 1151 1152 func TestRem64Overflow(t *testing.T) { 1153 Rem64Tests := []struct { 1154 hi, lo, y uint64 1155 rem uint64 1156 }{ 1157 // Testcases computed using Python 3, as: 1158 // >>> hi = 42; lo = 1119; y = 42 1159 // >>> ((hi<<64)+lo) % y 1160 {42, 1119, 42, 27}, 1161 {42, 1119, 38, 9}, 1162 {42, 1119, 26, 23}, 1163 {469, 0, 467, 271}, 1164 {469, 0, 113, 58}, 1165 {111111, 111111, 1171, 803}, 1166 {3968194946088682615, 3192705705065114702, 1000037, 56067}, 1167 } 1168 1169 for _, rt := range Rem64Tests { 1170 if rt.hi < rt.y { 1171 t.Fatalf("Rem64(%v, %v, %v) is not a test with quo overflow", rt.hi, rt.lo, rt.y) 1172 } 1173 rem := Rem64(rt.hi, rt.lo, rt.y) 1174 if rem != rt.rem { 1175 t.Errorf("Rem64(%v, %v, %v) returned %v, wanted %v", 1176 rt.hi, rt.lo, rt.y, rem, rt.rem) 1177 } 1178 } 1179 } 1180 1181 func BenchmarkAdd(b *testing.B) { 1182 var z, c uint 1183 for i := 0; i < b.N; i++ { 1184 z, c = Add(uint(Input), uint(i), c) 1185 } 1186 Output = int(z + c) 1187 } 1188 1189 func BenchmarkAdd32(b *testing.B) { 1190 var z, c uint32 1191 for i := 0; i < b.N; i++ { 1192 z, c = Add32(uint32(Input), uint32(i), c) 1193 } 1194 Output = int(z + c) 1195 } 1196 1197 func BenchmarkAdd64(b *testing.B) { 1198 var z, c uint64 1199 for i := 0; i < b.N; i++ { 1200 z, c = Add64(uint64(Input), uint64(i), c) 1201 } 1202 Output = int(z + c) 1203 } 1204 1205 func BenchmarkAdd64multiple(b *testing.B) { 1206 var z0 = uint64(Input) 1207 var z1 = uint64(Input) 1208 var z2 = uint64(Input) 1209 var z3 = uint64(Input) 1210 for i := 0; i < b.N; i++ { 1211 var c uint64 1212 z0, c = Add64(z0, uint64(i), c) 1213 z1, c = Add64(z1, uint64(i), c) 1214 z2, c = Add64(z2, uint64(i), c) 1215 z3, _ = Add64(z3, uint64(i), c) 1216 } 1217 Output = int(z0 + z1 + z2 + z3) 1218 } 1219 1220 func BenchmarkSub(b *testing.B) { 1221 var z, c uint 1222 for i := 0; i < b.N; i++ { 1223 z, c = Sub(uint(Input), uint(i), c) 1224 } 1225 Output = int(z + c) 1226 } 1227 1228 func BenchmarkSub32(b *testing.B) { 1229 var z, c uint32 1230 for i := 0; i < b.N; i++ { 1231 z, c = Sub32(uint32(Input), uint32(i), c) 1232 } 1233 Output = int(z + c) 1234 } 1235 1236 func BenchmarkSub64(b *testing.B) { 1237 var z, c uint64 1238 for i := 0; i < b.N; i++ { 1239 z, c = Sub64(uint64(Input), uint64(i), c) 1240 } 1241 Output = int(z + c) 1242 } 1243 1244 func BenchmarkSub64multiple(b *testing.B) { 1245 var z0 = uint64(Input) 1246 var z1 = uint64(Input) 1247 var z2 = uint64(Input) 1248 var z3 = uint64(Input) 1249 for i := 0; i < b.N; i++ { 1250 var c uint64 1251 z0, c = Sub64(z0, uint64(i), c) 1252 z1, c = Sub64(z1, uint64(i), c) 1253 z2, c = Sub64(z2, uint64(i), c) 1254 z3, _ = Sub64(z3, uint64(i), c) 1255 } 1256 Output = int(z0 + z1 + z2 + z3) 1257 } 1258 1259 func BenchmarkMul(b *testing.B) { 1260 var hi, lo uint 1261 for i := 0; i < b.N; i++ { 1262 hi, lo = Mul(uint(Input), uint(i)) 1263 } 1264 Output = int(hi + lo) 1265 } 1266 1267 func BenchmarkMul32(b *testing.B) { 1268 var hi, lo uint32 1269 for i := 0; i < b.N; i++ { 1270 hi, lo = Mul32(uint32(Input), uint32(i)) 1271 } 1272 Output = int(hi + lo) 1273 } 1274 1275 func BenchmarkMul64(b *testing.B) { 1276 var hi, lo uint64 1277 for i := 0; i < b.N; i++ { 1278 hi, lo = Mul64(uint64(Input), uint64(i)) 1279 } 1280 Output = int(hi + lo) 1281 } 1282 1283 func BenchmarkDiv(b *testing.B) { 1284 var q, r uint 1285 for i := 0; i < b.N; i++ { 1286 q, r = Div(1, uint(i), uint(Input)) 1287 } 1288 Output = int(q + r) 1289 } 1290 1291 func BenchmarkDiv32(b *testing.B) { 1292 var q, r uint32 1293 for i := 0; i < b.N; i++ { 1294 q, r = Div32(1, uint32(i), uint32(Input)) 1295 } 1296 Output = int(q + r) 1297 } 1298 1299 func BenchmarkDiv64(b *testing.B) { 1300 var q, r uint64 1301 for i := 0; i < b.N; i++ { 1302 q, r = Div64(1, uint64(i), uint64(Input)) 1303 } 1304 Output = int(q + r) 1305 } 1306 1307 // ---------------------------------------------------------------------------- 1308 // Testing support 1309 1310 type entry = struct { 1311 nlz, ntz, pop int 1312 } 1313 1314 // tab contains results for all uint8 values 1315 var tab [256]entry 1316 1317 func init() { 1318 tab[0] = entry{8, 8, 0} 1319 for i := 1; i < len(tab); i++ { 1320 // nlz 1321 x := i // x != 0 1322 n := 0 1323 for x&0x80 == 0 { 1324 n++ 1325 x <<= 1 1326 } 1327 tab[i].nlz = n 1328 1329 // ntz 1330 x = i // x != 0 1331 n = 0 1332 for x&1 == 0 { 1333 n++ 1334 x >>= 1 1335 } 1336 tab[i].ntz = n 1337 1338 // pop 1339 x = i // x != 0 1340 n = 0 1341 for x != 0 { 1342 n += int(x & 1) 1343 x >>= 1 1344 } 1345 tab[i].pop = n 1346 } 1347 }