/*  gcd.C   */
/*  Copyright 1991 Mountain Math Software  */
/*  All Rights Reserved                    */
#include "gcd.h"
#include "plimits.h"

// Algorithm taken from Knuth, Fundamental Algorithms, page 14 (sec 1.2.1)
int32 GreatestCommonDivisor(int32 m, int32 n)
{

	int32 a,A,b,B,c,d,q,r ;

	if (!n || !m) return 0 ;

	A = b = 1;
	a = B = 0 ;
	c = m ;
	d = n ;

	q = 0 ;
	for(;;) {
		if ( q > 32767) return 0 ;
		q = c / d;
		r = c - q * d ;
		if (!r) break ;
		c = d ;
		d = r ;
		int32 t = A ;
		A = a;
		a = t - q * a ;
		t = B ;
		B = b;
		b = t - q * b ;
	}
	return d ;
}

int32 CheckMultiply(int32 a, int32 b)
{
	double x = a;
	double y = b;
	x = x * y ;
	if (x > INT32_MAX) return 0 ;
	return (int32) x ;
}

int32 LeastCommonMultiple(int32 a, int32 b)
{
	if (!a || !b) return 0 ;
	int32 Gcd = GreatestCommonDivisor(a,b);
	if (!Gcd) return 0 ;
	return CheckMultiply(a/Gcd,b);
}


int32 RemoveCommonFactor(int32& Num, int32& Denom)
{
	int32 CommonFact = GreatestCommonDivisor(Num,Denom);
	if (!CommonFact) return -1 ;
	if (CommonFact > 1) {
		Num /= CommonFact ;
		Denom /= CommonFact ;
	}
	return CommonFact ;
}

