ScaLAPACK  2.0.2
ScaLAPACK: Scalable Linear Algebra PACKage
PB_Clcm.c
Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------
00002 *
00003 *  -- PBLAS auxiliary routine (version 2.0) --
00004 *     University of Tennessee, Knoxville, Oak Ridge National Laboratory,
00005 *     and University of California, Berkeley.
00006 *     April 1, 1998
00007 *
00008 *  ---------------------------------------------------------------------
00009 */
00010 /*
00011 *  Include files
00012 */
00013 #include "../pblas.h"
00014 #include "../PBpblas.h"
00015 #include "../PBtools.h"
00016 #include "../PBblacs.h"
00017 #include "../PBblas.h"
00018 
00019 #ifdef __STDC__
00020 int PB_Clcm( int M, int N )
00021 #else
00022 int PB_Clcm( M, N )
00023 /*
00024 *  .. Scalar Arguments ..
00025 */
00026    int            M, N;
00027 #endif
00028 {
00029 /*
00030 *  Purpose
00031 *  =======
00032 *
00033 *  PB_Clcm computes and returns the Least Common Multiple  (LCM)  of two
00034 *  positive integers M and N. In fact, the routine computes the Greatest
00035 *  Common Divisor (GCD) and use the property that M*N = GCD*LCM.
00036 *
00037 *  Arguments
00038 *  =========
00039 *
00040 *  M       (input) INTEGER
00041 *          On entry, M must be at least zero.
00042 *
00043 *  N       (input) INTEGER
00044 *          On entry, N must be at least zero.
00045 *
00046 *  -- Written on April 1, 1998 by
00047 *     Antoine Petitet, University of Tennessee, Knoxville 37996, USA.
00048 *
00049 *  ---------------------------------------------------------------------
00050 */
00051 /*
00052 *  .. Local Scalars ..
00053 */
00054    int            gcd=1, m_val, n_val, t;
00055 /* ..
00056 *  .. Executable Statements ..
00057 *
00058 */
00059    if( M > N ) { m_val = N; n_val = M; }
00060    else        { m_val = M; n_val = N; }
00061 
00062    while( m_val > 0 )
00063    {
00064       while( !( m_val & 1 ) )
00065       {
00066 /*
00067 *  m is even
00068 */
00069          m_val >>= 1;
00070 /*
00071 *  if n is odd, gcd( m, n ) = gcd( m / 2, n )
00072 */
00073          if( !( n_val & 1 ) )
00074          {
00075 /*
00076 *  otherwise gcd( m, n ) = 2 * gcd( m / 2, n / 2 )
00077 */
00078             n_val >>= 1;
00079             gcd   <<= 1;
00080          }
00081       }
00082 /*
00083 *  m is odd now. If n is odd, gcd( m, n ) = gcd( m, ( m - n ) / 2 ).
00084 *  Otherwise, gcd( m, n ) = gcd ( m, n / 2 ).
00085 */
00086       n_val -= ( n_val & 1 ) ? m_val : 0;
00087       n_val >>= 1;
00088       while( n_val >= m_val )
00089       {
00090 /*
00091 *  If n is odd, gcd( m, n ) = gcd( m, ( m - n ) / 2 ).
00092 *  Otherwise, gcd( m, n ) = gcd ( m, n / 2 )
00093 */
00094         n_val -= ( n_val & 1 ) ? m_val : 0;
00095         n_val >>= 1;
00096       }
00097 /*
00098 *  n < m, gcd( m, n ) = gcd( n, m )
00099 */
00100       t     = n_val;
00101       n_val = m_val;
00102       m_val = t;
00103    }
00104    return ( ( M * N ) / ( n_val * gcd ) );
00105 /*
00106 *  End of PB_Clcm
00107 */
00108 }