Skip to content

Commit 909a77c

Browse files
authored
Create GCD.swift
Binary GCD algorithm
1 parent 4a6730b commit 909a77c

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

Sources/IntegerUtilities/GCD.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//===--- GCD.swift --------------------------------------------*- swift -*-===//
2+
//
3+
// This source file is part of the Swift Numerics open source project
4+
//
5+
// Copyright (c) 2021 Apple Inc. and the Swift Numerics project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
//
10+
//===----------------------------------------------------------------------===//
11+
12+
extension BinaryInteger {
13+
14+
/// The greatest common divisor of `a` and `b`.
15+
///
16+
/// If both inputs are zero, the result is zero.
17+
@inlinable
18+
public static func gcd(_ a: Self, _ b: Self) -> Self {
19+
var x = a.magnitude
20+
var y = b.magnitude
21+
22+
if x == 0 { return Self(y) }
23+
if y == 0 { return Self(x) }
24+
25+
let xtz = x.trailingZeroBitCount
26+
let ytz = y.trailingZeroBitCount
27+
28+
x >>= xtz
29+
y >>= ytz
30+
31+
// The binary GCD algorithm
32+
//
33+
// At the top of the loop both x and y are odd. Each pass removes at least
34+
// one low-order bit from the larger of the two, so the number of iterations
35+
// is bounded by the sum of the bit-widths of the inputs.
36+
while x != 0 {
37+
if x < y { swap(&x, &y) }
38+
x -= y
39+
x >>= x.trailingZeroBitCount
40+
}
41+
42+
return Self(y << min(xtz, ytz))
43+
}
44+
}

0 commit comments

Comments
 (0)