/*
* Author: Syed Mehroz Alam
* Email: smehrozalam@yahoo.com
* URL: Programming Home "http://www.geocities.com/smehrozalam/"
* Date: 6/20/2004
* Time: 4:46 PM
*
*/
using System;
namespace Mehroz
{
///
/// Classes Contained:
/// MatrixApplication
/// Matrix (version 1.1)
/// MatrixException
/// Fraction (Version 2.0)
/// FractionException
///
///
/// class name: Application
/// The class demonstrates the Matrix class
///
public class MatrixApplication
{
public static void Main()
{
try
{
Console.WriteLine("Press 'm' for Matrix demo, 'e' for Equation Solver demo");
if ( Console.ReadLine().ToLower()=="e" )
EquationSolver();
else
MatrixDemo();
Console.WriteLine("\n\nPress any key to exit");
} //end try
catch (MatrixException exp)
{
Console.WriteLine("\nInternal Matrix Error: " + exp.Message);
}
catch (FractionException exp)
{
Console.WriteLine("\nInternal Fraction Error: " + exp.Message);
}
catch (Exception exp)
{
Console.WriteLine("\nSystem Error: " + exp);//.Message);
}
Console.ReadLine();
}
public static void MatrixDemo()
{
Console.WriteLine("Enter no. of Rows: ");
int iRows=Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter no. of Cols: ");
int iCols=Convert.ToInt32(Console.ReadLine());
Matrix m1=new Matrix(iRows,iCols);
Matrix m2=new Matrix(iRows,iCols);
System.Random rnd=new System.Random();
for ( int i=0;i0 && nn0 && j
public class Matrix
{
///
/// Class attributes/members
///
int m_iRows;
int m_iCols;
Fraction[,] m_iElement;
///
/// Constructors
///
public Matrix(Fraction[,] elements)
{
m_iElement=elements;
m_iRows=elements.GetLength(0);
m_iCols=elements.GetLength(1);
}
public Matrix(int[,] elements)
{
m_iRows=elements.GetLength(0);
m_iCols=elements.GetLength(1);;
m_iElement=new Fraction[m_iRows,m_iCols];
for(int i=0;i
/// Properites
///
public int Rows
{
get { return m_iRows; }
}
public int Cols
{
get { return m_iCols; }
}
///
/// Indexer
///
public Fraction this[int iRow, int iCol] // matrix's index starts at 0,0
{
get { return GetElement(iRow,iCol); }
set { SetElement(iRow,iCol,value); }
}
///
/// Internal functions for getting/setting values
///
private Fraction GetElement(int iRow, int iCol)
{
if ( iRow<0 || iRow>Rows-1 || iCol<0 || iCol>Cols-1 )
throw new MatrixException("Invalid index specified");
return m_iElement[iRow,iCol];
}
private void SetElement(int iRow, int iCol, Fraction value)
{
if ( iRow<0 || iRow>Rows-1 || iCol<0 || iCol>Cols-1 )
throw new MatrixException("Invalid index specified");
m_iElement[iRow,iCol]=value.Duplicate();
}
///
/// The function returns the current Matrix object as a string
///
public override string ToString()
{
string str="";
for (int i=0;i
/// The function return the Minor of element[Row,Col] of a Matrix object
///
public static Matrix Minor(Matrix matrix, int iRow, int iCol)
{
Matrix minor=new Matrix(matrix.Rows-1, matrix.Cols-1);
int m=0,n=0;
for (int i=0;i
/// The function multiplies the given row of the current matrix object by a Fraction
///
public void MultiplyRow(int iRow, Fraction frac)
{
for (int j=0;j
/// The function multiplies the given row of the current matrix object by an integer
///
public void MultiplyRow(int iRow, int iNo)
{
this.MultiplyRow(iRow, new Fraction(iNo));
}
///
/// The function multiplies the given row of the current matrix object by a double
///
public void MultiplyRow(int iRow, double dbl)
{
this.MultiplyRow(iRow, Fraction.ToFraction(dbl));
}
///
/// The function adds two rows for current matrix object
/// It performs the following calculation:
/// iTargetRow = iTargetRow + iMultiple*iSecondRow
///
public void AddRow(int iTargetRow, int iSecondRow, Fraction iMultiple)
{
for (int j=0;j
/// The function interchanges two rows of the current matrix object
///
public void InterchangeRow(int iRow1, int iRow2)
{
for (int j=0;j
/// The function concatenates the two given matrices column-wise
/// it can be helpful in a equation solver class where the augmented matrix is obtained by concatenation
///
public static Matrix Concatenate(Matrix matrix1, Matrix matrix2)
{
if (matrix1.Rows!=matrix2.Rows)
throw new MatrixException("Concatenation not possible");
Matrix matrix=new Matrix(matrix1.Rows, matrix1.Cols+matrix2.Cols );
for (int i=0;i
/// The function returns the determinent of the current Matrix object as Fraction
/// It computes the determinent by reducing the matrix to reduced echelon form using row operations
/// The function is very fast and efficient but may raise overflow exceptions in some cases.
/// In such cases use the Determinent() function which computes determinent in the traditional
/// manner(by using minors)
///
public Fraction DeterminentFast()
{
if (this.Rows!=this.Cols)
throw new MatrixException("Determinent of a non-square matrix doesn't exist");
Fraction det=new Fraction(1);
try
{
Matrix ReducedEchelonMatrix=this.Duplicate();
for (int i=0;i=0;j--)
{
ReducedEchelonMatrix.AddRow( j, i, -ReducedEchelonMatrix[j,i]);
}
}
return det;
}
catch(Exception)
{
throw new MatrixException("Determinent of the given matrix could not be calculated");
}
}
///
/// The function returns the determinent of the current Matrix object as Fraction
/// It computes the determinent in the traditional way (i.e. using minors)
/// It can be much slower(due to recursion) if the given matrix has order greater than 6
/// Try using DeterminentFast() function if the order of matrix is greater than 6
///
public Fraction Determinent()
{
return Determinent(this);
}
///
/// The helper function for the above Determinent() method
/// it calls itself recursively and computes determinent using minors
///
private Fraction Determinent(Matrix matrix)
{
Fraction det=new Fraction(0);
if (matrix.Rows!=matrix.Cols)
throw new MatrixException("Determinent of a non-square matrix doesn't exist");
if (matrix.Rows==1)
return matrix[0,0];
for (int j=0;j
/// The function returns the Echelon form of the current matrix
///
public Matrix EchelonForm()
{
try
{
Matrix EchelonMatrix=this.Duplicate();
for (int i=0;i
/// The function returns the reduced echelon form of the current matrix
///
public Matrix ReducedEchelonForm()
{
try
{
Matrix ReducedEchelonMatrix=this.Duplicate();
for (int i=0;i=0;j--)
ReducedEchelonMatrix.AddRow( j, i, -ReducedEchelonMatrix[j,i]);
}
return ReducedEchelonMatrix;
}
catch(Exception)
{
throw new MatrixException("Matrix can not be reduced to Echelon form");
}
}
///
/// The function returns the inverse of the current matrix using Reduced Echelon Form method
/// The function is very fast and efficient but may raise overflow exceptions in some cases.
/// In such cases use the Inverse() method which computes inverse in the traditional way(using adjoint).
///
public Matrix InverseFast()
{
if ( this.DeterminentFast()==0 )
throw new MatrixException("Inverse of a singular matrix is not possible");
try
{
Matrix IdentityMatrix=Matrix.IdentityMatrix(this.Rows, this.Cols);
Matrix ReducedEchelonMatrix=this.Duplicate();
for (int i=0;i=0;j--)
{
IdentityMatrix.AddRow( j, i, -ReducedEchelonMatrix[j,i]);
ReducedEchelonMatrix.AddRow( j, i, -ReducedEchelonMatrix[j,i]);
}
}
return IdentityMatrix;
}
catch(Exception)
{
throw new MatrixException("Inverse of the given matrix could not be calculated");
}
}
///
/// The function returns the inverse of the current matrix in the traditional way(by adjoint method)
/// It can be much slower if the given matrix has order greater than 6
/// Try using InverseFast() function if the order of matrix is greater than 6
///
public Matrix Inverse()
{
if ( this.Determinent()==0 )
throw new MatrixException("Inverse of a singular matrix is not possible");
return ( this.Adjoint()/this.Determinent() );
}
///
/// The function returns the adjoint of the current matrix
///
public Matrix Adjoint()
{
if (this.Rows!=this.Cols)
throw new MatrixException("Adjoint of a non-square matrix does not exists");
Matrix AdjointMatrix=new Matrix(this.Rows, this.Cols);
for (int i=0;i
/// The function returns the transpose of the current matrix
///
public Matrix Transpose()
{
Matrix TransposeMatrix=new Matrix(this.Cols, this.Rows);
for (int i=0;i
/// The function duplicates the current Matrix object
///
public Matrix Duplicate()
{
Matrix matrix=new Matrix(Rows,Cols);
for (int i=0;i
/// The function returns a Scalar Matrix of dimension ( Row x Col ) and scalar K
///
public static Matrix ScalarMatrix(int iRows, int iCols, int K)
{
Fraction zero=new Fraction(0);
Fraction scalar=new Fraction(K);
Matrix matrix=new Matrix(iRows,iCols);
for (int i=0;i
/// The function returns an identity matrix of dimensions ( Row x Col )
///
public static Matrix IdentityMatrix(int iRows, int iCols)
{
return ScalarMatrix(iRows, iCols, 1);
}
///
/// The function returns a Unit Matrix of dimension ( Row x Col )
///
public static Matrix UnitMatrix(int iRows, int iCols)
{
Fraction temp=new Fraction(1);
Matrix matrix=new Matrix(iRows,iCols);
for (int i=0;i
/// The function returns a Null Matrix of dimension ( Row x Col )
///
public static Matrix NullMatrix(int iRows, int iCols)
{
Fraction temp=new Fraction(0);
Matrix matrix=new Matrix(iRows,iCols);
for (int i=0;i
/// Operators for the Matrix object
/// includes -(unary), and binary opertors such as +,-,*,/
///
public static Matrix operator -(Matrix matrix)
{ return Matrix.Negate(matrix); }
public static Matrix operator +(Matrix matrix1, Matrix matrix2)
{ return Matrix.Add(matrix1, matrix2); }
public static Matrix operator -(Matrix matrix1, Matrix matrix2)
{ return Matrix.Add(matrix1, -matrix2); }
public static Matrix operator *(Matrix matrix1, Matrix matrix2)
{ return Matrix.Multiply(matrix1, matrix2); }
public static Matrix operator *(Matrix matrix1, int iNo)
{ return Matrix.Multiply(matrix1, iNo); }
public static Matrix operator *(Matrix matrix1, double dbl)
{ return Matrix.Multiply(matrix1, Fraction.ToFraction(dbl)); }
public static Matrix operator *(Matrix matrix1, Fraction frac)
{ return Matrix.Multiply(matrix1, frac); }
public static Matrix operator *(int iNo, Matrix matrix1)
{ return Matrix.Multiply(matrix1, iNo); }
public static Matrix operator *(double dbl, Matrix matrix1)
{ return Matrix.Multiply(matrix1, Fraction.ToFraction(dbl)); }
public static Matrix operator *(Fraction frac, Matrix matrix1)
{ return Matrix.Multiply(matrix1, frac); }
public static Matrix operator /(Matrix matrix1, int iNo)
{ return Matrix.Multiply(matrix1, Fraction.Inverse(new Fraction(iNo))); }
public static Matrix operator /(Matrix matrix1, double dbl)
{ return Matrix.Multiply(matrix1, Fraction.Inverse(Fraction.ToFraction(dbl))); }
public static Matrix operator /(Matrix matrix1, Fraction frac)
{ return Matrix.Multiply(matrix1, Fraction.Inverse(frac)); }
///
/// Internal Fucntions for the above operators
///
private static Matrix Negate(Matrix matrix)
{
return Matrix.Multiply(matrix,-1);
}
private static Matrix Add(Matrix matrix1, Matrix matrix2)
{
if (matrix1.Rows!=matrix2.Rows || matrix1.Cols!=matrix2.Cols)
throw new MatrixException("Operation not possible");
Matrix result=new Matrix(matrix1.Rows, matrix1.Cols);
for (int i=0;i
/// Exception class for Matrix class, derived from System.Exception
///
public class MatrixException : Exception
{
public MatrixException() : base()
{}
public MatrixException(string Message) : base(Message)
{}
public MatrixException(string Message, Exception InnerException) : base(Message, InnerException)
{}
} // end class MatrixException
///
/// Class name: Fraction
/// Developed by: Syed Mehroz Alam
/// Email: smehrozalam@yahoo.com
/// URL: Programming Home "http://www.geocities.com/smehrozalam/"
/// Version: 2.0
///
/// What's new in version 2.0:
/// * Changed Numerator and Denominator from Int32(integer) to Int64(long) for increased range
/// * renamed ConvertToString() to (overloaded) ToString()
/// * added the capability of detecting/raising overflow exceptions
/// * Fixed the bug that very small numbers e.g. 0.00000001 could not be converted to fraction
/// * Other minor bugs fixed
///
/// Properties:
/// Numerator: Set/Get value for Numerator
/// Denominator: Set/Get value for Numerator
/// Value: Set an integer value for the fraction
///
/// Constructors:
/// no arguments: initializes fraction as 0/1
/// (Numerator, Denominator): initializes fraction with the given numerator and denominator values
/// (integer): initializes fraction with the given integer value
/// (long): initializes fraction with the given long value
/// (double): initializes fraction with the given double value
/// (string): initializes fraction with the given string value
/// the string can be an in the form of and integer, double or fraction.
/// e.g it can be like "123" or "123.321" or "123/456"
///
/// Public Methods (Description is given with respective methods' definitions)
/// (override) string ToString(Fraction)
/// Fraction ToFraction(string)
/// Fraction ToFraction(double)
/// double ToDouble(Fraction)
/// Fraction Duplicate()
/// Fraction Inverse(integer)
/// Fraction Inverse(Fraction)
/// ReduceFraction(Fraction)
/// Equals(object)
/// GetHashCode()
///
/// Private Methods (Description is given with respective methods' definitions)
/// Initialize(Numerator, Denominator)
/// Fraction Negate(Fraction)
/// Fraction Add(Fraction1, Fraction2)
///
/// Overloaded Operators (overloaded for Fractions, Integers and Doubles)
/// Unary: -
/// Binary: +,-,*,/
/// Relational and Logical Operators: ==,!=,<,>,<=,>=
///
/// Overloaded user-defined conversions
/// Implicit: From double/long/string to Fraction
/// Explicit: From Fraction to double/string
///
public class Fraction
{
///
/// Class attributes/members
///
long m_iNumerator;
long m_iDenominator;
///
/// Constructors
///
public Fraction()
{
Initialize(0,1);
}
public Fraction(long iWholeNumber)
{
Initialize(iWholeNumber, 1);
}
public Fraction(double dDecimalValue)
{
Fraction temp=ToFraction(dDecimalValue);
Initialize(temp.Numerator, temp.Denominator);
}
public Fraction(string strValue)
{
Fraction temp=ToFraction(strValue);
Initialize(temp.Numerator, temp.Denominator);
}
public Fraction(long iNumerator, long iDenominator)
{
Initialize(iNumerator, iDenominator);
}
///
/// Internal function for constructors
///
private void Initialize(long iNumerator, long iDenominator)
{
Numerator=iNumerator;
Denominator=iDenominator;
ReduceFraction(this);
}
///
/// Properites
///
public long Denominator
{
get
{ return m_iDenominator; }
set
{
if (value!=0)
m_iDenominator=value;
else
throw new FractionException("Denominator cannot be assigned a ZERO Value");
}
}
public long Numerator
{
get
{ return m_iNumerator; }
set
{ m_iNumerator=value; }
}
public long Value
{
set
{ m_iNumerator=value;
m_iDenominator=1; }
}
///
/// The function takes a Fraction object and returns its value as double
///
public static double ToDouble(Fraction frac)
{
return ( (double)frac.Numerator/frac.Denominator );
}
///
/// The function returns the current Fraction object as double
///
public double ToDouble()
{
return ( (double)this.Numerator/this.Denominator );
}
///
/// The function returns the current Fraction object as a string
///
public override string ToString()
{
string str;
if ( this.Denominator==1 )
str=this.Numerator.ToString();
else
str=this.Numerator + "/" + this.Denominator;
return str;
}
///
/// The function takes an string as an argument and returns its corresponding reduced fraction
/// the string can be an in the form of and integer, double or fraction.
/// e.g it can be like "123" or "123.321" or "123/456"
///
public static Fraction ToFraction(string strValue)
{
int i;
for (i=0;i
/// The function takes a floating point number as an argument
/// and returns its corresponding reduced fraction
///
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");
}
}
///
/// The function replicates current Fraction object
///
public Fraction Duplicate()
{
Fraction frac=new Fraction();
frac.Numerator=Numerator;
frac.Denominator=Denominator;
return frac;
}
///
/// The function returns the inverse of a Fraction object
///
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));
}
///
/// Operators for the Fraction object
/// includes -(unary), and binary opertors such as +,-,*,/
/// also includes relational and logical operators such as ==,!=,<,>,<=,>=
///
public static Fraction operator -(Fraction frac1)
{ return ( Negate(frac1) ); }
public static Fraction operator +(Fraction frac1, Fraction frac2)
{ return ( Add(frac1 , frac2) ); }
public static Fraction operator +(int iNo, Fraction frac1)
{ return ( Add(frac1 , new Fraction(iNo) ) ); }
public static Fraction operator +(Fraction frac1, int iNo)
{ return ( Add(frac1 , new Fraction(iNo) ) ); }
public static Fraction operator +(double dbl, Fraction frac1)
{ return ( Add(frac1 , Fraction.ToFraction(dbl) ) ); }
public static Fraction operator +(Fraction frac1, double dbl)
{ return ( Add(frac1 , Fraction.ToFraction(dbl) ) ); }
public static Fraction operator -(Fraction frac1, Fraction frac2)
{ return ( Add(frac1 , -frac2) ); }
public static Fraction operator -(int iNo, Fraction frac1)
{ return ( Add(-frac1 , new Fraction(iNo) ) ); }
public static Fraction operator -(Fraction frac1, int iNo)
{ return ( Add(frac1 , -(new Fraction(iNo)) ) ); }
public static Fraction operator -(double dbl, Fraction frac1)
{ return ( Add(-frac1 , Fraction.ToFraction(dbl) ) ); }
public static Fraction operator -(Fraction frac1, double dbl)
{ return ( Add(frac1 , -Fraction.ToFraction(dbl) ) ); }
public static Fraction operator *(Fraction frac1, Fraction frac2)
{ return ( Multiply(frac1 , frac2) ); }
public static Fraction operator *(int iNo, Fraction frac1)
{ return ( Multiply(frac1 , new Fraction(iNo) ) ); }
public static Fraction operator *(Fraction frac1, int iNo)
{ return ( Multiply(frac1 , new Fraction(iNo) ) ); }
public static Fraction operator *(double dbl, Fraction frac1)
{ return ( Multiply(frac1 , Fraction.ToFraction(dbl) ) ); }
public static Fraction operator *(Fraction frac1, double dbl)
{ return ( Multiply(frac1 , Fraction.ToFraction(dbl) ) ); }
public static Fraction operator /(Fraction frac1, Fraction frac2)
{ return ( Multiply( frac1 , Inverse(frac2) ) ); }
public static Fraction operator /(int iNo, Fraction frac1)
{ return ( Multiply( Inverse(frac1) , new Fraction(iNo) ) ); }
public static Fraction operator /(Fraction frac1, int iNo)
{ return ( Multiply( frac1 , Inverse(new Fraction(iNo)) ) ); }
public static Fraction operator /(double dbl, Fraction frac1)
{ return ( Multiply( Inverse(frac1) , Fraction.ToFraction(dbl) ) ); }
public static Fraction operator /(Fraction frac1, double dbl)
{ return ( Multiply( frac1 , Fraction.Inverse( Fraction.ToFraction(dbl) ) ) ); }
public static bool operator ==(Fraction frac1, Fraction frac2)
{ return frac1.Equals(frac2); }
public static bool operator !=(Fraction frac1, Fraction frac2)
{ return ( !frac1.Equals(frac2) ); }
public static bool operator ==(Fraction frac1, int iNo)
{ return frac1.Equals( new Fraction(iNo)); }
public static bool operator !=(Fraction frac1, int iNo)
{ return ( !frac1.Equals( new Fraction(iNo)) ); }
public static bool operator ==(Fraction frac1, double dbl)
{ return frac1.Equals( new Fraction(dbl)); }
public static bool operator !=(Fraction frac1, double dbl)
{ return ( !frac1.Equals( new Fraction(dbl)) ); }
public static bool operator<(Fraction frac1, Fraction frac2)
{ return frac1.Numerator * frac2.Denominator < frac2.Numerator * frac1.Denominator; }
public static bool operator>(Fraction frac1, Fraction frac2)
{ return frac1.Numerator * frac2.Denominator > frac2.Numerator * frac1.Denominator; }
public static bool operator<=(Fraction frac1, Fraction frac2)
{ return frac1.Numerator * frac2.Denominator <= frac2.Numerator * frac1.Denominator; }
public static bool operator>=(Fraction frac1, Fraction frac2)
{ return frac1.Numerator * frac2.Denominator >= frac2.Numerator * frac1.Denominator; }
///
/// checks whether two fractions are equal
///
public override bool Equals(object obj)
{
Fraction frac=(Fraction)obj;
return ( Numerator==frac.Numerator && Denominator==frac.Denominator);
}
///
/// returns a hash code for this fraction
///
public override int GetHashCode()
{
return ( Convert.ToInt32((Numerator ^ Denominator) & 0xFFFFFFFF) ) ;
}
///
/// internal function for negation
///
private static Fraction Negate(Fraction frac1)
{
long iNumerator=-frac1.Numerator;
long iDenominator=frac1.Denominator;
return ( new Fraction(iNumerator, iDenominator) );
}
///
/// internal functions for binary operations
///
private static Fraction Add(Fraction frac1, Fraction frac2)
{
try
{
checked
{
long iNumerator=frac1.Numerator*frac2.Denominator + frac2.Numerator*frac1.Denominator;
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");
}
}
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");
}
}
///
/// The function returns GCD of two numbers (used for reducing a Fraction)
///
private static long GCD(long iNo1, long iNo2)
{
// take absolute values
if (iNo1 < 0) iNo1 = -iNo1;
if (iNo2 < 0) iNo2 = -iNo2;
do
{
if (iNo1 < iNo2)
{
long tmp = iNo1; // swap the two operands
iNo1 = iNo2;
iNo2 = tmp;
}
iNo1 = iNo1 % iNo2;
} while (iNo1 != 0);
return iNo2;
}
///
/// The function reduces(simplifies) a Fraction object by dividing both its numerator
/// and denominator by their GCD
///
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);
}
}
} //end class Fraction
///
/// Exception class for Fraction, derived from System.Exception
///
public class FractionException : Exception
{
public FractionException() : base()
{}
public FractionException(string Message) : base(Message)
{}
public FractionException(string Message, Exception InnerException) : base(Message, InnerException)
{}
} //end class FractionException
} //end namespace Mehroz