85

What is the most efficient way to calculate the least common multiple of two integers?

I just came up with this, but it definitely leaves something to be desired.

int n=7, m=4, n1=n, m1=m;

while( m1 != n1 ){
    if( m1 > n1 )
        n1 += n;
    else 
        m1 += m;
}

System.out.println( "lcm is " + m1 );
General Grievance
  • 4,555
  • 31
  • 31
  • 45
farm ostrich
  • 5,881
  • 14
  • 55
  • 81
  • note that in case n and m are coprime, your loop iterates m + n - 2 times. which isn't good for large numbers compared to [other solutions](https://en.wikipedia.org/wiki/Least_common_multiple#Calculation). – Dariush Mazlumi May 14 '22 at 09:56

17 Answers17

163

The least common multiple (lcm) of a and b is their product divided by their greatest common divisor (gcd) ( i.e. lcm(a, b) = ab/gcd(a,b)).

So, the question becomes, how to find the gcd? The Euclidean algorithm is generally how the gcd is computed. The direct implementation of the classic algorithm is efficient, but there are variations that take advantage of binary arithmetic to do a little better. See Knuth's "The Art of Computer Programming" Volume 2, "Seminumerical Algorithms" § 4.5.2.

Sled
  • 18,541
  • 27
  • 119
  • 168
John D. Cook
  • 29,517
  • 10
  • 67
  • 94
  • 106
    Yes, LCM using GCD is fast and easy to code. One small but important detail: in order to avoid overflows, calculate the final result like this: `lcm = a / gcd * b` instead of `lcm = a * b / gcd`. – Bolo Jul 01 '10 at 01:41
  • 8
    @Bolo - if you are "worried" about overflow, you should be using `long` or in other circumstance even `BigInteger`. The LCM of two `int` values may be a `long`. – Stephen C Jul 01 '10 at 01:47
  • 20
    @Stephen C With Bolo's approach the LCM can be computed without overflow if it can be represented. There is no need to use a bigger and slower number type just for the multiplication. – starblue Jul 01 '10 at 04:39
  • 3
    @starblue - but conversely, there is nothing in the question that the LCM *can* be represented as an `int`. And we know for a fact that for certain values of `m` and `n` it cannot. My point is, that if you worry about overflow in the calculation you should *also* worry about overflow in the final result. – Stephen C Jul 01 '10 at 05:29
  • 13
    @Stephen C It may happen that the two input integers are of order O(N) and their LCM is of order O(N). In the original approach the intermediate result is of order O(N^2), while in the modified one it's only O(N). Example: p = 2^31 - 1 = 2147483647, m = 2*p, n = 3*p. Their LCM = 6*p, these are not very large numbers (`long` can represent integers up to 2^63 - 1 = 9223372036854775807), but the original approach will overflow anyway (the intermediate value is 6*p*p). A simple reordering can greatly improve the algorithm's applicability, regardless of the type (`short`, `int`, or `long`). – Bolo Jul 01 '10 at 09:55
  • 2
    @Bolo - true, but *also* changing the type of the result to `long` will increase its applicability *even further*. It is not hard to find coprime `m` and `n` that are less than `2^31` and `LCM(m, n)` (i.e. `m * n`) is greater than `2^31`. – Stephen C Jul 01 '10 at 10:41
  • 3
    @Stephen C Of course for fixed size integers the result of most operations can overflow. That's a given and one always has to choose an appropriately sized number type so that overflow doesn't occur. The point is that with Bolo's approach the internal computation for the LCM doesn't overflow. – starblue Jul 01 '10 at 11:45
  • @starblue - I know that. I accept that. I said that I accepted that. What is your point? – Stephen C Jul 01 '10 at 11:54
  • 2
    @Stephen C - but you kept advocating for using long and seem to pooh-pooh Bolo's very important improvement which avoids many overflow cases. Bolo was right. – Heath Hunnicutt Jul 09 '10 at 16:53
  • @Heath - if you read the entire thread of comments, it should be absolutely clear that I was not pooh-poohing @Bolo's idea. For example my last response to @Bolo. Read it carefully. – Stephen C Jul 10 '10 at 00:52
  • Well as per i know, most library calculate lcm using gcd, at least in Java. – roottraveller Aug 01 '17 at 14:18
  • Would be nice if you included a reference to an open, online source describing "variations that take advantage of binary arithmetic", instead of just pointing to Knuth's book – Azmisov Feb 01 '22 at 05:39
  • I've benchmarked the binary algorithm from Knuth's book (which actually came from Josef Stein, 1961), and it is actually 2x slower than the more naive implementation using modulo arithmetic. Modulo is fast enough on modern CPUs I suppose that it beats out the repeated subtraction. So I'd recommend that the binary version is no longer "a little better". – Azmisov Feb 01 '22 at 18:24
8

Remember The least common multiple is the least whole number that is a multiple of each of two or more numbers.

If you are trying to figure out the LCM of three integers, follow these steps:

  **Find the LCM of 19, 21, and 42.**

Write the prime factorization for each number. 19 is a prime number. You do not need to factor 19.

21 = 3 × 7
42 = 2 × 3 × 7
19

Repeat each prime factor the greatest number of times it appears in any of the prime factorizations above.

2 × 3 × 7 × 19 = 798

The least common multiple of 21, 42, and 19 is 798.

Jørgen R
  • 10,568
  • 7
  • 42
  • 59
Tai
  • 81
  • 1
  • 1
  • very good if you already need the prime factorization for other calculations – Dean Brown Apr 28 '16 at 16:35
  • 4
    Unfortunately finding the prime factorization of an arbitrary number is a "hard problem" https://en.wikipedia.org/wiki/Prime_factor#Cryptographic_applications – Daniel Kats Aug 25 '17 at 18:03
4

I think that the approach of "reduction by the greatest common divider" should be faster. Start by calculating the GCD (e.g. using Euclid's algorithm), then divide the product of the two numbers by the GCD.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
4

Best solution in C++ below without overflowing

#include <iostream>
using namespace std; 
long long gcd(long long int a, long long int b){        
    if(b==0)
        return a;
    return gcd(b,a%b);
}

long long lcm(long long a,long long b){     
    if(a>b)
        return (a/gcd(a,b))*b;
    else
        return (b/gcd(a,b))*a;    
} 

int main()
{
    long long int a ,b ;
    cin>>a>>b;
    cout<<lcm(a,b)<<endl;        
    return 0;
}
Pang
  • 9,564
  • 146
  • 81
  • 122
Priyansh
  • 1,163
  • 11
  • 28
2

First of all, you have to find the greatest common divisor

for(int i=1; i<=a && i<=b; i++) {

   if (i % a == 0 && i % b == 0)
   {
       gcd = i;
   }

}

After that, using the GCD you can easily find the least common multiple like this

lcm = a / gcd * b;
  • 1
    Would it be faster to start iterating from the lower of the two numbers down to zero? This way, you can avoid having to iterate through the whole set. Something like ```for (int i = a; i >= 0; i--)``` and then if that if statement returns true, you can break out of the loop. – qwerty Apr 01 '20 at 12:55
1

I don't know whether it is optimized or not, but probably the easiest one:

public void lcm(int a, int b)
{
    if (a > b)
    {
        min = b;
        max = a;
    }
    else
    {
        min = a;
        max = b;
    }
    for (i = 1; i < max; i++)
    {
        if ((min*i)%max == 0)
        {
            res = min*i;
            break;
        }
    }
    Console.Write("{0}", res);
}
OhBeWise
  • 5,350
  • 3
  • 32
  • 60
Uday Desiraju
  • 115
  • 1
  • 2
1

Here is a highly efficient approach to find the LCM of two numbers in python.

def gcd(a, b):
    if min(a, b) == 0:
        return max(a, b)
    a_1 = max(a, b) % min(a, b)
    return gcd(a_1, min(a, b))

def lcm(a, b):
    return (a * b) // gcd(a, b)
Algebra
  • 196
  • 2
  • 9
1

Using Euclidean algorithm to find gcd and then calculating the lcm dividing a by the product of gcd and b worked for me.

int euclidgcd(int a, int b){
        if(b==0)
        return a;
        int a_rem = a % b;
        return euclidgcd(b, a_rem);
        }
    
long long lcm(int a, int b) {
        int gcd=euclidgcd(a, b);
        return (a/gcd*b);
        }

int main() {
      int a, b;
      std::cin >> a >> b;
      std::cout << lcm(a, b) << std::endl;
    return 0;           
    }
Vividha
  • 55
  • 7
1

Extending @John D. Cook answer that is also marked answer for this question. ( https://stackoverflow.com/a/3154503/13272795), I am sharing algorithm to find LCM of n numbers, it maybe LCM of 2 numbers or any numbers. Source for this code is this

 int gcd(int a, int b)
 {
     if (b == 0)
         return a;
     return gcd(b, a % b);
 }

  // Returns LCM of array elements
 ll findlcm(int arr[], int n)
 {
    // Initialize result
     ll ans = arr[0];

   // ans contains LCM of arr[0], ..arr[i]
   // after i'th iteration,
       for (int i = 1; i < n; i++)
           ans = arr[i] * ans/gcd(arr[i], ans);
       return ans;
 }
Ankit Mishra
  • 530
  • 8
  • 16
0

Take successive multiples of the larger of the two numbers until the result is a multiple of the smaller.

this might work..

   public int LCM(int x, int y)
   {
       int larger  = x>y? x: y,
           smaller = x>y? y: x,
           candidate = larger ;
       while (candidate % smaller  != 0) candidate += larger ;
       return candidate;
   }
Charles Bretana
  • 143,358
  • 22
  • 150
  • 216
  • This will work okay for small values of x and y, it will have difficulty scaling. – andand Jul 01 '10 at 03:12
  • Dude, this helped in a challenge where Euclid algorithm caused stack-overflow. I guess to scale it up u just treat them as string and have functions for modulo and addition? – Shivam Chawla Apr 14 '18 at 20:41
0

C++ template. Compile time

#include <iostream>

const int lhs = 8, rhs = 12;

template<int n, int mod_lhs=n % lhs, int mod_rhs=n % rhs> struct calc {
  calc() { }
};

template<int n> struct calc<n, 0, 0> {
  calc() { std::cout << n << std::endl; }
};

template<int n, int mod_rhs> struct calc<n, 0, mod_rhs> {
  calc() { }
};

template<int n, int mod_lhs> struct calc <n, mod_lhs, 0> {
  calc() { }
};

template<int n> struct lcm {
  lcm() {
    lcm<n-1>();
    calc<n>();
  }
};

template<> struct lcm<0> {
  lcm() {}
};

int main() {
  lcm<lhs * rhs>();
}
Pang
  • 9,564
  • 146
  • 81
  • 122
mattn
  • 7,571
  • 30
  • 54
0

Product of 2 numbers is equal to LCM * GCD or HCF. So best way to find LCM is to find GCD and divide the product with GCD. That is, LCM(a,b) = (a*b)/GCD(a,b).

User9211
  • 194
  • 1
  • 2
  • 17
nkj
  • 11
0

Euclidean GCD code snippet

int findGCD(int a, int b) {
        if(a < 0 || b < 0)
            return -1;

        if (a == 0)
            return b;
        else if (b == 0)
            return a;
        else 
            return findGCD(b, a % b);
    }
Kamal
  • 309
  • 2
  • 5
0

There is no way more efficient than using a built-in function!

As of Python 3.8 lcm() function has been added in math library. And can be called with folowing signature:

math.lcm(*integers)

Returns the least common multiple of the specified integer arguments. If all arguments are nonzero, then the returned value is the smallest positive integer that is a multiple of all arguments. If any of the arguments is zero, then the returned value is 0. lcm() without arguments returns 1.

Hamza
  • 5,373
  • 3
  • 28
  • 43
0

Since we know the mathematic property which states that "product of LCM and HCF of any two numbers is equal to the product of the two numbers".

lets say X and Y are two integers, then X * Y = HCF(X, Y) * LCM(X, Y)

Now we can find LCM by knowing the HCF, which we can find through Euclidean Algorithm.

  LCM(X, Y) = (X * Y) / HCF(X, Y)

Hope this will be efficient.

import java.util.*;
public class Hello {
    public static int HCF(int X, int Y){
        if(X == 0)return Y;
        return HCF(Y%X, X);
    }
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int X = scanner.nextInt(), Y = scanner.nextInt();
        System.out.print((X * Y) / HCF(X, Y));
    }
}
0

Yes, there are numerous way to calculate LCM such as using GCD (HCF). You can apply prime decomposition such as (optimized/naive) Sieve Eratosthenes or find factor of prime number to compute GCD, which is way more faster than calculate LCM directly. Then as all said above, LCM(X, Y) = (X * Y) / GCD(X, Y)

0

I googled the same question, and found this Stackoverflow page, however I come up with another simple solution using python

def find_lcm(numbers):
    h = max(numbers)

    lcm = h

    def check(l, numbers):
        remainders = [ l%n==0 for n in numbers]
        return all(remainders)

    while (check(lcm, numbers) == False):
        lcm = lcm + h
    
    return lcm


for numbers = [120,150,135,225] it will return 5400

numbers = [120,150,135,225]

print(find_lcm(numbers)) # will print 5400
Barun Ghosh
  • 61
  • 2
  • 7