/// <summary>
 /// internal function for negation
 /// </summary>
 private static Fraction Negate(Fraction frac1)
 {
     long iNumerator=-frac1.Numerator;
     long iDenominator=frac1.Denominator;
     return ( new Fraction(iNumerator, iDenominator) );
 }
 private static Fraction Multiply(Fraction frac1, Fraction frac2)
 {
     try
     {
         checked
         {
             long iNumerator=frac1.Numerator*frac2.Numerator;
             long iDenominator=frac1.Denominator*frac2.Denominator;
             return ( new Fraction(iNumerator, iDenominator) );
         }
     }
     catch(OverflowException)
     {
         throw new FractionException("Overflow occurred while performing arithemetic operation");
     }
     catch(Exception)
     {
         throw new FractionException("An error occurred while performing arithemetic operation");
     }
 }
 /// <summary>
 /// The function replicates current Fraction object
 /// </summary>
 public Fraction Duplicate()
 {
     Fraction frac=new Fraction();
     frac.Numerator=Numerator;
     frac.Denominator=Denominator;
     return frac;
 }
 /// <summary>
 /// The function takes a floating point number as an argument 
 /// and returns its corresponding reduced fraction
 /// </summary>
 public static Fraction ToFraction(double dValue)
 {
     try
     {
         checked
         {
             Fraction frac;
             if (dValue%1==0)	// if whole number
             {
                 frac=new Fraction( (long) dValue );
             }
             else
             {
                 double dTemp=dValue;
                 long iMultiple=1;
                 string strTemp=dValue.ToString();
                 while ( strTemp.IndexOf("E")>0 )	// if in the form like 12E-9
                 {
                     dTemp*=10;
                     iMultiple*=10;
                     strTemp=dTemp.ToString();
                 }
                 int i=0;
                 while ( strTemp[i]!='.' )
                     i++;
                 int iDigitsAfterDecimal=strTemp.Length-i-1;
                 while ( iDigitsAfterDecimal>0  )
                 {
                     dTemp*=10;
                     iMultiple*=10;
                     iDigitsAfterDecimal--;
                 }
                 frac=new Fraction( (int)Math.Round(dTemp) , iMultiple );
             }
             return frac;
         }
     }
     catch(OverflowException)
     {
         throw new FractionException("Conversion not possible due to overflow");
     }
     catch(Exception)
     {
         throw new FractionException("Conversion not possible");
     }
 }
        /// <summary>
        /// The function reduces(simplifies) a Fraction object by dividing both its numerator 
        /// and denominator by their GCD
        /// </summary>
        public static void ReduceFraction(Fraction frac)
        {
            try
            {
                if (frac.Numerator==0)
                {
                    frac.Denominator=1;
                    return;
                }

                long iGCD=GCD(frac.Numerator, frac.Denominator);
                frac.Numerator/=iGCD;
                frac.Denominator/=iGCD;

                if ( frac.Denominator<0 )	// if -ve sign in denominator
                {
                    //pass -ve sign to numerator
                    frac.Numerator*=-1;
                    frac.Denominator*=-1;
                }
            } // end try
            catch(Exception exp)
            {
                throw new FractionException("Cannot reduce Fraction: " + exp.Message);
            }
        }
        /// <summary>
        /// The function returns the inverse of a Fraction object
        /// </summary>
        public static Fraction Inverse(Fraction frac1)
        {
            if (frac1.Numerator==0)
                throw new FractionException("Operation not possible (Denominator cannot be assigned a ZERO Value)");

            long iNumerator=frac1.Denominator;
            long iDenominator=frac1.Numerator;
            return ( new Fraction(iNumerator, iDenominator));
        }