using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace doubleFraction { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { dFract A=new dFract(1,2), B=new dFract(1,3), C = A.add(B); MessageBox.Show(A.ToString() + " + " + B.ToString() + " = " + C.ToString()); C = A.sub(B); MessageBox.Show(A.ToString() + " - " + B.ToString() + " = " + C.ToString()); C = A.mlt(B); MessageBox.Show(A.ToString() + " * " + B.ToString() + " = " + C.ToString()); C = A.div(B); MessageBox.Show(A.ToString() + " / " + B.ToString() + " = " + C.ToString()); C = A.rev(); MessageBox.Show(" 1 / " + A.ToString() + " = " + C.ToString()); string SS = dFract.intToStr(true, 273.0); MessageBox.Show(SS); C = new dFract(41, 9); SS = C.fracToDecStr(3); MessageBox.Show(SS); C = dFract.compE(100); SS = dFract.sepStr(C.fracToDecStr(19)); MessageBox.Show(SS); C = dFract.compPi(50); SS = dFract.sepStr(C.fracToDecStr(19)); MessageBox.Show(SS); } } public class dFract// doubleを分母、分子とする分数 { double nume, deno; // 分子(nume), 分母(deno) public dFract(double Nume, double Deno) { nume = Nume; deno = Deno; if (nume == 0) deno = Math.Abs(Deno); else if (deno == 0) MessageBox.Show("分母0の分数が指定されました"); else { double G = GCD(nume, deno); nume /= G; deno /= G; if (deno < 0) { nume *= -1; deno *= -1; } } } public static double Mod(double A, double B)// double用Mod { double P = Math.Floor(A / B); return A - B * P; } public static double GCD(double A, double B)// double用最大公約数 { double W; A = Math.Abs(A); B = Math.Abs(B); if (A < B) { double T = A; A = B; B = T; } while (B != 0) { W = Mod(A, B); A = B; B = W; } return A; } public override string ToString()// double分数を文字列で表現する { return nume.ToString()+"/"+deno.ToString(); } public dFract comDeno()// 約分 { double G = GCD(nume, deno); return new dFract(nume / G, deno / G); } public dFract comDenoSign()// 約分と符号の調整(分母は必ず正とする) { double G = GCD(nume, deno); if (deno >= 0) return new dFract(nume / G, deno / G); return new dFract(-nume / G, - deno / G); } public dFract add(dFract B)// 加算 { return new dFract(nume * B.deno + B.nume * deno, deno * B.deno).comDeno(); } public dFract sub(dFract B)// 減算 { return new dFract(nume * B.deno - B.nume * deno, deno * B.deno).comDeno(); } public dFract mlt(dFract B)// 乗算 { return new dFract(nume * B.nume, deno* B.deno).comDenoSign(); } public dFract div(dFract B)// 除算 { return new dFract(nume * B.deno, deno * B.nume).comDenoSign(); } public dFract rev()// 逆数 { return new dFract(deno, nume).comDenoSign(); } public dFract abs()// 絶対値 { Double Nume = Math.Abs(nume); return new dFract(Nume, deno); } public dFract minus()// 符号逆転 { Double Nume = -nume; return new dFract(Nume, deno); } public static int cmpFract(dFract A, dFract B)//分数の比較 { dFract C = A - B; if (C.nume > 0) return 1; else if (C.nume<0) return -1; else return 0; } public static string intToStr(Boolean sign, double C)// X の整数部分を数字列化 { string Fig="0123456789"; double D = 1; string S; if (sign) S = "-"; else S = ""; for (double CC = C; CC > 9; CC /= 10, D *= 10) ; int CD; for (double CX = C; D >0.5; CX -= (double)CD * D, D /= 10) { CD = (int)(CX / D); S+=Fig.Substring(CD, 1);} return S; } public string fracToDecStr(int N)// 分数を数字列化 { string Fig = "0123456789"; double Nume = Math.Abs(nume), Deno = deno; double C = Math.Floor(Nume / Deno); string S = intToStr(nume < 0, C); S += "."; for (int i = 0; i < N; i++) { Nume -= C * Deno; Nume *= 10; C = Math.Floor(Nume / Deno); S += Fig.Substring((int)C, 1); } return S; } public static string sepStr(string S)//文字列をスペースで分割 { if (S.Length <= 6) return S; string R = S.Substring(0, 6); for (int j = 6; j < S.Length; j+=5 ) { int N = 5; if ((j + 5) > S.Length) N = S.Length - j; R += " " + S.Substring(j, N); } return R; } // 関数呼出しのバラエティ public static dFract add(dFract A, dFract B) { return A.add(B);} public static dFract sub(dFract A, dFract B) { return A.sub(B);} public static dFract mlt(dFract A, dFract B) { return A.mlt(B);} public static dFract div(dFract A, dFract B) { return A.div(B);} public static dFract rev(dFract A) { return A.rev(); } public static dFract abs(dFract A) { return A.abs(); } public static dFract minus(dFract A) { return A.minus(); } // オペレータ定義 public static dFract operator +(dFract A, dFract B) { return add(A, B); } public static dFract operator +(double A, dFract B) { return add(new dFract(A, 1), B); } public static dFract operator +(dFract A, double B) { return add(A, new dFract(B, 1)); } public static dFract operator +(dFract A) { return A; } public static dFract operator -(dFract A, dFract B) { return sub(A, B); } public static dFract operator -(double A, dFract B) { return sub(new dFract(A, 1), B); } public static dFract operator -(dFract A, double B) { return sub(A, new dFract(B, 1)); } public static dFract operator -(dFract A) { return minus(A); } public static dFract operator *(dFract A, dFract B) { return mlt(A, B); } public static dFract operator *(double A, dFract B) { return mlt(new dFract(A, 1), B); } public static dFract operator *(dFract A, double B) { return mlt(A, new dFract(B, 1)); } public static dFract operator /(dFract A, dFract B) { return div(A, B); } public static dFract operator /(double A, dFract B) { return div(new dFract(A, 1), B); } public static dFract operator /(dFract A, double B) { return div(A, new dFract(B, 1)); } public static bool operator ==(dFract A, dFract B) { return cmpFract(A, B) == 0; } public static bool operator ==(double A, dFract B) { return cmpFract(new dFract(A, 1), B) == 0; } public static bool operator ==(dFract A, double B) { return cmpFract(A, new dFract(B, 1)) == 0; } public static bool operator !=(dFract A, dFract B) { return cmpFract(A, B) != 0; } public static bool operator !=(double A, dFract B) { return cmpFract(new dFract(A, 1), B) != 0; } public static bool operator !=(dFract A, double B) { return cmpFract(A, new dFract(B, 1)) != 0; } public static bool operator >(dFract A, dFract B) { return cmpFract(A, B) > 0; } public static bool operator >(double A, dFract B) { return cmpFract(new dFract(A, 1), B) > 0; } public static bool operator >(dFract A, double B) { return cmpFract(A, new dFract(B, 1)) > 0; } public static bool operator <(dFract A, dFract B) { return cmpFract(A, B) < 0; } public static bool operator <(double A, dFract B) { return cmpFract(new dFract(A, 1), B) < 0; } public static bool operator <(dFract A, double B) { return cmpFract(A, new dFract(B, 1)) < 0; } public static bool operator >=(dFract A, dFract B) { return cmpFract(A, B) >= 0; } public static bool operator >=(double A, dFract B) { return cmpFract(new dFract(A, 1), B) >= 0; } public static bool operator >=(dFract A, double B) { return cmpFract(A, new dFract(B, 1)) >= 0; } public static bool operator <=(dFract A, dFract B) { return cmpFract(A, B) <= 0; } public static bool operator <=(double A, dFract B) { return cmpFract(new dFract(A, 1), B) <= 0; } public static bool operator <=(dFract A, double B) { return cmpFract(A, new dFract(B, 1)) <= 0; } public override bool Equals(object obj){ return base.Equals(obj);} public override int GetHashCode() { return base.GetHashCode();} // ネイピア数の計算(自然対数の底)の計算 public static dFract compE(int Loop) { // 引数は繰返し回数(100程度を指定すると、単なるdoubleで計算した結果より4桁程度精度がよい) dFract C1 = new dFract(1, 1), E = new dFract(1,1); for (int i = (Loop+1) * 2; i >= 2; i -= 2) E = C1 + rev(new dFract((double)i, 1) + rev(C1 + rev(E))); return (new dFract(2,1) )+ rev(E); } // 円周率πの計算 public static dFract compPi(int Loop) { // 引数は繰返し回数(50程度を指定すると単なるdoubleで計算した結果より4桁程度精度がよい) dFract P = new dFract(1,1); for(int i=Loop+1; i>=1; i--) P=(new dFract((double)(2*i-1),1))+(new dFract((double)(i*i),1)/P); return (new dFract(4, 1)) / P; } } }