1 /* 128 bit integer arithmetic. 2 * 3 * Not optimized for speed. 4 * 5 * Copyright: Copyright D Language Foundation 2022. 6 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 7 * Authors: Walter Bright 8 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/common/int128.d, root/_int128.d) 9 * Documentation: https://dlang.org/phobos/dmd_common_int128.html 10 * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/common/int128.d 11 */ 12 13 module dmd.common.int128; 14 15 nothrow: 16 @safe: 17 @nogc: 18 19 alias I = long; 20 alias U = ulong; 21 enum Ubits = uint(U.sizeof * 8); 22 23 align(16) struct Cent 24 { 25 U lo; // low 64 bits 26 U hi; // high 64 bits 27 } 28 29 enum One = Cent(1); 30 enum Zero = Cent(); 31 enum MinusOne = neg(One); 32 33 /***************************** 34 * Test against 0 35 * Params: 36 * c = Cent to test 37 * Returns: 38 * true if != 0 39 */ 40 pure 41 bool tst(Cent c) 42 { 43 return c.hi || c.lo; 44 } 45 46 47 /***************************** 48 * Complement 49 * Params: 50 * c = Cent to complement 51 * Returns: 52 * complemented value 53 */ 54 pure 55 Cent com(Cent c) 56 { 57 c.lo = ~c.lo; 58 c.hi = ~c.hi; 59 return c; 60 } 61 62 /***************************** 63 * Negate 64 * Params: 65 * c = Cent to negate 66 * Returns: 67 * negated value 68 */ 69 pure 70 Cent neg(Cent c) 71 { 72 if (c.lo == 0) 73 c.hi = -c.hi; 74 else 75 { 76 c.lo = -c.lo; 77 c.hi = ~c.hi; 78 } 79 return c; 80 } 81 82 /***************************** 83 * Increment 84 * Params: 85 * c = Cent to increment 86 * Returns: 87 * incremented value 88 */ 89 pure 90 Cent inc(Cent c) 91 { 92 return add(c, One); 93 } 94 95 /***************************** 96 * Decrement 97 * Params: 98 * c = Cent to decrement 99 * Returns: 100 * incremented value 101 */ 102 pure 103 Cent dec(Cent c) 104 { 105 return sub(c, One); 106 } 107 108 /***************************** 109 * Shift left one bit 110 * Params: 111 * c = Cent to shift 112 * Returns: 113 * shifted value 114 */ 115 pure 116 Cent shl1(Cent c) 117 { 118 c.hi = (c.hi << 1) | (cast(I)c.lo < 0); 119 c.lo <<= 1; 120 return c; 121 } 122 123 /***************************** 124 * Unsigned shift right one bit 125 * Params: 126 * c = Cent to shift 127 * Returns: 128 * shifted value 129 */ 130 pure 131 Cent shr1(Cent c) 132 { 133 c.lo = (c.lo >> 1) | ((c.hi & 1) << (Ubits - 1)); 134 c.hi >>= 1; 135 return c; 136 } 137 138 139 /***************************** 140 * Arithmetic shift right one bit 141 * Params: 142 * c = Cent to shift 143 * Returns: 144 * shifted value 145 */ 146 pure 147 Cent sar1(Cent c) 148 { 149 c.lo = (c.lo >> 1) | ((c.hi & 1) << (Ubits - 1)); 150 c.hi = cast(I)c.hi >> 1; 151 return c; 152 } 153 154 /***************************** 155 * Shift left n bits 156 * Params: 157 * c = Cent to shift 158 * n = number of bits to shift 159 * Returns: 160 * shifted value 161 */ 162 pure 163 Cent shl(Cent c, uint n) 164 { 165 if (n >= Ubits * 2) 166 return Zero; 167 168 if (n >= Ubits) 169 { 170 c.hi = c.lo << (n - Ubits); 171 c.lo = 0; 172 } 173 else 174 { 175 c.hi = ((c.hi << n) | (c.lo >> (Ubits - n - 1) >> 1)); 176 c.lo = c.lo << n; 177 } 178 return c; 179 } 180 181 /***************************** 182 * Unsigned shift right n bits 183 * Params: 184 * c = Cent to shift 185 * n = number of bits to shift 186 * Returns: 187 * shifted value 188 */ 189 pure 190 Cent shr(Cent c, uint n) 191 { 192 if (n >= Ubits * 2) 193 return Zero; 194 195 if (n >= Ubits) 196 { 197 c.lo = c.hi >> (n - Ubits); 198 c.hi = 0; 199 } 200 else 201 { 202 c.lo = ((c.lo >> n) | (c.hi << (Ubits - n - 1) << 1)); 203 c.hi = c.hi >> n; 204 } 205 return c; 206 } 207 208 /***************************** 209 * Arithmetic shift right n bits 210 * Params: 211 * c = Cent to shift 212 * n = number of bits to shift 213 * Returns: 214 * shifted value 215 */ 216 pure 217 Cent sar(Cent c, uint n) 218 { 219 const signmask = -(c.hi >> (Ubits - 1)); 220 const signshift = (Ubits * 2) - n; 221 c = shr(c, n); 222 223 // Sign extend all bits beyond the precision of Cent. 224 if (n >= Ubits * 2) 225 { 226 c.hi = signmask; 227 c.lo = signmask; 228 } 229 else if (signshift >= Ubits * 2) 230 { 231 } 232 else if (signshift >= Ubits) 233 { 234 c.hi &= ~(U.max << (signshift - Ubits)); 235 c.hi |= signmask << (signshift - Ubits); 236 } 237 else 238 { 239 c.hi = signmask; 240 c.lo &= ~(U.max << signshift); 241 c.lo |= signmask << signshift; 242 } 243 return c; 244 } 245 246 /***************************** 247 * Rotate left one bit 248 * Params: 249 * c = Cent to rotate 250 * Returns: 251 * rotated value 252 */ 253 pure 254 Cent rol1(Cent c) 255 { 256 int carry = cast(I)c.hi < 0; 257 258 c.hi = (c.hi << 1) | (cast(I)c.lo < 0); 259 c.lo = (c.lo << 1) | carry; 260 return c; 261 } 262 263 /***************************** 264 * Rotate right one bit 265 * Params: 266 * c = Cent to rotate 267 * Returns: 268 * rotated value 269 */ 270 pure 271 Cent ror1(Cent c) 272 { 273 int carry = c.lo & 1; 274 c.lo = (c.lo >> 1) | (cast(U)(c.hi & 1) << (Ubits - 1)); 275 c.hi = (c.hi >> 1) | (cast(U)carry << (Ubits - 1)); 276 return c; 277 } 278 279 280 /***************************** 281 * Rotate left n bits 282 * Params: 283 * c = Cent to rotate 284 * n = number of bits to rotate 285 * Returns: 286 * rotated value 287 */ 288 pure 289 Cent rol(Cent c, uint n) 290 { 291 n &= Ubits * 2 - 1; 292 Cent l = shl(c, n); 293 Cent r = shr(c, Ubits * 2 - n); 294 return or(l, r); 295 } 296 297 /***************************** 298 * Rotate right n bits 299 * Params: 300 * c = Cent to rotate 301 * n = number of bits to rotate 302 * Returns: 303 * rotated value 304 */ 305 pure 306 Cent ror(Cent c, uint n) 307 { 308 n &= Ubits * 2 - 1; 309 Cent r = shr(c, n); 310 Cent l = shl(c, Ubits * 2 - n); 311 return or(r, l); 312 } 313 314 /**************************** 315 * And c1 & c2. 316 * Params: 317 * c1 = operand 1 318 * c2 = operand 2 319 * Returns: 320 * c1 & c2 321 */ 322 pure 323 Cent and(Cent c1, Cent c2) 324 { 325 return Cent(c1.lo & c2.lo, c1.hi & c2.hi); 326 } 327 328 /**************************** 329 * Or c1 | c2. 330 * Params: 331 * c1 = operand 1 332 * c2 = operand 2 333 * Returns: 334 * c1 | c2 335 */ 336 pure 337 Cent or(Cent c1, Cent c2) 338 { 339 return Cent(c1.lo | c2.lo, c1.hi | c2.hi); 340 } 341 342 /**************************** 343 * Xor c1 ^ c2. 344 * Params: 345 * c1 = operand 1 346 * c2 = operand 2 347 * Returns: 348 * c1 ^ c2 349 */ 350 pure 351 Cent xor(Cent c1, Cent c2) 352 { 353 return Cent(c1.lo ^ c2.lo, c1.hi ^ c2.hi); 354 } 355 356 /**************************** 357 * Add c1 to c2. 358 * Params: 359 * c1 = operand 1 360 * c2 = operand 2 361 * Returns: 362 * c1 + c2 363 */ 364 pure 365 Cent add(Cent c1, Cent c2) 366 { 367 U r = cast(U)(c1.lo + c2.lo); 368 return Cent(r, cast(U)(c1.hi + c2.hi + (r < c1.lo))); 369 } 370 371 /**************************** 372 * Subtract c2 from c1. 373 * Params: 374 * c1 = operand 1 375 * c2 = operand 2 376 * Returns: 377 * c1 - c2 378 */ 379 pure 380 Cent sub(Cent c1, Cent c2) 381 { 382 return add(c1, neg(c2)); 383 } 384 385 /**************************** 386 * Multiply c1 * c2. 387 * Params: 388 * c1 = operand 1 389 * c2 = operand 2 390 * Returns: 391 * c1 * c2 392 */ 393 pure 394 Cent mul(Cent c1, Cent c2) 395 { 396 enum mulmask = (1UL << (Ubits / 2)) - 1; 397 enum mulshift = Ubits / 2; 398 399 // This algorithm splits the operands into 4 words, then computes and sums 400 // the partial products of each part. 401 const c2l0 = c2.lo & mulmask; 402 const c2l1 = c2.lo >> mulshift; 403 const c2h0 = c2.hi & mulmask; 404 const c2h1 = c2.hi >> mulshift; 405 406 const c1l0 = c1.lo & mulmask; 407 U r0 = c1l0 * c2l0; 408 U r1 = c1l0 * c2l1 + (r0 >> mulshift); 409 U r2 = c1l0 * c2h0 + (r1 >> mulshift); 410 U r3 = c1l0 * c2h1 + (r2 >> mulshift); 411 412 const c1l1 = c1.lo >> mulshift; 413 r1 = c1l1 * c2l0 + (r1 & mulmask); 414 r2 = c1l1 * c2l1 + (r2 & mulmask) + (r1 >> mulshift); 415 r3 = c1l1 * c2h0 + (r3 & mulmask) + (r2 >> mulshift); 416 417 const c1h0 = c1.hi & mulmask; 418 r2 = c1h0 * c2l0 + (r2 & mulmask); 419 r3 = c1h0 * c2l1 + (r3 & mulmask) + (r2 >> mulshift); 420 421 const c1h1 = c1.hi >> mulshift; 422 r3 = c1h1 * c2l0 + (r3 & mulmask); 423 424 return Cent((r0 & mulmask) + (r1 & mulmask) * (mulmask + 1), 425 (r2 & mulmask) + (r3 & mulmask) * (mulmask + 1)); 426 427 } 428 429 430 /**************************** 431 * Unsigned divide c1 / c2. 432 * Params: 433 * c1 = dividend 434 * c2 = divisor 435 * Returns: 436 * quotient c1 / c2 437 */ 438 pure 439 Cent udiv(Cent c1, Cent c2) 440 { 441 Cent modulus; 442 return udivmod(c1, c2, modulus); 443 } 444 445 /**************************** 446 * Unsigned divide c1 / c2. The remainder after division is stored to modulus. 447 * Params: 448 * c1 = dividend 449 * c2 = divisor 450 * modulus = set to c1 % c2 451 * Returns: 452 * quotient c1 / c2 453 */ 454 pure 455 Cent udivmod(Cent c1, Cent c2, out Cent modulus) 456 { 457 //printf("udiv c1(%llx,%llx) c2(%llx,%llx)\n", c1.lo, c1.hi, c2.lo, c2.hi); 458 // Based on "Unsigned Doubleword Division" in Hacker's Delight 459 import core.bitop; 460 461 // Divides a 128-bit dividend by a 64-bit divisor. 462 // The result must fit in 64 bits. 463 static U udivmod128_64(Cent c1, U c2, out U modulus) 464 { 465 // We work in base 2^^32 466 enum base = 1UL << 32; 467 enum divmask = (1UL << (Ubits / 2)) - 1; 468 enum divshift = Ubits / 2; 469 470 // Check for overflow and divide by 0 471 if (c1.hi >= c2) 472 { 473 modulus = 0UL; 474 return ~0UL; 475 } 476 477 // Computes [num1 num0] / den 478 static uint udiv96_64(U num1, uint num0, U den) 479 { 480 // Extract both digits of the denominator 481 const den1 = cast(uint)(den >> divshift); 482 const den0 = cast(uint)(den & divmask); 483 // Estimate ret as num1 / den1, and then correct it 484 U ret = num1 / den1; 485 const t2 = (num1 % den1) * base + num0; 486 const t1 = ret * den0; 487 if (t1 > t2) 488 ret -= (t1 - t2 > den) ? 2 : 1; 489 return cast(uint)ret; 490 } 491 492 // Determine the normalization factor. We multiply c2 by this, so that its leading 493 // digit is at least half base. In binary this means just shifting left by the number 494 // of leading zeros, so that there's a 1 in the MSB. 495 // We also shift number by the same amount. This cannot overflow because c1.hi < c2. 496 const shift = (Ubits - 1) - bsr(c2); 497 c2 <<= shift; 498 U num2 = c1.hi; 499 num2 <<= shift; 500 num2 |= (c1.lo >> (-shift & 63)) & (-cast(I)shift >> 63); 501 c1.lo <<= shift; 502 503 // Extract the low digits of the numerator (after normalizing) 504 const num1 = cast(uint)(c1.lo >> divshift); 505 const num0 = cast(uint)(c1.lo & divmask); 506 507 // Compute q1 = [num2 num1] / c2 508 const q1 = udiv96_64(num2, num1, c2); 509 // Compute the true (partial) remainder 510 const rem = num2 * base + num1 - q1 * c2; 511 // Compute q0 = [rem num0] / c2 512 const q0 = udiv96_64(rem, num0, c2); 513 514 modulus = (rem * base + num0 - q0 * c2) >> shift; 515 return (cast(U)q1 << divshift) | q0; 516 } 517 518 // Special cases 519 if (!tst(c2)) 520 { 521 // Divide by zero 522 modulus = Zero; 523 return com(modulus); 524 } 525 if (c1.hi == 0 && c2.hi == 0) 526 { 527 // Single precision divide 528 modulus = Cent(c1.lo % c2.lo); 529 return Cent(c1.lo / c2.lo); 530 } 531 if (c1.hi == 0) 532 { 533 // Numerator is smaller than the divisor 534 modulus = c1; 535 return Zero; 536 } 537 if (c2.hi == 0) 538 { 539 // Divisor is a 64-bit value, so we just need one 128/64 division. 540 // If c1 / c2 would overflow, break c1 up into two halves. 541 const q1 = (c1.hi < c2.lo) ? 0 : (c1.hi / c2.lo); 542 if (q1) 543 c1.hi = c1.hi % c2.lo; 544 U rem; 545 const q0 = udivmod128_64(c1, c2.lo, rem); 546 modulus = Cent(rem); 547 return Cent(q0, q1); 548 } 549 550 // Full cent precision division. 551 // Here c2 >= 2^^64 552 // We know that c2.hi != 0, so count leading zeros is OK 553 // We have 0 <= shift <= 63 554 const shift = (Ubits - 1) - bsr(c2.hi); 555 556 // Normalize the divisor so its MSB is 1 557 // v1 = (c2 << shift) >> 64 558 U v1 = shl(c2, shift).hi; 559 560 // To ensure no overflow. 561 Cent u1 = shr1(c1); 562 563 // Get quotient from divide unsigned operation. 564 U rem_ignored; 565 const q1 = udivmod128_64(u1, v1, rem_ignored); 566 567 // Undo normalization and division of c1 by 2. 568 Cent quotient = shr(shl(Cent(q1), shift), 63); 569 570 // Make quotient correct or too small by 1 571 if (tst(quotient)) 572 quotient = dec(quotient); 573 574 // Now quotient is correct. 575 // Compute rem = c1 - (quotient * c2); 576 Cent rem = sub(c1, mul(quotient, c2)); 577 578 // Check if remainder is larger than the divisor 579 if (uge(rem, c2)) 580 { 581 // Increment quotient 582 quotient = inc(quotient); 583 // Subtract c2 from remainder 584 rem = sub(rem, c2); 585 } 586 modulus = rem; 587 //printf("quotient "); print(quotient); 588 //printf("modulus "); print(modulus); 589 return quotient; 590 } 591 592 593 /**************************** 594 * Signed divide c1 / c2. 595 * Params: 596 * c1 = dividend 597 * c2 = divisor 598 * Returns: 599 * quotient c1 / c2 600 */ 601 pure 602 Cent div(Cent c1, Cent c2) 603 { 604 Cent modulus; 605 return divmod(c1, c2, modulus); 606 } 607 608 /**************************** 609 * Signed divide c1 / c2. The remainder after division is stored to modulus. 610 * Params: 611 * c1 = dividend 612 * c2 = divisor 613 * modulus = set to c1 % c2 614 * Returns: 615 * quotient c1 / c2 616 */ 617 pure 618 Cent divmod(Cent c1, Cent c2, out Cent modulus) 619 { 620 /* Muck about with the signs so we can use the unsigned divide 621 */ 622 if (cast(I)c1.hi < 0) 623 { 624 if (cast(I)c2.hi < 0) 625 { 626 Cent r = udivmod(neg(c1), neg(c2), modulus); 627 modulus = neg(modulus); 628 return r; 629 } 630 Cent r = neg(udivmod(neg(c1), c2, modulus)); 631 modulus = neg(modulus); 632 return r; 633 } 634 else if (cast(I)c2.hi < 0) 635 { 636 return neg(udivmod(c1, neg(c2), modulus)); 637 } 638 else 639 return udivmod(c1, c2, modulus); 640 } 641 642 /**************************** 643 * If c1 > c2 unsigned 644 * Params: 645 * c1 = operand 1 646 * c2 = operand 2 647 * Returns: 648 * true if c1 > c2 649 */ 650 pure 651 bool ugt(Cent c1, Cent c2) 652 { 653 return (c1.hi == c2.hi) ? (c1.lo > c2.lo) : (c1.hi > c2.hi); 654 } 655 656 /**************************** 657 * If c1 >= c2 unsigned 658 * Params: 659 * c1 = operand 1 660 * c2 = operand 2 661 * Returns: 662 * true if c1 >= c2 663 */ 664 pure 665 bool uge(Cent c1, Cent c2) 666 { 667 return !ugt(c2, c1); 668 } 669 670 /**************************** 671 * If c1 < c2 unsigned 672 * Params: 673 * c1 = operand 1 674 * c2 = operand 2 675 * Returns: 676 * true if c1 < c2 677 */ 678 pure 679 bool ult(Cent c1, Cent c2) 680 { 681 return ugt(c2, c1); 682 } 683 684 /**************************** 685 * If c1 <= c2 unsigned 686 * Params: 687 * c1 = operand 1 688 * c2 = operand 2 689 * Returns: 690 * true if c1 <= c2 691 */ 692 pure 693 bool ule(Cent c1, Cent c2) 694 { 695 return !ugt(c1, c2); 696 } 697 698 /**************************** 699 * If c1 > c2 signed 700 * Params: 701 * c1 = operand 1 702 * c2 = operand 2 703 * Returns: 704 * true if c1 > c2 705 */ 706 pure 707 bool gt(Cent c1, Cent c2) 708 { 709 return (c1.hi == c2.hi) 710 ? (c1.lo > c2.lo) 711 : (cast(I)c1.hi > cast(I)c2.hi); 712 } 713 714 /**************************** 715 * If c1 >= c2 signed 716 * Params: 717 * c1 = operand 1 718 * c2 = operand 2 719 * Returns: 720 * true if c1 >= c2 721 */ 722 pure 723 bool ge(Cent c1, Cent c2) 724 { 725 return !gt(c2, c1); 726 } 727 728 /**************************** 729 * If c1 < c2 signed 730 * Params: 731 * c1 = operand 1 732 * c2 = operand 2 733 * Returns: 734 * true if c1 < c2 735 */ 736 pure 737 bool lt(Cent c1, Cent c2) 738 { 739 return gt(c2, c1); 740 } 741 742 /**************************** 743 * If c1 <= c2 signed 744 * Params: 745 * c1 = operand 1 746 * c2 = operand 2 747 * Returns: 748 * true if c1 <= c2 749 */ 750 pure 751 bool le(Cent c1, Cent c2) 752 { 753 return !gt(c1, c2); 754 } 755 756 /*******************************************************/ 757 758 version (unittest) 759 { 760 version (none) 761 { 762 import core.stdc.stdio; 763 764 @trusted 765 void print(Cent c) 766 { 767 printf("%lld, %lld\n", cast(ulong)c.lo, cast(ulong)c.hi); 768 printf("x%llx, x%llx\n", cast(ulong)c.lo, cast(ulong)c.hi); 769 } 770 } 771 } 772 773 unittest 774 { 775 const C0 = Zero; 776 const C1 = One; 777 const C2 = Cent(2); 778 const C3 = Cent(3); 779 const C5 = Cent(5); 780 const C10 = Cent(10); 781 const C20 = Cent(20); 782 const C30 = Cent(30); 783 const C100 = Cent(100); 784 785 const Cm1 = neg(One); 786 const Cm3 = neg(C3); 787 const Cm10 = neg(C10); 788 789 const C3_1 = Cent(1,3); 790 const C3_2 = Cent(2,3); 791 const C4_8 = Cent(8, 4); 792 const C5_0 = Cent(0, 5); 793 const C7_1 = Cent(1,7); 794 const C7_9 = Cent(9,7); 795 const C9_3 = Cent(3,9); 796 const C10_0 = Cent(0,10); 797 const C10_1 = Cent(1,10); 798 const C10_3 = Cent(3,10); 799 const C11_3 = Cent(3,11); 800 const C20_0 = Cent(0,20); 801 const C90_30 = Cent(30,90); 802 803 const Cm10_0 = inc(com(C10_0)); // Cent(0, -10); 804 const Cm10_1 = inc(com(C10_1)); // Cent(-1, -11); 805 const Cm10_3 = inc(com(C10_3)); // Cent(-3, -11); 806 const Cm20_0 = inc(com(C20_0)); // Cent(0, -20); 807 808 enum Cs_3 = Cent(3, I.min); 809 810 const Cbig_1 = Cent(0xa3ccac1832952398, 0xc3ac542864f652f8); 811 const Cbig_2 = Cent(0x5267b85f8a42fc20, 0); 812 const Cbig_3 = Cent(0xf0000000ffffffff, 0); 813 814 /************************/ 815 816 assert( ugt(C1, C0) ); 817 assert( ult(C1, C2) ); 818 assert( uge(C1, C0) ); 819 assert( ule(C1, C2) ); 820 821 assert( !ugt(C0, C1) ); 822 assert( !ult(C2, C1) ); 823 assert( !uge(C0, C1) ); 824 assert( !ule(C2, C1) ); 825 826 assert( !ugt(C1, C1) ); 827 assert( !ult(C1, C1) ); 828 assert( uge(C1, C1) ); 829 assert( ule(C2, C2) ); 830 831 assert( ugt(C10_3, C10_1) ); 832 assert( ugt(C11_3, C10_3) ); 833 assert( !ugt(C9_3, C10_3) ); 834 assert( !ugt(C9_3, C9_3) ); 835 836 assert( gt(C2, C1) ); 837 assert( !gt(C1, C2) ); 838 assert( !gt(C1, C1) ); 839 assert( gt(C0, Cm1) ); 840 assert( gt(Cm1, neg(C10))); 841 assert( !gt(Cm1, Cm1) ); 842 assert( !gt(Cm1, C0) ); 843 844 assert( !lt(C2, C1) ); 845 assert( !le(C2, C1) ); 846 assert( ge(C2, C1) ); 847 848 assert(neg(C10_0) == Cm10_0); 849 assert(neg(C10_1) == Cm10_1); 850 assert(neg(C10_3) == Cm10_3); 851 852 assert(add(C7_1,C3_2) == C10_3); 853 assert(sub(C1,C2) == Cm1); 854 855 assert(inc(C3_1) == C3_2); 856 assert(dec(C3_2) == C3_1); 857 858 assert(shl(C10,0) == C10); 859 assert(shl(C10,Ubits) == C10_0); 860 assert(shl(C10,1) == C20); 861 assert(shl(C10,Ubits * 2) == C0); 862 assert(shr(C10_0,0) == C10_0); 863 assert(shr(C10_0,Ubits) == C10); 864 assert(shr(C10_0,Ubits - 1) == C20); 865 assert(shr(C10_0,Ubits + 1) == C5); 866 assert(shr(C10_0,Ubits * 2) == C0); 867 assert(sar(C10_0,0) == C10_0); 868 assert(sar(C10_0,Ubits) == C10); 869 assert(sar(C10_0,Ubits - 1) == C20); 870 assert(sar(C10_0,Ubits + 1) == C5); 871 assert(sar(C10_0,Ubits * 2) == C0); 872 assert(sar(Cm1,Ubits * 2) == Cm1); 873 874 assert(shl1(C10) == C20); 875 assert(shr1(C10_0) == C5_0); 876 assert(sar1(C10_0) == C5_0); 877 assert(sar1(Cm1) == Cm1); 878 879 Cent modulus; 880 881 assert(udiv(C10,C2) == C5); 882 assert(udivmod(C10,C2, modulus) == C5); assert(modulus == C0); 883 assert(udivmod(C10,C3, modulus) == C3); assert(modulus == C1); 884 assert(udivmod(C10,C0, modulus) == Cm1); assert(modulus == C0); 885 assert(udivmod(C2,C90_30, modulus) == C0); assert(modulus == C2); 886 assert(udiv(mul(C90_30, C2), C2) == C90_30); 887 assert(udiv(mul(C90_30, C2), C90_30) == C2); 888 889 assert(div(C10,C3) == C3); 890 assert(divmod( C10, C3, modulus) == C3); assert(modulus == C1); 891 assert(divmod(Cm10, C3, modulus) == Cm3); assert(modulus == Cm1); 892 assert(divmod( C10, Cm3, modulus) == Cm3); assert(modulus == C1); 893 assert(divmod(Cm10, Cm3, modulus) == C3); assert(modulus == Cm1); 894 assert(divmod(C2, C90_30, modulus) == C0); assert(modulus == C2); 895 assert(div(mul(C90_30, C2), C2) == C90_30); 896 assert(div(mul(C90_30, C2), C90_30) == C2); 897 898 assert(divmod(Cbig_1, Cbig_2, modulus) == Cent(0x4496aa309d4d4a2f, U.max)); 899 assert(modulus == Cent(0xd83203d0fdc799b8, U.max)); 900 assert(udivmod(Cbig_1, Cbig_2, modulus) == Cent(0x5fe0e9bace2bedad, 2)); 901 assert(modulus == Cent(0x2c923125a68721f8, 0)); 902 assert(div(Cbig_1, Cbig_3) == Cent(0xbfa6c02b5aff8b86, U.max)); 903 assert(udiv(Cbig_1, Cbig_3) == Cent(0xd0b7d13b48cb350f, 0)); 904 905 assert(mul(Cm10, C1) == Cm10); 906 assert(mul(C1, Cm10) == Cm10); 907 assert(mul(C9_3, C10) == C90_30); 908 assert(mul(Cs_3, C10) == C30); 909 assert(mul(Cm10, Cm10) == C100); 910 assert(mul(C20_0, Cm1) == Cm20_0); 911 912 assert( or(C4_8, C3_1) == C7_9); 913 assert(and(C4_8, C7_9) == C4_8); 914 assert(xor(C4_8, C7_9) == C3_1); 915 916 assert(rol(Cm1, 1) == Cm1); 917 assert(ror(Cm1, 45) == Cm1); 918 assert(rol(ror(C7_9, 5), 5) == C7_9); 919 assert(rol(C7_9, 1) == rol1(C7_9)); 920 assert(ror(C7_9, 1) == ror1(C7_9)); 921 }