Commit 616b23c815

Robin Voetter <robin@voetter.nl>
2021-09-25 00:49:45
big ints: split lladd/llsub into carry variants
lladd is now implemented in terms of lladdcarry, which returns the carry limb. Similarly, llsub is implemented using llsubcarry, which returns the borrow limb.
1 parent c41b989
Changed files (1)
lib
std
math
lib/std/math/big/int.zig
@@ -2133,10 +2133,10 @@ fn llnormalize(a: []const Limb) usize {
 }
 
 /// Knuth 4.3.1, Algorithm S.
-fn llsub(r: []Limb, a: []const Limb, b: []const Limb) void {
+fn llsubcarry(r: []Limb, a: []const Limb, b: []const Limb) Limb {
     @setRuntimeSafety(debug_safety);
     assert(a.len != 0 and b.len != 0);
-    assert(a.len > b.len or (a.len == b.len and a[a.len - 1] >= b[b.len - 1]));
+    assert(a.len >= b.len);
     assert(r.len >= a.len);
 
     var i: usize = 0;
@@ -2153,15 +2153,21 @@ fn llsub(r: []Limb, a: []const Limb, b: []const Limb) void {
         borrow = @boolToInt(@subWithOverflow(Limb, a[i], borrow, &r[i]));
     }
 
-    assert(borrow == 0);
+    return borrow;
+}
+
+fn llsub(r: []Limb, a: []const Limb, b: []const Limb) void {
+    @setRuntimeSafety(debug_safety);
+    assert(a.len > b.len or (a.len == b.len and a[a.len - 1] >= b[b.len - 1]));
+    assert(llsubcarry(r, a, b) == 0);
 }
 
 /// Knuth 4.3.1, Algorithm A.
-fn lladd(r: []Limb, a: []const Limb, b: []const Limb) void {
+fn lladdcarry(r: []Limb, a: []const Limb, b: []const Limb) Limb {
     @setRuntimeSafety(debug_safety);
     assert(a.len != 0 and b.len != 0);
     assert(a.len >= b.len);
-    assert(r.len >= a.len + 1);
+    assert(r.len >= a.len);
 
     var i: usize = 0;
     var carry: Limb = 0;
@@ -2177,7 +2183,13 @@ fn lladd(r: []Limb, a: []const Limb, b: []const Limb) void {
         carry = @boolToInt(@addWithOverflow(Limb, a[i], carry, &r[i]));
     }
 
-    r[i] = carry;
+    return carry;
+}
+
+fn lladd(r: []Limb, a: []const Limb, b: []const Limb) void {
+    @setRuntimeSafety(debug_safety);
+    assert(r.len >= a.len + 1);
+    r[a.len] = lladdcarry(r, a, b);
 }
 
 /// Knuth 4.3.1, Exercise 16.