This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.
fnllsignedxor(r: []Limb, a: []constLimb, a_positive: bool, b: []constLimb, b_positive: bool) bool {
assert(a.len != 0andb.len != 0);
assert(r.len >= a.len);
assert(a.len >= b.len);
// If a and b are positive, the result is positive and r = a ^ b.
// If a negative, b positive, result is negative and we have
// r = --(--a ^ b)
// = --(~(-a - 1) ^ b)
// = -(~(~(-a - 1) ^ b) + 1)
// = -(((-a - 1) ^ b) + 1)
// Same if a is positive and b is negative, sides switched.
// If both a and b are negative, the result is positive and we have
// r = (--a) ^ (--b)
// = ~(-a - 1) ^ ~(-b - 1)
// = (-a - 1) ^ (-b - 1)
// These operations can be made more generic as follows:
// - If a is negative, subtract 1 from |a| before the xor.
// - If b is negative, subtract 1 from |b| before the xor.
// - if the result is supposed to be negative, add 1.
vari: usize = 0;
vara_borrow = @intFromBool(!a_positive);
varb_borrow = @intFromBool(!b_positive);
varr_carry = @intFromBool(a_positive != b_positive);
while (i < b.len) : (i += 1) {
constov1 = @subWithOverflow(a[i], a_borrow);
a_borrow = ov1[1];
constov2 = @subWithOverflow(b[i], b_borrow);
b_borrow = ov2[1];
constov3 = @addWithOverflow(ov1[0] ^ ov2[0], r_carry);
r[i] = ov3[0];
r_carry = ov3[1];
}
while (i < a.len) : (i += 1) {
constov1 = @subWithOverflow(a[i], a_borrow);
a_borrow = ov1[1];
constov2 = @addWithOverflow(ov1[0], r_carry);
r[i] = ov2[0];
r_carry = ov2[1];
}
// 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);
returna_positive == b_positive;
}