authorgravatar for 48591413+chrboesch@users.noreply.github.comChris Boesch <48591413+chrboesch@users.noreply.github.com> 2022-09-29 20:42:56+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-09-29 21:42:56+03:00
log9c99a88796cb00a220b4d093f5f1a84339167ace
treee256397b2db511b755892cf0463112d29bb0f47e
parent36d2a5503705b4da03dab9dbf724653895d2b641
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

std.math: add "Greatest common divisor" (gcd)


2 files changed, 49 insertions(+), 0 deletions(-)

lib/std/math.zig+1
......@@ -262,6 +262,7 @@ pub const atanh = @import("math/atanh.zig").atanh;
262262pub const sinh = @import("math/sinh.zig").sinh;
263263pub const cosh = @import("math/cosh.zig").cosh;
264264pub const tanh = @import("math/tanh.zig").tanh;
265pub const gcd = @import("math/gcd.zig").gcd;
265266
266267/// Sine trigonometric function on a floating point number.
267268/// Uses a dedicated hardware instruction when available.
lib/std/math/gcd.zig created+48
......@@ -0,0 +1,48 @@
1//! Greatest common divisor (https://mathworld.wolfram.com/GreatestCommonDivisor.html)
2const std = @import("std");
3const expectEqual = std.testing.expectEqual;
4
5/// Returns the greatest common divisor (GCD) of two unsigned integers (a and b) which are not both zero.
6/// For example, the GCD of 8 and 12 is 4, that is, gcd(8, 12) == 4.
7pub fn gcd(a: anytype, b: anytype) @TypeOf(a, b) {
8
9 // only unsigned integers are allowed and not both must be zero
10 comptime switch (@typeInfo(@TypeOf(a, b))) {
11 .Int => |int| std.debug.assert(int.signedness == .unsigned),
12 .ComptimeInt => {
13 std.debug.assert(a >= 0);
14 std.debug.assert(b >= 0);
15 },
16 else => unreachable,
17 };
18 std.debug.assert(a != 0 or b != 0);
19
20 // if one of them is zero, the other is returned
21 if (a == 0) return b;
22 if (b == 0) return a;
23
24 // init vars
25 var x: @TypeOf(a, b) = a;
26 var y: @TypeOf(a, b) = b;
27 var m: @TypeOf(a, b) = a;
28
29 // using the Euclidean algorithm (https://mathworld.wolfram.com/EuclideanAlgorithm.html)
30 while (y != 0) {
31 m = x % y;
32 x = y;
33 y = m;
34 }
35 return x;
36}
37
38test "gcd" {
39 try expectEqual(gcd(0, 5), 5);
40 try expectEqual(gcd(5, 0), 5);
41 try expectEqual(gcd(8, 12), 4);
42 try expectEqual(gcd(12, 8), 4);
43 try expectEqual(gcd(33, 77), 11);
44 try expectEqual(gcd(77, 33), 11);
45 try expectEqual(gcd(49865, 69811), 9973);
46 try expectEqual(gcd(300_000, 2_300_000), 100_000);
47 try expectEqual(gcd(90000000_000_000_000_000_000, 2), 2);
48}