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 {
15761576 // for i from n down to t + 1, do
15771577 var i = n;
15781578 while (i >= t + 1) : (i -= 1) {
1579 if (x.eqZero()) {
1580 break;
1581 }
1582
15831579 const k = i - t - 1;
15841580 // 3.1.
15851581 // if x_i == y_t:
......@@ -1630,7 +1626,6 @@ pub const Mutable = struct {
16301626 // Note, we multiply by a single limb here.
16311627 // The shift doesn't need to be performed if we add the result of the first multiplication
16321628 // to x[i - t - 1].
1633 // mem.set(Limb, x.limbs, 0);
16341629 const underflow = llmulLimb(.sub, x.limbs[k..x.len], y.limbs[0..y.len], q.limbs[k]);
16351630
16361631 // 3.4.
......@@ -1643,10 +1638,9 @@ pub const Mutable = struct {
16431638 llaccum(.add, x.limbs[k..x.len], y.limbs[0..y.len]);
16441639 q.limbs[k] -= 1;
16451640 }
1646
1647 x.normalize(x.len);
16481641 }
16491642
1643 x.normalize(x.len);
16501644 q.normalize(q.len);
16511645
16521646 // De-normalize r and y.
lib/std/math/big/int_test.zig+27
......@@ -1369,6 +1369,33 @@ test "big.int divFloor #10932" {
13691369 try testing.expect((try mod.to(i32)) == 0);
13701370}
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
13721399test "big.int gcd #10932" {
13731400 var a = try Managed.init(testing.allocator);
13741401 defer a.deinit();