Guest User

Untitled

a guest
Jul 17th, 2018
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.84 KB | None | 0 0
  1. namespace SimpleRational
  2. {
  3. public class Rational
  4. {
  5. private int _numerator = 0;
  6. private int _denominator = 1;
  7.  
  8. // コンストラクタ
  9. public Rational(int int_value)
  10. {
  11. set(int_value, 1);
  12. }
  13.  
  14. public Rational(int new_numerator, int new_denominator)
  15. {
  16. set(new_numerator, new_denominator);
  17. }
  18.  
  19. // アクセサ
  20. public void set(int new_numerator, int new_denominator)
  21. {
  22. if (new_denominator == 0)
  23. {
  24. throw new ArithmeticException("Denominator must not be 0");
  25. }
  26.  
  27. _numerator = new_numerator;
  28. _denominator = new_denominator;
  29. }
  30.  
  31. public int numerator()
  32. {
  33. return _numerator;
  34. }
  35.  
  36. public void numerator(int new_numerator)
  37. {
  38. _numerator = new_numerator;
  39. }
  40.  
  41. public int denominator()
  42. {
  43. return _denominator;
  44. }
  45.  
  46. public void denominator(int new_denominator)
  47. {
  48. if (new_denominator == 0)
  49. {
  50. throw new ArithmeticException("Denominator must not be 0");
  51. }
  52. _denominator = new_denominator;
  53. }
  54.  
  55. // ---------- 補助関数 ----------
  56.  
  57. // 最大公約数
  58. public static int gcd(int v1, int v2)
  59. {
  60. int tmp;
  61.  
  62. // どちらかが0だったら即座に終了
  63. if (v1 == 0 || v2 == 0) return 0;
  64.  
  65. // 正の値にしておく
  66. if (v1 < 0) v1 = -v1;
  67. if (v2 < 0) v2 = -v2;
  68.  
  69. // v1の方を大きくしておく
  70. if (v2 > v1)
  71. {
  72. tmp = v1; v1 = v2; v2 = tmp;
  73. }
  74.  
  75. for (; ; )
  76. {
  77. tmp = v1 % v2;
  78. if (tmp == 0) return v2;
  79.  
  80. v1 = v2; v2 = tmp;
  81. }
  82. }
  83.  
  84. // 通分する
  85. private void _fix_denominator(Rational other)
  86. {
  87. int tmp = _denominator;
  88. _numerator *= other._denominator;
  89. _denominator *= other._denominator;
  90.  
  91. other._numerator *= tmp;
  92. other._denominator *= tmp;
  93. }
  94.  
  95. // 正規化
  96. // ●分子・分母を約分する
  97. // ●負の符号が分母についている場合、分子にのみつけるようにする
  98. // ●値が0である場合は「0/1」にする
  99. private void _regularize()
  100. {
  101. int divisor = Math.Sign(_denominator) * gcd(_numerator, _denominator);
  102. if (divisor == 0)
  103. {
  104. // 分子が0の場合
  105. _numerator = 0;
  106. _denominator = 1;
  107. }
  108. else
  109. {
  110. _numerator /= divisor;
  111. _denominator /= divisor;
  112. }
  113. }
  114.  
  115. // ---------- 比較 ----------
  116.  
  117. public static bool operator ==(Rational r1, Rational r2)
  118. {
  119. r1._regularize();
  120. r2._regularize();
  121. return (r1._numerator == r2._numerator && r1._denominator == r2._denominator);
  122. }
  123.  
  124. public static bool operator !=(Rational r1, Rational r2)
  125. {
  126. return (r1 != r2);
  127. }
  128.  
  129. public static bool operator <(Rational r1, Rational r2)
  130. {
  131. r1._fix_denominator(r2);
  132. return (r1.numerator() < r2.numerator());
  133. }
  134.  
  135. public static bool operator >(Rational r1, Rational r2)
  136. {
  137. return (r2 < r1);
  138. }
  139.  
  140. // 以下、他の関数やクラスに使ってもらう際の補助関数
  141. public override bool Equals(object obj)
  142. {
  143. if (obj.GetType() == this.GetType())
  144. {
  145. return (this == (Rational)obj);
  146. }
  147.  
  148. return false;
  149. }
  150.  
  151. public override int GetHashCode()
  152. {
  153. return (_numerator | (_denominator << 16));
  154. }
  155.  
  156. // ---------- 型変換 ----------
  157.  
  158. public static explicit operator double(Rational r)
  159. {
  160. return (double)r._numerator / (double)r._denominator;
  161. }
  162.  
  163. public static explicit operator float(Rational r)
  164. {
  165. return (float)r._numerator / (float)r._denominator;
  166. }
  167.  
  168. // ---------- 加減乗除 ----------
  169.  
  170. public static Rational operator +(Rational r) // 単項演算子
  171. {
  172. // 単に自分のコピーを作ればよい
  173. return new Rational(r._numerator, r._denominator);
  174. }
  175.  
  176. public static Rational operator -(Rational r) // 単項演算子
  177. {
  178. return new Rational(-r._numerator, r._denominator);
  179. }
  180.  
  181. public static Rational operator +(Rational r1, Rational r2) // 二項演算子
  182. {
  183. r1._fix_denominator(r2);
  184. return new Rational(r1._numerator + r2._numerator, r1._denominator);
  185. }
  186.  
  187. public static Rational operator -(Rational r1, Rational r2) // 二項演算子
  188. {
  189. r1._fix_denominator(r2);
  190. return new Rational(r1._numerator - r2._numerator, r1._denominator);
  191. }
  192.  
  193. public static Rational operator *(Rational r1, Rational r2)
  194. {
  195. return new Rational(r1._numerator * r2._numerator, r1._denominator * r2._denominator);
  196. }
  197.  
  198. public static Rational operator /(Rational r1, Rational r2)
  199. {
  200. if (r2._numerator == 0)
  201. {
  202. throw new DivideByZeroException();
  203. }
  204. return new Rational(r1._numerator * r2._denominator, r1._denominator * r2._numerator);
  205. }
  206.  
  207. // ユーティリティ
  208. public override string ToString()
  209. {
  210. _regularize();
  211. if (_denominator == 1) return _numerator.ToString();
  212.  
  213. return string.Format("({0}/{1})", _numerator, _denominator);
  214. }
  215. }
  216. }
Add Comment
Please, Sign In to add comment