using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Sample { /// /// 有理数。 /// public struct Rational : IComparable { #region フィールド int num; int denom; #endregion #region 補助関数 /// /// 最大公約数を求める。 /// /// オペランド1。 /// オペランド2。 /// public static int Gdc(int a, int b) { int x = a; int y = b; if (x < 0) x = -x; if (y < 0) y = -y; for (; ; ) { int q = x / y; int r = x - q * y; if (r == 0) break; x = y; y = r; } return y; } /// /// 通分する。 /// /// 分子。 /// 分母。 public static void Reduce(ref int num, ref int denom) { var gdc = Gdc(num, denom); num /= gdc; denom /= gdc; } #endregion public Rational(int num, int denom) { Reduce(ref num, ref denom); this.num = num; this.denom = denom; } public int Numerator { get { return num; } set { num = value; } } public int Denominator { get { return denom; } set { denom = value; } } public static implicit operator Rational(int x) { return new Rational(x, 1); } public static explicit operator double(Rational x) { if (x.num == 0) return 0; return (double)x.num / (double)x.denom; } public static Rational operator +(Rational x) { return new Rational(x.num, x.denom); } public static Rational operator -(Rational x) { return new Rational(-x.num, x.denom); } public static Rational operator +(Rational x, Rational y) { var num = x.num * y.denom + x.denom * y.num; var denom = x.denom * y.denom; return new Rational(num, denom); } public static Rational operator -(Rational x, Rational y) { var num = x.num * y.denom - x.denom * y.num; var denom = x.denom * y.denom; return new Rational(num, denom); } public static Rational operator *(Rational x, Rational y) { var num = x.num * y.num; var denom = x.denom * y.denom; return new Rational(num, denom); } public static Rational operator /(Rational x, Rational y) { var num = x.num * y.denom; var denom = x.denom * y.num; return new Rational(num, denom); } public override string ToString() { return string.Format("({0}/{1})", this.num, this.denom); } #region IComparable メンバ public int CompareTo(Rational other) { return ((double)this).CompareTo((double)other); } #endregion } public static class RationalExtensions { public static Rational Over(this int x, int y) { return new Rational(x, y); } } }