Skip to content

Commit 19445fc

Browse files
authored
Merge pull request #4940 from Darredevil/issue-4125
Fix Issue 4125 - std.numeric.gcd can use a binary GCD
2 parents 43a4d2c + 6b4c258 commit 19445fc

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

std/numeric.d

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2572,15 +2572,16 @@ GapWeightedSimilarityIncremental!(R, F) gapWeightedSimilarityIncremental(R, F)
25722572

25732573
/**
25742574
Computes the greatest common divisor of $(D a) and $(D b) by using
2575-
Euclid's algorithm.
2575+
an efficient algorithm such as $(HTTPS en.wikipedia.org/wiki/Euclidean_algorithm, Euclid's)
2576+
or $(HTTPS en.wikipedia.org/wiki/Binary_GCD_algorithm, Stein's) algorithm.
25762577
*/
25772578
T gcd(T)(T a, T b)
25782579
{
25792580
static if (is(T == const) || is(T == immutable))
25802581
{
25812582
return gcd!(Unqual!T)(a, b);
25822583
}
2583-
else
2584+
else version(DigitalMars)
25842585
{
25852586
static if (T.min < 0)
25862587
{
@@ -2594,6 +2595,26 @@ T gcd(T)(T a, T b)
25942595
}
25952596
return a;
25962597
}
2598+
else
2599+
{
2600+
if (a == 0)
2601+
return b;
2602+
if (b == 0)
2603+
return a;
2604+
2605+
immutable uint shift = bsf(a | b);
2606+
a >>= a.bsf;
2607+
2608+
do
2609+
{
2610+
b >>= b.bsf;
2611+
if (a > b)
2612+
swap(a, b);
2613+
b -= a;
2614+
} while (b);
2615+
2616+
return a << shift;
2617+
}
25972618
}
25982619

25992620
///

0 commit comments

Comments
 (0)