Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace SimpleRational
- {
- public class Rational
- {
- private int _numerator = 0;
- private int _denominator = 1;
- // コンストラクタ
- public Rational(int int_value)
- {
- set(int_value, 1);
- }
- public Rational(int new_numerator, int new_denominator)
- {
- set(new_numerator, new_denominator);
- }
- // アクセサ
- public void set(int new_numerator, int new_denominator)
- {
- if (new_denominator == 0)
- {
- throw new ArithmeticException("Denominator must not be 0");
- }
- _numerator = new_numerator;
- _denominator = new_denominator;
- }
- public int numerator()
- {
- return _numerator;
- }
- public void numerator(int new_numerator)
- {
- _numerator = new_numerator;
- }
- public int denominator()
- {
- return _denominator;
- }
- public void denominator(int new_denominator)
- {
- if (new_denominator == 0)
- {
- throw new ArithmeticException("Denominator must not be 0");
- }
- _denominator = new_denominator;
- }
- // ---------- 補助関数 ----------
- // 最大公約数
- public static int gcd(int v1, int v2)
- {
- int tmp;
- // どちらかが0だったら即座に終了
- if (v1 == 0 || v2 == 0) return 0;
- // 正の値にしておく
- if (v1 < 0) v1 = -v1;
- if (v2 < 0) v2 = -v2;
- // v1の方を大きくしておく
- if (v2 > v1)
- {
- tmp = v1; v1 = v2; v2 = tmp;
- }
- for (; ; )
- {
- tmp = v1 % v2;
- if (tmp == 0) return v2;
- v1 = v2; v2 = tmp;
- }
- }
- // 通分する
- private void _fix_denominator(Rational other)
- {
- int tmp = _denominator;
- _numerator *= other._denominator;
- _denominator *= other._denominator;
- other._numerator *= tmp;
- other._denominator *= tmp;
- }
- // 正規化
- // ●分子・分母を約分する
- // ●負の符号が分母についている場合、分子にのみつけるようにする
- // ●値が0である場合は「0/1」にする
- private void _regularize()
- {
- int divisor = Math.Sign(_denominator) * gcd(_numerator, _denominator);
- if (divisor == 0)
- {
- // 分子が0の場合
- _numerator = 0;
- _denominator = 1;
- }
- else
- {
- _numerator /= divisor;
- _denominator /= divisor;
- }
- }
- // ---------- 比較 ----------
- public static bool operator ==(Rational r1, Rational r2)
- {
- r1._regularize();
- r2._regularize();
- return (r1._numerator == r2._numerator && r1._denominator == r2._denominator);
- }
- public static bool operator !=(Rational r1, Rational r2)
- {
- return (r1 != r2);
- }
- public static bool operator <(Rational r1, Rational r2)
- {
- r1._fix_denominator(r2);
- return (r1.numerator() < r2.numerator());
- }
- public static bool operator >(Rational r1, Rational r2)
- {
- return (r2 < r1);
- }
- // 以下、他の関数やクラスに使ってもらう際の補助関数
- public override bool Equals(object obj)
- {
- if (obj.GetType() == this.GetType())
- {
- return (this == (Rational)obj);
- }
- return false;
- }
- public override int GetHashCode()
- {
- return (_numerator | (_denominator << 16));
- }
- // ---------- 型変換 ----------
- public static explicit operator double(Rational r)
- {
- return (double)r._numerator / (double)r._denominator;
- }
- public static explicit operator float(Rational r)
- {
- return (float)r._numerator / (float)r._denominator;
- }
- // ---------- 加減乗除 ----------
- public static Rational operator +(Rational r) // 単項演算子
- {
- // 単に自分のコピーを作ればよい
- return new Rational(r._numerator, r._denominator);
- }
- public static Rational operator -(Rational r) // 単項演算子
- {
- return new Rational(-r._numerator, r._denominator);
- }
- public static Rational operator +(Rational r1, Rational r2) // 二項演算子
- {
- r1._fix_denominator(r2);
- return new Rational(r1._numerator + r2._numerator, r1._denominator);
- }
- public static Rational operator -(Rational r1, Rational r2) // 二項演算子
- {
- r1._fix_denominator(r2);
- return new Rational(r1._numerator - r2._numerator, r1._denominator);
- }
- public static Rational operator *(Rational r1, Rational r2)
- {
- return new Rational(r1._numerator * r2._numerator, r1._denominator * r2._denominator);
- }
- public static Rational operator /(Rational r1, Rational r2)
- {
- if (r2._numerator == 0)
- {
- throw new DivideByZeroException();
- }
- return new Rational(r1._numerator * r2._denominator, r1._denominator * r2._numerator);
- }
- // ユーティリティ
- public override string ToString()
- {
- _regularize();
- if (_denominator == 1) return _numerator.ToString();
- return string.Format("({0}/{1})", _numerator, _denominator);
- }
- }
- }
Add Comment
Please, Sign In to add comment