bate's blog

調べたこと実装したことなどを取りとめもなく書きます。

C++/CLIでやったことをC#で1

分数のクラスを書いた。
コメント書けない病の克服に至らず。

using System;
using System.Collections;

namespace MyMath
{
	/// <summary>
	/// 分数クラスです。
	/// </summary>
	public class Fraction
	{
		private int m_numerator;
		private int m_denominator;
		private int m_sign;	// +:1, -:0

		// コンストラクタ
		public Fraction( int num, int dem )
		{
			this.m_numerator = num;
			this.m_denominator = dem;

			Sign();
		}

		public Fraction() : this( 0, 1 )
		{
			Sign();
		}

		~Fraction()
		{ }

		public int GetNumerator()
		{
			return this.m_numerator;
		}
		public int GetDenominator()
		{
			return this.m_denominator;
		}
		public void SetNumerator( int num )
		{
			this.m_numerator = num;
		}
		public void SetDenominator( int den )
		{
			this.m_denominator = den;
		}

		public override string ToString()
		{
			//return ( this.m_numerator + "/" + this.m_denominator );
			return ( string.Format( "{0}/{1}", this.m_numerator, this.m_denominator ) );
		}
		public void Disp()
		{
			Console.WriteLine( "{0}/{1}", m_numerator, m_denominator );
		}

		// 符号について
		public void Sign()
		{
			// 符号を分子に
			if( this.m_denominator < 0 )
			{
				this.m_numerator *= -1;
				this.m_denominator *= -1;
			}

			// +:1, -:0
			this.m_sign = ( ( this.m_numerator < 0 ) ? 0 : 1 );
		}

		// 約分
		public Fraction Reduction()
		{
			Sign();

			if( 0 == m_sign )
				m_numerator *= -1;

			// 分子が0なら計算しない
			if( 0 == m_numerator )
			{
				m_denominator = 1;
				return new Fraction( m_numerator, m_denominator );
			}

			ArrayList n_factor = Function.Factorization( m_numerator );
			ArrayList d_factor = Function.Factorization( m_denominator );

			int j = 0, save_index = 0;
			for( int i = 0; i < n_factor.Count; ++i )
			{
				j = save_index;
				while( j < d_factor.Count )
				{
					if( (int)n_factor[i] == (int)d_factor[j] )
					{
						n_factor[i] = d_factor[j] = 1;
						save_index = j+1;

						break;
					}

					++j;
				}
			}

			int num = 1;
			int den = 1;
			for( int i = 0; i < n_factor.Count; ++i )
				num *= (int)n_factor[i];
			for( int i = 0; i < d_factor.Count; ++i )
				den *= (int)d_factor[i];

			if( 0 == m_sign ) num *= -1;

			return new Fraction( num, den );

		}

		// 演算子
		public static Fraction operator+( Fraction a, Fraction b )
		{
			Fraction t = new Fraction(
				a.GetNumerator()*b.GetDenominator() + a.GetDenominator()*b.GetNumerator(),
				a.GetDenominator()*b.GetDenominator()
				);
			t = t.Reduction();
			return t;
		}

		public static Fraction operator-( Fraction a, Fraction b )
		{
			Fraction t =new Fraction(
				a.GetNumerator()*b.GetDenominator() - b.GetNumerator()*a.GetDenominator(),
				a.GetDenominator()*b.GetDenominator()
				);
			t = t.Reduction();
			return t;
		}

		public static Fraction operator*( Fraction a, Fraction b )
		{
			Fraction t = new Fraction(
				a.GetNumerator()*b.GetNumerator(),
				a.GetDenominator()*b.GetDenominator()
				);
			t = t.Reduction();
			return t;
		}

		public static Fraction operator/( Fraction a, Fraction b )
		{
			Fraction t = new Fraction(
				a.GetNumerator()*b.GetDenominator(),
				a.GetDenominator()*b.GetNumerator()
				);
			t = t.Reduction();
			return t;
		}
	}
}