authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-09-28 11:22:21+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-04 11:25:29+02:00
loga36ef84deb1d52e513fbf311c71eaa2a9d48de00
treedd14e3f7f5f120496062961aeb8de5e57a9ea9e0
parent69be6ba8eea8e0b64153a0d0676f1b8749df8195

big ints: Basic wrapping multiplication


1 files changed, 43 insertions(+), 0 deletions(-)

lib/std/math/big/int.zig+43
......@@ -542,6 +542,36 @@ pub const Mutable = struct {
542542 rma.positive = (a.positive == b.positive);
543543 }
544544
545 pub fn mulNoAliasWrap(
546 rma: *Mutable,
547 a: Const,
548 b: Const,
549 signedness: std.builtin.Signedness,
550 bit_count: usize,
551 ) void {
552 assert(rma.limbs.ptr != a.limbs.ptr); // illegal aliasing
553 assert(rma.limbs.ptr != b.limbs.ptr); // illegal aliasing
554
555 const req_limbs = calcTwosCompLimbCount(bit_count);
556
557 // We can ignore the upper bits here, those results will be discarded anyway.
558 const a_limbs = a.limbs[0..math.min(req_limbs, a.limbs.len)];
559 const b_limbs = b.limbs[0..math.min(req_limbs, b.limbs.len)];
560
561 mem.set(Limb, rma.limbs[0..req_limbs], 0);
562
563 if (a_limbs.len >= b_limbs.len) {
564 llmulacc_lo(rma.limbs, a_limbs, b_limbs);
565 } else {
566 llmulacc_lo(rma.limbs, b_limbs, a_limbs);
567 }
568
569 rma.normalize(math.min(req_limbs, a.limbs.len + b.limbs.len));
570 rma.positive = (a.positive == b.positive);
571
572 rma.truncate(rma.toConst(), signedness, bit_count);
573 }
574
545575 /// rma = a * a
546576 ///
547577 /// `rma` may not alias with `a`.
......@@ -2156,6 +2186,19 @@ pub const Managed = struct {
21562186 }
21572187};
21582188
2189/// r = a * b, ignoring overflow
2190fn llmulacc_lo(r: []Limb, a: []const Limb, b: []const Limb) void {
2191 assert(r.len >= a.len);
2192 assert(a.len >= b.len);
2193
2194 // TODO: Improve performance.
2195
2196 var i: usize = 0;
2197 while (i < b.len) : (i += 1) {
2198 llmulDigit(r[i..], a, b[i]);
2199 }
2200}
2201
21592202/// Knuth 4.3.1, Algorithm M.
21602203///
21612204/// r MUST NOT alias any of a or b.