Created
December 11, 2019 19:07
-
-
Save falkreon/17d3ce5bb51f98e5ffb25f442d1d00e2 to your computer and use it in GitHub Desktop.
Fraction shenanigans
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** 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