Skip to content

Commit e988da6

Browse files
committed
Fix egcd for even numbers.
1 parent df96127 commit e988da6

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

lib/std/math/egcd.zig

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,10 @@ inline fn egcd_helper(other: anytype, odd: anytype, shift: anytype) [3]@TypeOf(o
6565
}
6666
}
6767

68-
y = @shlExact(y, @intCast(shift));
69-
s = @shlExact(s, @intCast(shift));
7068
// Using integer widening is only a temporary solution.
7169
const W = std.meta.Int(.signed, @bitSizeOf(S) * 2);
7270
t = @intCast(@divExact(y - @as(W, s) * toinv, ctrl));
71+
y = @shlExact(y, @intCast(shift));
7372
return .{ @bitCast(y), s, t };
7473
}
7574

@@ -107,6 +106,24 @@ pub fn egcd(a: anytype, b: anytype) ExtendedGreatestCommonDivisor(@TypeOf(a, b))
107106
}
108107

109108
test {
109+
{
110+
const a: i32 = 128;
111+
const b: i32 = 112;
112+
const r = egcd(a, b);
113+
const g = r.gcd;
114+
const s: i64 = r.bezout_coeff_1;
115+
const t: i64 = r.bezout_coeff_2;
116+
try std.testing.expect(s * a + t * b == g);
117+
}
118+
{
119+
const a: i32 = 4 * 89;
120+
const b: i32 = 2 * 17;
121+
const r = egcd(a, b);
122+
const g = r.gcd;
123+
const s: i64 = r.bezout_coeff_1;
124+
const t: i64 = r.bezout_coeff_2;
125+
try std.testing.expect(s * a + t * b == g);
126+
}
110127
{
111128
const a: i8 = 127;
112129
const b: i8 = 126;

0 commit comments

Comments
 (0)