| ... | ... | @@ -18,39 +18,6 @@ comptime { |
| 18 | 18 | debug.assert(Limb.is_signed == false); |
| 19 | 19 | } |
| 20 | 20 | |
| 21 | | const wrapped_buffer_size = 512; |
| 22 | | |
| 23 | | // Converts primitive integer values onto a stack-based big integer, or passes through existing |
| 24 | | // Int types with no modifications. This can fail at runtime if using a very large dynamic |
| 25 | | // integer but it is very unlikely and is considered a user error. |
| 26 | | fn wrapInt(allocator: *Allocator, bn: var) *const Int { |
| 27 | | const T = @typeOf(bn); |
| 28 | | switch (@typeInfo(T)) { |
| 29 | | TypeId.Pointer => |info| { |
| 30 | | if (info.child == Int) { |
| 31 | | return bn; |
| 32 | | } else { |
| 33 | | @compileError("cannot set Int using type " ++ @typeName(T)); |
| 34 | | } |
| 35 | | }, |
| 36 | | else => { |
| 37 | | var s = allocator.create(Int) catch unreachable; |
| 38 | | s.* = Int{ |
| 39 | | .allocator = allocator, |
| 40 | | .positive = false, |
| 41 | | .limbs = block: { |
| 42 | | var limbs = allocator.alloc(Limb, Int.default_capacity) catch unreachable; |
| 43 | | limbs[0] = 0; |
| 44 | | break :block limbs; |
| 45 | | }, |
| 46 | | .len = 1, |
| 47 | | }; |
| 48 | | s.set(bn) catch unreachable; |
| 49 | | return s; |
| 50 | | }, |
| 51 | | } |
| 52 | | } |
| 53 | | |
| 54 | 21 | pub const Int = struct { |
| 55 | 22 | allocator: *Allocator, |
| 56 | 23 | positive: bool, |
| ... | ... | @@ -93,11 +60,11 @@ pub const Int = struct { |
| 93 | 60 | self.limbs = try self.allocator.realloc(Limb, self.limbs, capacity); |
| 94 | 61 | } |
| 95 | 62 | |
| 96 | | pub fn deinit(self: *const Int) void { |
| 63 | pub fn deinit(self: Int) void { |
| 97 | 64 | self.allocator.free(self.limbs); |
| 98 | 65 | } |
| 99 | 66 | |
| 100 | | pub fn clone(other: *const Int) !Int { |
| 67 | pub fn clone(other: Int) !Int { |
| 101 | 68 | return Int{ |
| 102 | 69 | .allocator = other.allocator, |
| 103 | 70 | .positive = other.positive, |
| ... | ... | @@ -110,8 +77,8 @@ pub const Int = struct { |
| 110 | 77 | }; |
| 111 | 78 | } |
| 112 | 79 | |
| 113 | | pub fn copy(self: *Int, other: *const Int) !void { |
| 114 | | if (self == other) { |
| 80 | pub fn copy(self: *Int, other: Int) !void { |
| 81 | if (self == &other) { |
| 115 | 82 | return; |
| 116 | 83 | } |
| 117 | 84 | |
| ... | ... | @@ -125,7 +92,7 @@ pub const Int = struct { |
| 125 | 92 | mem.swap(Int, self, other); |
| 126 | 93 | } |
| 127 | 94 | |
| 128 | | pub fn dump(self: *const Int) void { |
| 95 | pub fn dump(self: Int) void { |
| 129 | 96 | for (self.limbs) |limb| { |
| 130 | 97 | debug.warn("{x} ", limb); |
| 131 | 98 | } |
| ... | ... | @@ -140,20 +107,20 @@ pub const Int = struct { |
| 140 | 107 | r.positive = true; |
| 141 | 108 | } |
| 142 | 109 | |
| 143 | | pub fn isOdd(r: *const Int) bool { |
| 110 | pub fn isOdd(r: Int) bool { |
| 144 | 111 | return r.limbs[0] & 1 != 0; |
| 145 | 112 | } |
| 146 | 113 | |
| 147 | | pub fn isEven(r: *const Int) bool { |
| 114 | pub fn isEven(r: Int) bool { |
| 148 | 115 | return !r.isOdd(); |
| 149 | 116 | } |
| 150 | 117 | |
| 151 | | fn bitcount(self: *const Int) usize { |
| 118 | fn bitcount(self: Int) usize { |
| 152 | 119 | const u_bit_count = (self.len - 1) * Limb.bit_count + (Limb.bit_count - @clz(self.limbs[self.len - 1])); |
| 153 | 120 | return usize(!self.positive) + u_bit_count; |
| 154 | 121 | } |
| 155 | 122 | |
| 156 | | pub fn sizeInBase(self: *const Int, base: usize) usize { |
| 123 | pub fn sizeInBase(self: Int, base: usize) usize { |
| 157 | 124 | return (self.bitcount() / math.log2(base)) + 1; |
| 158 | 125 | } |
| 159 | 126 | |
| ... | ... | @@ -219,7 +186,7 @@ pub const Int = struct { |
| 219 | 186 | TargetTooSmall, |
| 220 | 187 | }; |
| 221 | 188 | |
| 222 | | pub fn to(self: *const Int, comptime T: type) ConvertError!T { |
| 189 | pub fn to(self: Int, comptime T: type) ConvertError!T { |
| 223 | 190 | switch (@typeId(T)) { |
| 224 | 191 | TypeId.Int => { |
| 225 | 192 | const UT = if (T.is_signed) @IntType(false, T.bit_count - 1) else T; |
| ... | ... | @@ -286,16 +253,28 @@ pub const Int = struct { |
| 286 | 253 | i += 1; |
| 287 | 254 | } |
| 288 | 255 | |
| 256 | // TODO values less than limb size should guarantee non allocating |
| 257 | var base_buffer: [512]u8 = undefined; |
| 258 | const base_al = &std.heap.FixedBufferAllocator.init(base_buffer[0..]).allocator; |
| 259 | const base_ap = try Int.initSet(base_al, base); |
| 260 | |
| 261 | var d_buffer: [512]u8 = undefined; |
| 262 | var d_fba = std.heap.FixedBufferAllocator.init(d_buffer[0..]); |
| 263 | const d_al = &d_fba.allocator; |
| 264 | |
| 289 | 265 | try self.set(0); |
| 290 | 266 | for (value[i..]) |ch| { |
| 291 | 267 | const d = try charToDigit(ch, base); |
| 292 | | try self.mul(self, base); |
| 293 | | try self.add(self, d); |
| 268 | d_fba.end_index = 0; |
| 269 | const d_ap = try Int.initSet(d_al, d); |
| 270 | |
| 271 | try self.mul(self.*, base_ap); |
| 272 | try self.add(self.*, d_ap); |
| 294 | 273 | } |
| 295 | 274 | self.positive = positive; |
| 296 | 275 | } |
| 297 | 276 | |
| 298 | | pub fn toString(self: *const Int, allocator: *Allocator, base: u8) ![]const u8 { |
| 277 | pub fn toString(self: Int, allocator: *Allocator, base: u8) ![]const u8 { |
| 299 | 278 | if (base < 2 or base > 16) { |
| 300 | 279 | return error.InvalidBase; |
| 301 | 280 | } |
| ... | ... | @@ -345,7 +324,7 @@ pub const Int = struct { |
| 345 | 324 | var b = try Int.initSet(allocator, limb_base); |
| 346 | 325 | |
| 347 | 326 | while (q.len >= 2) { |
| 348 | | try Int.divTrunc(&q, &r, &q, &b); |
| 327 | try Int.divTrunc(&q, &r, q, b); |
| 349 | 328 | |
| 350 | 329 | var r_word = r.limbs[0]; |
| 351 | 330 | var i: usize = 0; |
| ... | ... | @@ -378,12 +357,7 @@ pub const Int = struct { |
| 378 | 357 | } |
| 379 | 358 | |
| 380 | 359 | // returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively. |
| 381 | | pub fn cmpAbs(a: *const Int, bv: var) i8 { |
| 382 | | // TODO: Thread-local buffer. |
| 383 | | var buffer: [wrapped_buffer_size]u8 = undefined; |
| 384 | | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); |
| 385 | | var b = wrapInt(&stack.allocator, bv); |
| 386 | | |
| 360 | pub fn cmpAbs(a: Int, b: Int) i8 { |
| 387 | 361 | if (a.len < b.len) { |
| 388 | 362 | return -1; |
| 389 | 363 | } |
| ... | ... | @@ -408,11 +382,7 @@ pub const Int = struct { |
| 408 | 382 | } |
| 409 | 383 | |
| 410 | 384 | // returns -1, 0, 1 if a < b, a == b or a > b respectively. |
| 411 | | pub fn cmp(a: *const Int, bv: var) i8 { |
| 412 | | var buffer: [wrapped_buffer_size]u8 = undefined; |
| 413 | | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); |
| 414 | | var b = wrapInt(&stack.allocator, bv); |
| 415 | | |
| 385 | pub fn cmp(a: Int, b: Int) i8 { |
| 416 | 386 | if (a.positive != b.positive) { |
| 417 | 387 | return if (a.positive) i8(1) else -1; |
| 418 | 388 | } else { |
| ... | ... | @@ -422,17 +392,17 @@ pub const Int = struct { |
| 422 | 392 | } |
| 423 | 393 | |
| 424 | 394 | // if a == 0 |
| 425 | | pub fn eqZero(a: *const Int) bool { |
| 395 | pub fn eqZero(a: Int) bool { |
| 426 | 396 | return a.len == 1 and a.limbs[0] == 0; |
| 427 | 397 | } |
| 428 | 398 | |
| 429 | 399 | // if |a| == |b| |
| 430 | | pub fn eqAbs(a: *const Int, b: var) bool { |
| 400 | pub fn eqAbs(a: Int, b: Int) bool { |
| 431 | 401 | return cmpAbs(a, b) == 0; |
| 432 | 402 | } |
| 433 | 403 | |
| 434 | 404 | // if a == b |
| 435 | | pub fn eq(a: *const Int, b: var) bool { |
| 405 | pub fn eq(a: Int, b: Int) bool { |
| 436 | 406 | return cmp(a, b) == 0; |
| 437 | 407 | } |
| 438 | 408 | |
| ... | ... | @@ -473,12 +443,7 @@ pub const Int = struct { |
| 473 | 443 | } |
| 474 | 444 | |
| 475 | 445 | // r = a + b |
| 476 | | pub fn add(r: *Int, av: var, bv: var) Allocator.Error!void { |
| 477 | | var buffer: [2 * wrapped_buffer_size]u8 = undefined; |
| 478 | | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); |
| 479 | | var a = wrapInt(&stack.allocator, av); |
| 480 | | var b = wrapInt(&stack.allocator, bv); |
| 481 | | |
| 446 | pub fn add(r: *Int, a: Int, b: Int) Allocator.Error!void { |
| 482 | 447 | if (a.eqZero()) { |
| 483 | 448 | try r.copy(b); |
| 484 | 449 | return; |
| ... | ... | @@ -547,12 +512,7 @@ pub const Int = struct { |
| 547 | 512 | } |
| 548 | 513 | |
| 549 | 514 | // r = a - b |
| 550 | | pub fn sub(r: *Int, av: var, bv: var) !void { |
| 551 | | var buffer: [wrapped_buffer_size]u8 = undefined; |
| 552 | | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); |
| 553 | | var a = wrapInt(&stack.allocator, av); |
| 554 | | var b = wrapInt(&stack.allocator, bv); |
| 555 | | |
| 515 | pub fn sub(r: *Int, a: Int, b: Int) !void { |
| 556 | 516 | if (a.positive != b.positive) { |
| 557 | 517 | if (a.positive) { |
| 558 | 518 | // (a) - (-b) => a + b |
| ... | ... | @@ -632,14 +592,9 @@ pub const Int = struct { |
| 632 | 592 | // rma = a * b |
| 633 | 593 | // |
| 634 | 594 | // For greatest efficiency, ensure rma does not alias a or b. |
| 635 | | pub fn mul(rma: *Int, av: var, bv: var) !void { |
| 636 | | var buffer: [2 * wrapped_buffer_size]u8 = undefined; |
| 637 | | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); |
| 638 | | var a = wrapInt(&stack.allocator, av); |
| 639 | | var b = wrapInt(&stack.allocator, bv); |
| 640 | | |
| 595 | pub fn mul(rma: *Int, a: Int, b: Int) !void { |
| 641 | 596 | var r = rma; |
| 642 | | var aliased = rma == a or rma == b; |
| 597 | var aliased = rma.limbs.ptr == a.limbs.ptr or rma.limbs.ptr == b.limbs.ptr; |
| 643 | 598 | |
| 644 | 599 | var sr: Int = undefined; |
| 645 | 600 | if (aliased) { |
| ... | ... | @@ -714,29 +669,29 @@ pub const Int = struct { |
| 714 | 669 | } |
| 715 | 670 | } |
| 716 | 671 | |
| 717 | | pub fn divFloor(q: *Int, r: *Int, a: var, b: var) !void { |
| 672 | pub fn divFloor(q: *Int, r: *Int, a: Int, b: Int) !void { |
| 718 | 673 | try div(q, r, a, b); |
| 719 | 674 | |
| 720 | 675 | // Trunc -> Floor. |
| 721 | 676 | if (!q.positive) { |
| 722 | | try q.sub(q, 1); |
| 723 | | try r.add(q, 1); |
| 677 | // TODO values less than limb size should guarantee non allocating |
| 678 | var one_buffer: [512]u8 = undefined; |
| 679 | const one_al = &std.heap.FixedBufferAllocator.init(one_buffer[0..]).allocator; |
| 680 | const one_ap = try Int.initSet(one_al, 1); |
| 681 | |
| 682 | try q.sub(q.*, one_ap); |
| 683 | try r.add(q.*, one_ap); |
| 724 | 684 | } |
| 725 | 685 | r.positive = b.positive; |
| 726 | 686 | } |
| 727 | 687 | |
| 728 | | pub fn divTrunc(q: *Int, r: *Int, a: var, b: var) !void { |
| 688 | pub fn divTrunc(q: *Int, r: *Int, a: Int, b: Int) !void { |
| 729 | 689 | try div(q, r, a, b); |
| 730 | 690 | r.positive = a.positive; |
| 731 | 691 | } |
| 732 | 692 | |
| 733 | 693 | // Truncates by default. |
| 734 | | fn div(quo: *Int, rem: *Int, av: var, bv: var) !void { |
| 735 | | var buffer: [2 * wrapped_buffer_size]u8 = undefined; |
| 736 | | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); |
| 737 | | var a = wrapInt(&stack.allocator, av); |
| 738 | | var b = wrapInt(&stack.allocator, bv); |
| 739 | | |
| 694 | fn div(quo: *Int, rem: *Int, a: Int, b: Int) !void { |
| 740 | 695 | if (b.eqZero()) { |
| 741 | 696 | @panic("division by zero"); |
| 742 | 697 | } |
| ... | ... | @@ -821,8 +776,8 @@ pub const Int = struct { |
| 821 | 776 | |
| 822 | 777 | // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set) |
| 823 | 778 | const norm_shift = @clz(y.limbs[y.len - 1]); |
| 824 | | try x.shiftLeft(x, norm_shift); |
| 825 | | try y.shiftLeft(y, norm_shift); |
| 779 | try x.shiftLeft(x.*, norm_shift); |
| 780 | try y.shiftLeft(y.*, norm_shift); |
| 826 | 781 | |
| 827 | 782 | const n = x.len - 1; |
| 828 | 783 | const t = y.len - 1; |
| ... | ... | @@ -832,10 +787,10 @@ pub const Int = struct { |
| 832 | 787 | mem.set(Limb, q.limbs[0..q.len], 0); |
| 833 | 788 | |
| 834 | 789 | // 2. |
| 835 | | try tmp.shiftLeft(y, Limb.bit_count * (n - t)); |
| 836 | | while (x.cmp(&tmp) >= 0) { |
| 790 | try tmp.shiftLeft(y.*, Limb.bit_count * (n - t)); |
| 791 | while (x.cmp(tmp) >= 0) { |
| 837 | 792 | q.limbs[n - t] += 1; |
| 838 | | try x.sub(x, tmp); |
| 793 | try x.sub(x.*, tmp); |
| 839 | 794 | } |
| 840 | 795 | |
| 841 | 796 | // 3. |
| ... | ... | @@ -864,7 +819,7 @@ pub const Int = struct { |
| 864 | 819 | r.limbs[2] = carry; |
| 865 | 820 | r.normN(3); |
| 866 | 821 | |
| 867 | | if (r.cmpAbs(&tmp) <= 0) { |
| 822 | if (r.cmpAbs(tmp) <= 0) { |
| 868 | 823 | break; |
| 869 | 824 | } |
| 870 | 825 | |
| ... | ... | @@ -873,13 +828,13 @@ pub const Int = struct { |
| 873 | 828 | |
| 874 | 829 | // 3.3 |
| 875 | 830 | try tmp.set(q.limbs[i - t - 1]); |
| 876 | | try tmp.mul(&tmp, y); |
| 877 | | try tmp.shiftLeft(&tmp, Limb.bit_count * (i - t - 1)); |
| 878 | | try x.sub(x, &tmp); |
| 831 | try tmp.mul(tmp, y.*); |
| 832 | try tmp.shiftLeft(tmp, Limb.bit_count * (i - t - 1)); |
| 833 | try x.sub(x.*, tmp); |
| 879 | 834 | |
| 880 | 835 | if (!x.positive) { |
| 881 | | try tmp.shiftLeft(y, Limb.bit_count * (i - t - 1)); |
| 882 | | try x.add(x, &tmp); |
| 836 | try tmp.shiftLeft(y.*, Limb.bit_count * (i - t - 1)); |
| 837 | try x.add(x.*, tmp); |
| 883 | 838 | q.limbs[i - t - 1] -= 1; |
| 884 | 839 | } |
| 885 | 840 | } |
| ... | ... | @@ -887,16 +842,12 @@ pub const Int = struct { |
| 887 | 842 | // Denormalize |
| 888 | 843 | q.normN(q.len); |
| 889 | 844 | |
| 890 | | try r.shiftRight(x, norm_shift); |
| 845 | try r.shiftRight(x.*, norm_shift); |
| 891 | 846 | r.normN(r.len); |
| 892 | 847 | } |
| 893 | 848 | |
| 894 | 849 | // r = a << shift, in other words, r = a * 2^shift |
| 895 | | pub fn shiftLeft(r: *Int, av: var, shift: usize) !void { |
| 896 | | var buffer: [wrapped_buffer_size]u8 = undefined; |
| 897 | | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); |
| 898 | | var a = wrapInt(&stack.allocator, av); |
| 899 | | |
| 850 | pub fn shiftLeft(r: *Int, a: Int, shift: usize) !void { |
| 900 | 851 | try r.ensureCapacity(a.len + (shift / Limb.bit_count) + 1); |
| 901 | 852 | llshl(r.limbs[0..], a.limbs[0..a.len], shift); |
| 902 | 853 | r.norm1(a.len + (shift / Limb.bit_count) + 1); |
| ... | ... | @@ -927,11 +878,7 @@ pub const Int = struct { |
| 927 | 878 | } |
| 928 | 879 | |
| 929 | 880 | // r = a >> shift |
| 930 | | pub fn shiftRight(r: *Int, av: var, shift: usize) !void { |
| 931 | | var buffer: [wrapped_buffer_size]u8 = undefined; |
| 932 | | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); |
| 933 | | var a = wrapInt(&stack.allocator, av); |
| 934 | | |
| 881 | pub fn shiftRight(r: *Int, a: Int, shift: usize) !void { |
| 935 | 882 | if (a.len <= shift / Limb.bit_count) { |
| 936 | 883 | r.len = 1; |
| 937 | 884 | r.limbs[0] = 0; |
| ... | ... | @@ -966,12 +913,7 @@ pub const Int = struct { |
| 966 | 913 | } |
| 967 | 914 | |
| 968 | 915 | // r = a | b |
| 969 | | pub fn bitOr(r: *Int, av: var, bv: var) !void { |
| 970 | | var buffer: [2 * wrapped_buffer_size]u8 = undefined; |
| 971 | | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); |
| 972 | | var a = wrapInt(&stack.allocator, av); |
| 973 | | var b = wrapInt(&stack.allocator, bv); |
| 974 | | |
| 916 | pub fn bitOr(r: *Int, a: Int, b: Int) !void { |
| 975 | 917 | if (a.len > b.len) { |
| 976 | 918 | try r.ensureCapacity(a.len); |
| 977 | 919 | llor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); |
| ... | ... | @@ -998,12 +940,7 @@ pub const Int = struct { |
| 998 | 940 | } |
| 999 | 941 | |
| 1000 | 942 | // r = a & b |
| 1001 | | pub fn bitAnd(r: *Int, av: var, bv: var) !void { |
| 1002 | | var buffer: [2 * wrapped_buffer_size]u8 = undefined; |
| 1003 | | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); |
| 1004 | | var a = wrapInt(&stack.allocator, av); |
| 1005 | | var b = wrapInt(&stack.allocator, bv); |
| 1006 | | |
| 943 | pub fn bitAnd(r: *Int, a: Int, b: Int) !void { |
| 1007 | 944 | if (a.len > b.len) { |
| 1008 | 945 | try r.ensureCapacity(b.len); |
| 1009 | 946 | lland(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); |
| ... | ... | @@ -1027,12 +964,7 @@ pub const Int = struct { |
| 1027 | 964 | } |
| 1028 | 965 | |
| 1029 | 966 | // r = a ^ b |
| 1030 | | pub fn bitXor(r: *Int, av: var, bv: var) !void { |
| 1031 | | var buffer: [2 * wrapped_buffer_size]u8 = undefined; |
| 1032 | | var stack = std.heap.FixedBufferAllocator.init(buffer[0..]); |
| 1033 | | var a = wrapInt(&stack.allocator, av); |
| 1034 | | var b = wrapInt(&stack.allocator, bv); |
| 1035 | | |
| 967 | pub fn bitXor(r: *Int, a: Int, b: Int) !void { |
| 1036 | 968 | if (a.len > b.len) { |
| 1037 | 969 | try r.ensureCapacity(a.len); |
| 1038 | 970 | llxor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]); |
| ... | ... | @@ -1065,7 +997,7 @@ pub const Int = struct { |
| 1065 | 997 | // may be untested in some cases. |
| 1066 | 998 | |
| 1067 | 999 | const u256 = @IntType(false, 256); |
| 1068 | | var al = debug.global_allocator; |
| 1000 | const al = debug.global_allocator; |
| 1069 | 1001 | |
| 1070 | 1002 | test "big.int comptime_int set" { |
| 1071 | 1003 | comptime var s = 0xefffffff00000001eeeeeeefaaaaaaab; |
| ... | ... | @@ -1198,7 +1130,7 @@ test "big.int bitcount + sizeInBase" { |
| 1198 | 1130 | debug.assert(a.sizeInBase(2) >= 32); |
| 1199 | 1131 | debug.assert(a.sizeInBase(10) >= 10); |
| 1200 | 1132 | |
| 1201 | | try a.shiftLeft(&a, 5000); |
| 1133 | try a.shiftLeft(a, 5000); |
| 1202 | 1134 | debug.assert(a.bitcount() == 5032); |
| 1203 | 1135 | debug.assert(a.sizeInBase(2) >= 5032); |
| 1204 | 1136 | a.positive = false; |
| ... | ... | @@ -1320,40 +1252,40 @@ test "big.int compare" { |
| 1320 | 1252 | var a = try Int.initSet(al, -11); |
| 1321 | 1253 | var b = try Int.initSet(al, 10); |
| 1322 | 1254 | |
| 1323 | | debug.assert(a.cmpAbs(&b) == 1); |
| 1324 | | debug.assert(a.cmp(&b) == -1); |
| 1255 | debug.assert(a.cmpAbs(b) == 1); |
| 1256 | debug.assert(a.cmp(b) == -1); |
| 1325 | 1257 | } |
| 1326 | 1258 | |
| 1327 | 1259 | test "big.int compare similar" { |
| 1328 | 1260 | var a = try Int.initSet(al, 0xffffffffeeeeeeeeffffffffeeeeeeee); |
| 1329 | 1261 | var b = try Int.initSet(al, 0xffffffffeeeeeeeeffffffffeeeeeeef); |
| 1330 | 1262 | |
| 1331 | | debug.assert(a.cmpAbs(&b) == -1); |
| 1332 | | debug.assert(b.cmpAbs(&a) == 1); |
| 1263 | debug.assert(a.cmpAbs(b) == -1); |
| 1264 | debug.assert(b.cmpAbs(a) == 1); |
| 1333 | 1265 | } |
| 1334 | 1266 | |
| 1335 | 1267 | test "big.int compare different limb size" { |
| 1336 | 1268 | var a = try Int.initSet(al, @maxValue(Limb) + 1); |
| 1337 | 1269 | var b = try Int.initSet(al, 1); |
| 1338 | 1270 | |
| 1339 | | debug.assert(a.cmpAbs(&b) == 1); |
| 1340 | | debug.assert(b.cmpAbs(&a) == -1); |
| 1271 | debug.assert(a.cmpAbs(b) == 1); |
| 1272 | debug.assert(b.cmpAbs(a) == -1); |
| 1341 | 1273 | } |
| 1342 | 1274 | |
| 1343 | 1275 | test "big.int compare multi-limb" { |
| 1344 | 1276 | var a = try Int.initSet(al, -0x7777777799999999ffffeeeeffffeeeeffffeeeef); |
| 1345 | 1277 | var b = try Int.initSet(al, 0x7777777799999999ffffeeeeffffeeeeffffeeeee); |
| 1346 | 1278 | |
| 1347 | | debug.assert(a.cmpAbs(&b) == 1); |
| 1348 | | debug.assert(a.cmp(&b) == -1); |
| 1279 | debug.assert(a.cmpAbs(b) == 1); |
| 1280 | debug.assert(a.cmp(b) == -1); |
| 1349 | 1281 | } |
| 1350 | 1282 | |
| 1351 | 1283 | test "big.int equality" { |
| 1352 | 1284 | var a = try Int.initSet(al, 0xffffffff1); |
| 1353 | 1285 | var b = try Int.initSet(al, -0xffffffff1); |
| 1354 | 1286 | |
| 1355 | | debug.assert(a.eqAbs(&b)); |
| 1356 | | debug.assert(!a.eq(&b)); |
| 1287 | debug.assert(a.eqAbs(b)); |
| 1288 | debug.assert(!a.eq(b)); |
| 1357 | 1289 | } |
| 1358 | 1290 | |
| 1359 | 1291 | test "big.int abs" { |
| ... | ... | @@ -1381,7 +1313,7 @@ test "big.int add single-single" { |
| 1381 | 1313 | var b = try Int.initSet(al, 5); |
| 1382 | 1314 | |
| 1383 | 1315 | var c = try Int.init(al); |
| 1384 | | try c.add(&a, &b); |
| 1316 | try c.add(a, b); |
| 1385 | 1317 | |
| 1386 | 1318 | debug.assert((try c.to(u32)) == 55); |
| 1387 | 1319 | } |
| ... | ... | @@ -1392,10 +1324,10 @@ test "big.int add multi-single" { |
| 1392 | 1324 | |
| 1393 | 1325 | var c = try Int.init(al); |
| 1394 | 1326 | |
| 1395 | | try c.add(&a, &b); |
| 1327 | try c.add(a, b); |
| 1396 | 1328 | debug.assert((try c.to(DoubleLimb)) == @maxValue(Limb) + 2); |
| 1397 | 1329 | |
| 1398 | | try c.add(&b, &a); |
| 1330 | try c.add(b, a); |
| 1399 | 1331 | debug.assert((try c.to(DoubleLimb)) == @maxValue(Limb) + 2); |
| 1400 | 1332 | } |
| 1401 | 1333 | |
| ... | ... | @@ -1406,7 +1338,7 @@ test "big.int add multi-multi" { |
| 1406 | 1338 | var b = try Int.initSet(al, op2); |
| 1407 | 1339 | |
| 1408 | 1340 | var c = try Int.init(al); |
| 1409 | | try c.add(&a, &b); |
| 1341 | try c.add(a, b); |
| 1410 | 1342 | |
| 1411 | 1343 | debug.assert((try c.to(u128)) == op1 + op2); |
| 1412 | 1344 | } |
| ... | ... | @@ -1416,7 +1348,7 @@ test "big.int add zero-zero" { |
| 1416 | 1348 | var b = try Int.initSet(al, 0); |
| 1417 | 1349 | |
| 1418 | 1350 | var c = try Int.init(al); |
| 1419 | | try c.add(&a, &b); |
| 1351 | try c.add(a, b); |
| 1420 | 1352 | |
| 1421 | 1353 | debug.assert((try c.to(u32)) == 0); |
| 1422 | 1354 | } |
| ... | ... | @@ -1426,7 +1358,7 @@ test "big.int add alias multi-limb nonzero-zero" { |
| 1426 | 1358 | var a = try Int.initSet(al, op1); |
| 1427 | 1359 | var b = try Int.initSet(al, 0); |
| 1428 | 1360 | |
| 1429 | | try a.add(&a, &b); |
| 1361 | try a.add(a, b); |
| 1430 | 1362 | |
| 1431 | 1363 | debug.assert((try a.to(u128)) == op1); |
| 1432 | 1364 | } |
| ... | ... | @@ -1434,16 +1366,21 @@ test "big.int add alias multi-limb nonzero-zero" { |
| 1434 | 1366 | test "big.int add sign" { |
| 1435 | 1367 | var a = try Int.init(al); |
| 1436 | 1368 | |
| 1437 | | try a.add(1, 2); |
| 1369 | const one = try Int.initSet(al, 1); |
| 1370 | const two = try Int.initSet(al, 2); |
| 1371 | const neg_one = try Int.initSet(al, -1); |
| 1372 | const neg_two = try Int.initSet(al, -2); |
| 1373 | |
| 1374 | try a.add(one, two); |
| 1438 | 1375 | debug.assert((try a.to(i32)) == 3); |
| 1439 | 1376 | |
| 1440 | | try a.add(-1, 2); |
| 1377 | try a.add(neg_one, two); |
| 1441 | 1378 | debug.assert((try a.to(i32)) == 1); |
| 1442 | 1379 | |
| 1443 | | try a.add(1, -2); |
| 1380 | try a.add(one, neg_two); |
| 1444 | 1381 | debug.assert((try a.to(i32)) == -1); |
| 1445 | 1382 | |
| 1446 | | try a.add(-1, -2); |
| 1383 | try a.add(neg_one, neg_two); |
| 1447 | 1384 | debug.assert((try a.to(i32)) == -3); |
| 1448 | 1385 | } |
| 1449 | 1386 | |
| ... | ... | @@ -1452,7 +1389,7 @@ test "big.int sub single-single" { |
| 1452 | 1389 | var b = try Int.initSet(al, 5); |
| 1453 | 1390 | |
| 1454 | 1391 | var c = try Int.init(al); |
| 1455 | | try c.sub(&a, &b); |
| 1392 | try c.sub(a, b); |
| 1456 | 1393 | |
| 1457 | 1394 | debug.assert((try c.to(u32)) == 45); |
| 1458 | 1395 | } |
| ... | ... | @@ -1462,7 +1399,7 @@ test "big.int sub multi-single" { |
| 1462 | 1399 | var b = try Int.initSet(al, 1); |
| 1463 | 1400 | |
| 1464 | 1401 | var c = try Int.init(al); |
| 1465 | | try c.sub(&a, &b); |
| 1402 | try c.sub(a, b); |
| 1466 | 1403 | |
| 1467 | 1404 | debug.assert((try c.to(Limb)) == @maxValue(Limb)); |
| 1468 | 1405 | } |
| ... | ... | @@ -1475,7 +1412,7 @@ test "big.int sub multi-multi" { |
| 1475 | 1412 | var b = try Int.initSet(al, op2); |
| 1476 | 1413 | |
| 1477 | 1414 | var c = try Int.init(al); |
| 1478 | | try c.sub(&a, &b); |
| 1415 | try c.sub(a, b); |
| 1479 | 1416 | |
| 1480 | 1417 | debug.assert((try c.to(u128)) == op1 - op2); |
| 1481 | 1418 | } |
| ... | ... | @@ -1485,7 +1422,7 @@ test "big.int sub equal" { |
| 1485 | 1422 | var b = try Int.initSet(al, 0x11efefefefefefefefefefefef); |
| 1486 | 1423 | |
| 1487 | 1424 | var c = try Int.init(al); |
| 1488 | | try c.sub(&a, &b); |
| 1425 | try c.sub(a, b); |
| 1489 | 1426 | |
| 1490 | 1427 | debug.assert((try c.to(u32)) == 0); |
| 1491 | 1428 | } |
| ... | ... | @@ -1493,19 +1430,24 @@ test "big.int sub equal" { |
| 1493 | 1430 | test "big.int sub sign" { |
| 1494 | 1431 | var a = try Int.init(al); |
| 1495 | 1432 | |
| 1496 | | try a.sub(1, 2); |
| 1433 | const one = try Int.initSet(al, 1); |
| 1434 | const two = try Int.initSet(al, 2); |
| 1435 | const neg_one = try Int.initSet(al, -1); |
| 1436 | const neg_two = try Int.initSet(al, -2); |
| 1437 | |
| 1438 | try a.sub(one, two); |
| 1497 | 1439 | debug.assert((try a.to(i32)) == -1); |
| 1498 | 1440 | |
| 1499 | | try a.sub(-1, 2); |
| 1441 | try a.sub(neg_one, two); |
| 1500 | 1442 | debug.assert((try a.to(i32)) == -3); |
| 1501 | 1443 | |
| 1502 | | try a.sub(1, -2); |
| 1444 | try a.sub(one, neg_two); |
| 1503 | 1445 | debug.assert((try a.to(i32)) == 3); |
| 1504 | 1446 | |
| 1505 | | try a.sub(-1, -2); |
| 1447 | try a.sub(neg_one, neg_two); |
| 1506 | 1448 | debug.assert((try a.to(i32)) == 1); |
| 1507 | 1449 | |
| 1508 | | try a.sub(-2, -1); |
| 1450 | try a.sub(neg_two, neg_one); |
| 1509 | 1451 | debug.assert((try a.to(i32)) == -1); |
| 1510 | 1452 | } |
| 1511 | 1453 | |
| ... | ... | @@ -1514,7 +1456,7 @@ test "big.int mul single-single" { |
| 1514 | 1456 | var b = try Int.initSet(al, 5); |
| 1515 | 1457 | |
| 1516 | 1458 | var c = try Int.init(al); |
| 1517 | | try c.mul(&a, &b); |
| 1459 | try c.mul(a, b); |
| 1518 | 1460 | |
| 1519 | 1461 | debug.assert((try c.to(u64)) == 250); |
| 1520 | 1462 | } |
| ... | ... | @@ -1524,7 +1466,7 @@ test "big.int mul multi-single" { |
| 1524 | 1466 | var b = try Int.initSet(al, 2); |
| 1525 | 1467 | |
| 1526 | 1468 | var c = try Int.init(al); |
| 1527 | | try c.mul(&a, &b); |
| 1469 | try c.mul(a, b); |
| 1528 | 1470 | |
| 1529 | 1471 | debug.assert((try c.to(DoubleLimb)) == 2 * @maxValue(Limb)); |
| 1530 | 1472 | } |
| ... | ... | @@ -1536,7 +1478,7 @@ test "big.int mul multi-multi" { |
| 1536 | 1478 | var b = try Int.initSet(al, op2); |
| 1537 | 1479 | |
| 1538 | 1480 | var c = try Int.init(al); |
| 1539 | | try c.mul(&a, &b); |
| 1481 | try c.mul(a, b); |
| 1540 | 1482 | |
| 1541 | 1483 | debug.assert((try c.to(u256)) == op1 * op2); |
| 1542 | 1484 | } |
| ... | ... | @@ -1545,7 +1487,7 @@ test "big.int mul alias r with a" { |
| 1545 | 1487 | var a = try Int.initSet(al, @maxValue(Limb)); |
| 1546 | 1488 | var b = try Int.initSet(al, 2); |
| 1547 | 1489 | |
| 1548 | | try a.mul(&a, &b); |
| 1490 | try a.mul(a, b); |
| 1549 | 1491 | |
| 1550 | 1492 | debug.assert((try a.to(DoubleLimb)) == 2 * @maxValue(Limb)); |
| 1551 | 1493 | } |
| ... | ... | @@ -1554,7 +1496,7 @@ test "big.int mul alias r with b" { |
| 1554 | 1496 | var a = try Int.initSet(al, @maxValue(Limb)); |
| 1555 | 1497 | var b = try Int.initSet(al, 2); |
| 1556 | 1498 | |
| 1557 | | try a.mul(&b, &a); |
| 1499 | try a.mul(b, a); |
| 1558 | 1500 | |
| 1559 | 1501 | debug.assert((try a.to(DoubleLimb)) == 2 * @maxValue(Limb)); |
| 1560 | 1502 | } |
| ... | ... | @@ -1562,7 +1504,7 @@ test "big.int mul alias r with b" { |
| 1562 | 1504 | test "big.int mul alias r with a and b" { |
| 1563 | 1505 | var a = try Int.initSet(al, @maxValue(Limb)); |
| 1564 | 1506 | |
| 1565 | | try a.mul(&a, &a); |
| 1507 | try a.mul(a, a); |
| 1566 | 1508 | |
| 1567 | 1509 | debug.assert((try a.to(DoubleLimb)) == @maxValue(Limb) * @maxValue(Limb)); |
| 1568 | 1510 | } |
| ... | ... | @@ -1572,7 +1514,7 @@ test "big.int mul a*0" { |
| 1572 | 1514 | var b = try Int.initSet(al, 0); |
| 1573 | 1515 | |
| 1574 | 1516 | var c = try Int.init(al); |
| 1575 | | try c.mul(&a, &b); |
| 1517 | try c.mul(a, b); |
| 1576 | 1518 | |
| 1577 | 1519 | debug.assert((try c.to(u32)) == 0); |
| 1578 | 1520 | } |
| ... | ... | @@ -1582,7 +1524,7 @@ test "big.int mul 0*0" { |
| 1582 | 1524 | var b = try Int.initSet(al, 0); |
| 1583 | 1525 | |
| 1584 | 1526 | var c = try Int.init(al); |
| 1585 | | try c.mul(&a, &b); |
| 1527 | try c.mul(a, b); |
| 1586 | 1528 | |
| 1587 | 1529 | debug.assert((try c.to(u32)) == 0); |
| 1588 | 1530 | } |
| ... | ... | @@ -1593,7 +1535,7 @@ test "big.int div single-single no rem" { |
| 1593 | 1535 | |
| 1594 | 1536 | var q = try Int.init(al); |
| 1595 | 1537 | var r = try Int.init(al); |
| 1596 | | try Int.divTrunc(&q, &r, &a, &b); |
| 1538 | try Int.divTrunc(&q, &r, a, b); |
| 1597 | 1539 | |
| 1598 | 1540 | debug.assert((try q.to(u32)) == 10); |
| 1599 | 1541 | debug.assert((try r.to(u32)) == 0); |
| ... | ... | @@ -1605,7 +1547,7 @@ test "big.int div single-single with rem" { |
| 1605 | 1547 | |
| 1606 | 1548 | var q = try Int.init(al); |
| 1607 | 1549 | var r = try Int.init(al); |
| 1608 | | try Int.divTrunc(&q, &r, &a, &b); |
| 1550 | try Int.divTrunc(&q, &r, a, b); |
| 1609 | 1551 | |
| 1610 | 1552 | debug.assert((try q.to(u32)) == 9); |
| 1611 | 1553 | debug.assert((try r.to(u32)) == 4); |
| ... | ... | @@ -1620,7 +1562,7 @@ test "big.int div multi-single no rem" { |
| 1620 | 1562 | |
| 1621 | 1563 | var q = try Int.init(al); |
| 1622 | 1564 | var r = try Int.init(al); |
| 1623 | | try Int.divTrunc(&q, &r, &a, &b); |
| 1565 | try Int.divTrunc(&q, &r, a, b); |
| 1624 | 1566 | |
| 1625 | 1567 | debug.assert((try q.to(u64)) == op1 / op2); |
| 1626 | 1568 | debug.assert((try r.to(u64)) == 0); |
| ... | ... | @@ -1635,7 +1577,7 @@ test "big.int div multi-single with rem" { |
| 1635 | 1577 | |
| 1636 | 1578 | var q = try Int.init(al); |
| 1637 | 1579 | var r = try Int.init(al); |
| 1638 | | try Int.divTrunc(&q, &r, &a, &b); |
| 1580 | try Int.divTrunc(&q, &r, a, b); |
| 1639 | 1581 | |
| 1640 | 1582 | debug.assert((try q.to(u64)) == op1 / op2); |
| 1641 | 1583 | debug.assert((try r.to(u64)) == 3); |
| ... | ... | @@ -1650,7 +1592,7 @@ test "big.int div multi>2-single" { |
| 1650 | 1592 | |
| 1651 | 1593 | var q = try Int.init(al); |
| 1652 | 1594 | var r = try Int.init(al); |
| 1653 | | try Int.divTrunc(&q, &r, &a, &b); |
| 1595 | try Int.divTrunc(&q, &r, a, b); |
| 1654 | 1596 | |
| 1655 | 1597 | debug.assert((try q.to(u128)) == op1 / op2); |
| 1656 | 1598 | debug.assert((try r.to(u32)) == 0x3e4e); |
| ... | ... | @@ -1662,7 +1604,7 @@ test "big.int div single-single q < r" { |
| 1662 | 1604 | |
| 1663 | 1605 | var q = try Int.init(al); |
| 1664 | 1606 | var r = try Int.init(al); |
| 1665 | | try Int.divTrunc(&q, &r, &a, &b); |
| 1607 | try Int.divTrunc(&q, &r, a, b); |
| 1666 | 1608 | |
| 1667 | 1609 | debug.assert((try q.to(u64)) == 0); |
| 1668 | 1610 | debug.assert((try r.to(u64)) == 0x0078f432); |
| ... | ... | @@ -1674,7 +1616,7 @@ test "big.int div single-single q == r" { |
| 1674 | 1616 | |
| 1675 | 1617 | var q = try Int.init(al); |
| 1676 | 1618 | var r = try Int.init(al); |
| 1677 | | try Int.divTrunc(&q, &r, &a, &b); |
| 1619 | try Int.divTrunc(&q, &r, a, b); |
| 1678 | 1620 | |
| 1679 | 1621 | debug.assert((try q.to(u64)) == 1); |
| 1680 | 1622 | debug.assert((try r.to(u64)) == 0); |
| ... | ... | @@ -1684,7 +1626,7 @@ test "big.int div q=0 alias" { |
| 1684 | 1626 | var a = try Int.initSet(al, 3); |
| 1685 | 1627 | var b = try Int.initSet(al, 10); |
| 1686 | 1628 | |
| 1687 | | try Int.divTrunc(&a, &b, &a, &b); |
| 1629 | try Int.divTrunc(&a, &b, a, b); |
| 1688 | 1630 | |
| 1689 | 1631 | debug.assert((try a.to(u64)) == 0); |
| 1690 | 1632 | debug.assert((try b.to(u64)) == 3); |
| ... | ... | @@ -1698,7 +1640,7 @@ test "big.int div multi-multi q < r" { |
| 1698 | 1640 | |
| 1699 | 1641 | var q = try Int.init(al); |
| 1700 | 1642 | var r = try Int.init(al); |
| 1701 | | try Int.divTrunc(&q, &r, &a, &b); |
| 1643 | try Int.divTrunc(&q, &r, a, b); |
| 1702 | 1644 | |
| 1703 | 1645 | debug.assert((try q.to(u128)) == 0); |
| 1704 | 1646 | debug.assert((try r.to(u128)) == op1); |
| ... | ... | @@ -1713,7 +1655,7 @@ test "big.int div trunc single-single +/+" { |
| 1713 | 1655 | |
| 1714 | 1656 | var q = try Int.init(al); |
| 1715 | 1657 | var r = try Int.init(al); |
| 1716 | | try Int.divTrunc(&q, &r, &a, &b); |
| 1658 | try Int.divTrunc(&q, &r, a, b); |
| 1717 | 1659 | |
| 1718 | 1660 | // n = q * d + r |
| 1719 | 1661 | // 5 = 1 * 3 + 2 |
| ... | ... | @@ -1733,7 +1675,7 @@ test "big.int div trunc single-single -/+" { |
| 1733 | 1675 | |
| 1734 | 1676 | var q = try Int.init(al); |
| 1735 | 1677 | var r = try Int.init(al); |
| 1736 | | try Int.divTrunc(&q, &r, &a, &b); |
| 1678 | try Int.divTrunc(&q, &r, a, b); |
| 1737 | 1679 | |
| 1738 | 1680 | // n = q * d + r |
| 1739 | 1681 | // -5 = 1 * -3 - 2 |
| ... | ... | @@ -1753,7 +1695,7 @@ test "big.int div trunc single-single +/-" { |
| 1753 | 1695 | |
| 1754 | 1696 | var q = try Int.init(al); |
| 1755 | 1697 | var r = try Int.init(al); |
| 1756 | | try Int.divTrunc(&q, &r, &a, &b); |
| 1698 | try Int.divTrunc(&q, &r, a, b); |
| 1757 | 1699 | |
| 1758 | 1700 | // n = q * d + r |
| 1759 | 1701 | // 5 = -1 * -3 + 2 |
| ... | ... | @@ -1773,7 +1715,7 @@ test "big.int div trunc single-single -/-" { |
| 1773 | 1715 | |
| 1774 | 1716 | var q = try Int.init(al); |
| 1775 | 1717 | var r = try Int.init(al); |
| 1776 | | try Int.divTrunc(&q, &r, &a, &b); |
| 1718 | try Int.divTrunc(&q, &r, a, b); |
| 1777 | 1719 | |
| 1778 | 1720 | // n = q * d + r |
| 1779 | 1721 | // -5 = 1 * -3 - 2 |
| ... | ... | @@ -1793,7 +1735,7 @@ test "big.int div floor single-single +/+" { |
| 1793 | 1735 | |
| 1794 | 1736 | var q = try Int.init(al); |
| 1795 | 1737 | var r = try Int.init(al); |
| 1796 | | try Int.divFloor(&q, &r, &a, &b); |
| 1738 | try Int.divFloor(&q, &r, a, b); |
| 1797 | 1739 | |
| 1798 | 1740 | // n = q * d + r |
| 1799 | 1741 | // 5 = 1 * 3 + 2 |
| ... | ... | @@ -1813,7 +1755,7 @@ test "big.int div floor single-single -/+" { |
| 1813 | 1755 | |
| 1814 | 1756 | var q = try Int.init(al); |
| 1815 | 1757 | var r = try Int.init(al); |
| 1816 | | try Int.divFloor(&q, &r, &a, &b); |
| 1758 | try Int.divFloor(&q, &r, a, b); |
| 1817 | 1759 | |
| 1818 | 1760 | // n = q * d + r |
| 1819 | 1761 | // -5 = -2 * 3 + 1 |
| ... | ... | @@ -1833,7 +1775,7 @@ test "big.int div floor single-single +/-" { |
| 1833 | 1775 | |
| 1834 | 1776 | var q = try Int.init(al); |
| 1835 | 1777 | var r = try Int.init(al); |
| 1836 | | try Int.divFloor(&q, &r, &a, &b); |
| 1778 | try Int.divFloor(&q, &r, a, b); |
| 1837 | 1779 | |
| 1838 | 1780 | // n = q * d + r |
| 1839 | 1781 | // 5 = -2 * -3 - 1 |
| ... | ... | @@ -1853,7 +1795,7 @@ test "big.int div floor single-single -/-" { |
| 1853 | 1795 | |
| 1854 | 1796 | var q = try Int.init(al); |
| 1855 | 1797 | var r = try Int.init(al); |
| 1856 | | try Int.divFloor(&q, &r, &a, &b); |
| 1798 | try Int.divFloor(&q, &r, a, b); |
| 1857 | 1799 | |
| 1858 | 1800 | // n = q * d + r |
| 1859 | 1801 | // -5 = 2 * -3 + 1 |
| ... | ... | @@ -1870,7 +1812,7 @@ test "big.int div multi-multi with rem" { |
| 1870 | 1812 | |
| 1871 | 1813 | var q = try Int.init(al); |
| 1872 | 1814 | var r = try Int.init(al); |
| 1873 | | try Int.divTrunc(&q, &r, &a, &b); |
| 1815 | try Int.divTrunc(&q, &r, a, b); |
| 1874 | 1816 | |
| 1875 | 1817 | debug.assert((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b); |
| 1876 | 1818 | debug.assert((try r.to(u128)) == 0x28de0acacd806823638); |
| ... | ... | @@ -1882,7 +1824,7 @@ test "big.int div multi-multi no rem" { |
| 1882 | 1824 | |
| 1883 | 1825 | var q = try Int.init(al); |
| 1884 | 1826 | var r = try Int.init(al); |
| 1885 | | try Int.divTrunc(&q, &r, &a, &b); |
| 1827 | try Int.divTrunc(&q, &r, a, b); |
| 1886 | 1828 | |
| 1887 | 1829 | debug.assert((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b); |
| 1888 | 1830 | debug.assert((try r.to(u128)) == 0); |
| ... | ... | @@ -1894,7 +1836,7 @@ test "big.int div multi-multi (2 branch)" { |
| 1894 | 1836 | |
| 1895 | 1837 | var q = try Int.init(al); |
| 1896 | 1838 | var r = try Int.init(al); |
| 1897 | | try Int.divTrunc(&q, &r, &a, &b); |
| 1839 | try Int.divTrunc(&q, &r, a, b); |
| 1898 | 1840 | |
| 1899 | 1841 | debug.assert((try q.to(u128)) == 0x10000000000000000); |
| 1900 | 1842 | debug.assert((try r.to(u128)) == 0x44444443444444431111111111111111); |
| ... | ... | @@ -1906,7 +1848,7 @@ test "big.int div multi-multi (3.1/3.3 branch)" { |
| 1906 | 1848 | |
| 1907 | 1849 | var q = try Int.init(al); |
| 1908 | 1850 | var r = try Int.init(al); |
| 1909 | | try Int.divTrunc(&q, &r, &a, &b); |
| 1851 | try Int.divTrunc(&q, &r, a, b); |
| 1910 | 1852 | |
| 1911 | 1853 | debug.assert((try q.to(u128)) == 0xfffffffffffffffffff); |
| 1912 | 1854 | debug.assert((try r.to(u256)) == 0x1111111111111111111110b12222222222222222282); |
| ... | ... | @@ -1943,17 +1885,17 @@ test "big.int shift-left multi" { |
| 1943 | 1885 | test "big.int shift-right negative" { |
| 1944 | 1886 | var a = try Int.init(al); |
| 1945 | 1887 | |
| 1946 | | try a.shiftRight(-20, 2); |
| 1888 | try a.shiftRight(try Int.initSet(al, -20), 2); |
| 1947 | 1889 | debug.assert((try a.to(i32)) == -20 >> 2); |
| 1948 | 1890 | |
| 1949 | | try a.shiftRight(-5, 10); |
| 1891 | try a.shiftRight(try Int.initSet(al, -5), 10); |
| 1950 | 1892 | debug.assert((try a.to(i32)) == -5 >> 10); |
| 1951 | 1893 | } |
| 1952 | 1894 | |
| 1953 | 1895 | test "big.int shift-left negative" { |
| 1954 | 1896 | var a = try Int.init(al); |
| 1955 | 1897 | |
| 1956 | | try a.shiftRight(-10, 1232); |
| 1898 | try a.shiftRight(try Int.initSet(al, -10), 1232); |
| 1957 | 1899 | debug.assert((try a.to(i32)) == -10 >> 1232); |
| 1958 | 1900 | } |
| 1959 | 1901 | |
| ... | ... | @@ -1961,7 +1903,7 @@ test "big.int bitwise and simple" { |
| 1961 | 1903 | var a = try Int.initSet(al, 0xffffffff11111111); |
| 1962 | 1904 | var b = try Int.initSet(al, 0xeeeeeeee22222222); |
| 1963 | 1905 | |
| 1964 | | try a.bitAnd(&a, &b); |
| 1906 | try a.bitAnd(a, b); |
| 1965 | 1907 | |
| 1966 | 1908 | debug.assert((try a.to(u64)) == 0xeeeeeeee00000000); |
| 1967 | 1909 | } |
| ... | ... | @@ -1970,7 +1912,7 @@ test "big.int bitwise and multi-limb" { |
| 1970 | 1912 | var a = try Int.initSet(al, @maxValue(Limb) + 1); |
| 1971 | 1913 | var b = try Int.initSet(al, @maxValue(Limb)); |
| 1972 | 1914 | |
| 1973 | | try a.bitAnd(&a, &b); |
| 1915 | try a.bitAnd(a, b); |
| 1974 | 1916 | |
| 1975 | 1917 | debug.assert((try a.to(u128)) == 0); |
| 1976 | 1918 | } |
| ... | ... | @@ -1979,7 +1921,7 @@ test "big.int bitwise xor simple" { |
| 1979 | 1921 | var a = try Int.initSet(al, 0xffffffff11111111); |
| 1980 | 1922 | var b = try Int.initSet(al, 0xeeeeeeee22222222); |
| 1981 | 1923 | |
| 1982 | | try a.bitXor(&a, &b); |
| 1924 | try a.bitXor(a, b); |
| 1983 | 1925 | |
| 1984 | 1926 | debug.assert((try a.to(u64)) == 0x1111111133333333); |
| 1985 | 1927 | } |
| ... | ... | @@ -1988,7 +1930,7 @@ test "big.int bitwise xor multi-limb" { |
| 1988 | 1930 | var a = try Int.initSet(al, @maxValue(Limb) + 1); |
| 1989 | 1931 | var b = try Int.initSet(al, @maxValue(Limb)); |
| 1990 | 1932 | |
| 1991 | | try a.bitXor(&a, &b); |
| 1933 | try a.bitXor(a, b); |
| 1992 | 1934 | |
| 1993 | 1935 | debug.assert((try a.to(DoubleLimb)) == (@maxValue(Limb) + 1) ^ @maxValue(Limb)); |
| 1994 | 1936 | } |
| ... | ... | @@ -1997,7 +1939,7 @@ test "big.int bitwise or simple" { |
| 1997 | 1939 | var a = try Int.initSet(al, 0xffffffff11111111); |
| 1998 | 1940 | var b = try Int.initSet(al, 0xeeeeeeee22222222); |
| 1999 | 1941 | |
| 2000 | | try a.bitOr(&a, &b); |
| 1942 | try a.bitOr(a, b); |
| 2001 | 1943 | |
| 2002 | 1944 | debug.assert((try a.to(u64)) == 0xffffffff33333333); |
| 2003 | 1945 | } |
| ... | ... | @@ -2006,7 +1948,7 @@ test "big.int bitwise or multi-limb" { |
| 2006 | 1948 | var a = try Int.initSet(al, @maxValue(Limb) + 1); |
| 2007 | 1949 | var b = try Int.initSet(al, @maxValue(Limb)); |
| 2008 | 1950 | |
| 2009 | | try a.bitOr(&a, &b); |
| 1951 | try a.bitOr(a, b); |
| 2010 | 1952 | |
| 2011 | 1953 | // TODO: big.int.cpp or is wrong on multi-limb. |
| 2012 | 1954 | debug.assert((try a.to(DoubleLimb)) == (@maxValue(Limb) + 1) + @maxValue(Limb)); |
| ... | ... | @@ -2015,9 +1957,9 @@ test "big.int bitwise or multi-limb" { |
| 2015 | 1957 | test "big.int var args" { |
| 2016 | 1958 | var a = try Int.initSet(al, 5); |
| 2017 | 1959 | |
| 2018 | | try a.add(&a, 6); |
| 1960 | try a.add(a, try Int.initSet(al, 6)); |
| 2019 | 1961 | debug.assert((try a.to(u64)) == 11); |
| 2020 | 1962 | |
| 2021 | | debug.assert(a.cmp(11) == 0); |
| 2022 | | debug.assert(a.cmp(14) <= 0); |
| 1963 | debug.assert(a.cmp(try Int.initSet(al, 11)) == 0); |
| 1964 | debug.assert(a.cmp(try Int.initSet(al, 14)) <= 0); |
| 2023 | 1965 | } |