Skip to content

Instantly share code, notes, and snippets.

@falkreon
Created December 11, 2019 19:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save falkreon/17d3ce5bb51f98e5ffb25f442d1d00e2 to your computer and use it in GitHub Desktop.
Save falkreon/17d3ce5bb51f98e5ffb25f442d1d00e2 to your computer and use it in GitHub Desktop.
Fraction shenanigans
/** Returns the greatest common divisor (factor) of positive integers a and b
* <p>Source: https://en.wikipedia.org/wiki/Binary_GCD_algorithm
*/
private static int gcdUnsigned(int u, int v) {
// simple cases (termination)
if (u == v) return u;
if (u == 0) return v;
if (v == 0) return u;
// look for factors of 2
if ((u&1)==0) { // u is even
if ((v&1)==1) { // v is odd
return gcdUnsigned(u >> 1, v);
} else { // both u and v are even
return gcdUnsigned(u >> 1, v >> 1) << 1;
}
}
if ((v&1)==0) {// u is odd, v is even
return gcdUnsigned(u, v >> 1);
}
// reduce larger argument
if (u > v)
return gcdUnsigned((u - v) >> 1, v);
return gcdUnsigned((v - u) >> 1, u);
}
/** Handles the one additional case for fractions which potentially have -1 as a factor */
public static int gcd(int a, int b) {
int gcd = gcdUnsigned(Math.abs(a), Math.abs(b));
if (a<0 && b<0) { //-1 is also a common factor
return -gcd;
} else {
return gcd;
}
}
/**
* Returns the least common multiple of integer divisors a and b
* <p>Source: https://en.wikipedia.org/wiki/Least_common_multiple#Using_the_greatest_common_divisor
*/
public static int lcm(int a, int b) {
return Math.abs(a*b) / gcd(a, b);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment