-2

How is the gcd function below working I do not understand what the ger varible does. Also what is the lcm varible doing I find this function hard to understand I am not good at math.



long lcm,hcf = 0;
    long i=1;
    // This sets ger to max(a,b) - why?
    long ger=a>b?a:b;
    // This would return a wrong result if a == b
    // that never happens here, though
    while(i<ger)
    {
        if((a%i==0) && (b%i==0))
            hcf=i;
        i++;
    }
    lcm=(a*b)/hcf;
    return lcm;



Run Usb
  • 1
  • 1

2 Answers2

1

Unfortunately, this is not a very good implementation of finding the Greatest Common Divisor (GCD). I suggest you look up Euclid's method on WikiPedia.

The way the above works is the program continues to divide both numbers by increasing values of i starting with 1. When both a and b are divisible by i, i is assigned to hcf and the loop continues until i exceeds the larger of a and b. The last assignment to hcf is the GCD.

The Least Common Multiple (LCM) is the smallest number that is divisible by both a and b and is computed mathematically as the product of a and b divided by their greatest common divisor.

The % sign in java means for a % i get the remainder. So if the remainder of both a and b when divided by i is zero, then i would be the GCD.

Updated Answer

Although I don't like the above approach, the idea can still be improved in several ways which I will identify and explain here. (Euclid's method would still be better).

  1. Don't find the largest of a and b, find the smallest. Why keep iterating from or toward a larger termination point? No value larger than v will ever divide v. So stop as soon as the smaller value is exceeded.

  2. Don't iterate starting at 1 and increasing toward the smaller number. Start with the smaller number and decrease until you hit the first successful test. That would be the GCD of both numbers.

  3. Don't do this (a*b)/gcd to get the LCM. It is possible that a*b could overflow a long. Since it is known that the gcd divides both, divide one of the values by gcd and then multiply by the other.

Here is the code with the changes.

public static long lcm(long a, long b) {
    // find min(a,b)
    long hcf = a<b?a:b;
    // just loop and decrement
    for (;; hcf--) {
        if((a%hcf==0) && (b%hcf==0)) {
            // guaranteed to exit
            // when hcf reaches 1
            break;
        }
    }
    return a*(b/hcf);
}
WJS
  • 36,363
  • 4
  • 24
  • 39
0

1) I do not understand what the ger variable does?

long ger = a > b ? a : b; is supposed to set an upper bound for the following while-loop.

However

  • as you've already noted, it's wrong in combination with the while-condition while(i < ger) (wrong result when a == b)
  • and actually taking the maximum of the two integers is not making any sense as the upper bound should be the min(a, b) as the greatest common divisor of them cannot be larger than their minimum.

The while-loop finds the GCD by finding incrementally the largest divisor i (= GCD) which divides a and b without any remainder, i.e (a % i == 0) && (b % i == 0).

2) Also what is the lcm variable doing?

The lcm variable is the Least Common Multiple of two integers and can be computed using the Greatest Common Divisor (GCD = HCF). Simply put, it's just a formula.

Conclusion

So, the purpose of this function is to compute the LCM by first computing the GCD and then applying the formula: a × b = gcd(a, b) × lcm(a, b) Proof ⟶ lcm(a, b) = a × b / gcd(a, b)

Ivo Mori
  • 2,177
  • 5
  • 24
  • 35