zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit cd3dcc225b52be981b52b71dcdb34ba176f4081b (tree)
parent 351e4f07cebc8299c107bd3de760efe17d184af7
Author: Robin Voetter <robin@voetter.nl>
Date:   Thu, 23 Sep 2021 06:22:18 +0200

big ints: only write xor overflow if required

Diffstat:
Mlib/std/math/big/int.zig | 9++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig @@ -2495,6 +2495,8 @@ fn llsignedand(r: []Limb, a: []const Limb, a_positive: bool, b: []const Limb, b_ // r may alias. // a and b must not be -0. // Returns `true` when the result is positive. +// If the sign of a and b is equal, then r requires at least `max(a.len, b.len)` limbs are required. +// Otherwise, r requires at least `max(a.len, b.len) + 1` limbs. fn llsignedxor(r: []Limb, a: []const Limb, a_positive: bool, b: []const Limb, b_positive: bool) bool { @setRuntimeSafety(debug_safety); assert(a.len != 0 and b.len != 0); @@ -2538,7 +2540,12 @@ fn llsignedxor(r: []Limb, a: []const Limb, a_positive: bool, b: []const Limb, b_ r_carry = @boolToInt(@addWithOverflow(Limb, r[i], r_carry, &r[i])); } - r[i] = r_carry; + // If both inputs don't share the same sign, an extra limb is required. + if (a_positive != b_positive) { + r[i] = r_carry; + } else { + assert(r_carry == 0); + } assert(a_borrow == 0); assert(b_borrow == 0);