authorgravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2022-03-24 07:24:25+13:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-03-23 19:24:25+01:00
log2e0de0b4e20794c07fad76c657ad2c33f1928562
tree5a0732f87089da4581d88d3dc20d31a81e8ead3c
parent1cf1346323e05b1d481fd2fe0b20a79ed94d9360
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

math/big: correct fix for divmod (#11271)

Fixes #11166.

2 files changed, 28 insertions(+), 7 deletions(-)

lib/std/math/big/int.zig+1-7
...@@ -1576,10 +1576,6 @@ pub const Mutable = struct {...@@ -1576,10 +1576,6 @@ pub const Mutable = struct {
1576 // for i from n down to t + 1, do1576 // for i from n down to t + 1, do
1577 var i = n;1577 var i = n;
1578 while (i >= t + 1) : (i -= 1) {1578 while (i >= t + 1) : (i -= 1) {
1579 if (x.eqZero()) {
1580 break;
1581 }
1582
1583 const k = i - t - 1;1579 const k = i - t - 1;
1584 // 3.1.1580 // 3.1.
1585 // if x_i == y_t:1581 // if x_i == y_t:
...@@ -1630,7 +1626,6 @@ pub const Mutable = struct {...@@ -1630,7 +1626,6 @@ pub const Mutable = struct {
1630 // Note, we multiply by a single limb here.1626 // Note, we multiply by a single limb here.
1631 // The shift doesn't need to be performed if we add the result of the first multiplication1627 // The shift doesn't need to be performed if we add the result of the first multiplication
1632 // to x[i - t - 1].1628 // to x[i - t - 1].
1633 // mem.set(Limb, x.limbs, 0);
1634 const underflow = llmulLimb(.sub, x.limbs[k..x.len], y.limbs[0..y.len], q.limbs[k]);1629 const underflow = llmulLimb(.sub, x.limbs[k..x.len], y.limbs[0..y.len], q.limbs[k]);
16351630
1636 // 3.4.1631 // 3.4.
...@@ -1643,10 +1638,9 @@ pub const Mutable = struct {...@@ -1643,10 +1638,9 @@ pub const Mutable = struct {
1643 llaccum(.add, x.limbs[k..x.len], y.limbs[0..y.len]);1638 llaccum(.add, x.limbs[k..x.len], y.limbs[0..y.len]);
1644 q.limbs[k] -= 1;1639 q.limbs[k] -= 1;
1645 }1640 }
1646
1647 x.normalize(x.len);
1648 }1641 }
16491642
1643 x.normalize(x.len);
1650 q.normalize(q.len);1644 q.normalize(q.len);
16511645
1652 // De-normalize r and y.1646 // De-normalize r and y.
lib/std/math/big/int_test.zig+27
...@@ -1369,6 +1369,33 @@ test "big.int divFloor #10932" {...@@ -1369,6 +1369,33 @@ test "big.int divFloor #10932" {
1369 try testing.expect((try mod.to(i32)) == 0);1369 try testing.expect((try mod.to(i32)) == 0);
1370}1370}
13711371
1372test "big.int divFloor #11166" {
1373 var a = try Managed.init(testing.allocator);
1374 defer a.deinit();
1375
1376 var b = try Managed.init(testing.allocator);
1377 defer b.deinit();
1378
1379 var res = try Managed.init(testing.allocator);
1380 defer res.deinit();
1381
1382 try a.setString(10, "10000007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000870000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
1383 try b.setString(10, "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
1384
1385 var mod = try Managed.init(testing.allocator);
1386 defer mod.deinit();
1387
1388 try res.divFloor(&mod, a.toConst(), b.toConst());
1389
1390 const ress = try res.toString(testing.allocator, 10, .lower);
1391 defer testing.allocator.free(ress);
1392 try testing.expect(std.mem.eql(u8, ress, "1000000700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"));
1393
1394 const mods = try mod.toString(testing.allocator, 10, .lower);
1395 defer testing.allocator.free(mods);
1396 try testing.expect(std.mem.eql(u8, mods, "870000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"));
1397}
1398
1372test "big.int gcd #10932" {1399test "big.int gcd #10932" {
1373 var a = try Managed.init(testing.allocator);1400 var a = try Managed.init(testing.allocator);
1374 defer a.deinit();1401 defer a.deinit();