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 WindowsFormsApplication1 { public partial class Form1 : Form { public static BigNumber GCD(BigNumber X, BigNumber Y) { // ユークリッドの互除法による最大公約数 BigNumber T,XX,YY; XX=X;YY=Y; if (gtBig(X, Y)) { XX = X; YY = Y;} else { XX = Y; YY = X;} BigNumber B0 = new BigNumber(0); while (neqBig(YY, B0)) { T = modBig(XX, YY); XX = YY; YY = T; } return XX; } public static bool eq0(BigNumber X) { //BigNumberが0かどうかの判定 return X.omit().number.Length == 0; } public struct Fract { public bool sign; // 正負(負のときTrue) public BigNumber nume; // 分子 public BigNumber deno; // 分母 public Fract(bool Sign, int Nume, int Deno) { // 整数を符号付き分数に変換 if (Nume == 0) { sign = false; nume = new BigNumber(0); deno = new BigNumber(1); } else { sign = Sign; nume = new BigNumber(Math.Abs(Nume)); deno = new BigNumber(Math.Abs(Deno)); } } public Fract(int Nume, int Deno) { // 整数を分数に変換(符号は分子,分母の符号による) if (Nume == 0) { sign = false; nume = new BigNumber(0); deno = new BigNumber(1); } else { sign = ((long)Nume * (long)Deno < 0); nume = new BigNumber(Math.Abs(Nume)); deno = new BigNumber(Math.Abs(Deno)); } } public Fract(int Nume) {  // 整数を分数に変換(分母=1) if (Nume == 0) { sign = false; nume = new BigNumber(0); deno = new BigNumber(1); } else { sign = (Nume < 0); nume = new BigNumber(Math.Abs(Nume)); deno = new BigNumber(1); } } public Fract(bool Sign, BigNumber Nume, BigNumber Deno) {  // 分子,分母にBigNumberを指定して分数に変換(符号指定) sign = Sign; nume = Nume; nume.sign = false; if (eq0(Nume)) deno = new BigNumber(1); else { deno = Deno; deno.sign = false; } } public Fract(BigNumber Nume,BigNumber Deno) {  // 分子,分母にBigNumberを指定して分数に変換 // (符号は分子,分母の符号で設定) sign = (Nume.sign != Deno.sign); nume = Nume; nume.sign = false; if (eq0(Nume)) deno = new BigNumber(1); else { deno = Deno; deno.sign = false; } } public Fract(BigNumber Nume) { // 分子のみのBigNumberを分数に変換(分母=0) sign = Nume.sign; nume = Nume; nume.sign = false; deno = new BigNumber(1); } public Fract commonDeno() { // 約分(最大公約数で分母・分子を除す) bool S; BigNumber D, N; if (eq0(nume)) return new Fract(false, 0, 1); else { S = sign; BigNumber T = GCD(nume, deno); N = divBig(nume, T); D = divBig(deno, T); } return new Fract(S, N, D); } public Fract addAbsFract(BigNumber Nume, BigNumber Deno) {  // 分数絶対値の加算処理 BigNumber D = multBig(deno, Deno); BigNumber N = addBig(multBig(nume, Deno),multBig(Nume, deno)); return (new Fract(N,D)).commonDeno(); } public Fract addAbsFract(Fract A) {  // 分数絶対値の加算 return addAbsFract(A.nume, A.deno); } public Fract subAbsFract(BigNumber Nume, BigNumber Deno) {  // 分数絶対値の減算処理 BigNumber D = multBig(deno, Deno); BigNumber N = subBig(multBig(nume, Deno), multBig(Nume, deno)); bool S = false; if (N.sign == true) { S = true; N.sign = false; } return (new Fract(S, N, D)).commonDeno(); } public Fract subAbsFract(BigNumber Nume) {  // 分数絶対値の減算(減ずる値はBigNumber) return subAbsFract(Nume, new BigNumber(1)); } public Fract subAbsFract(Fract A) { // 分数絶対値の減算 return subAbsFract(A.nume, A.deno); } public Fract multAbsFract(BigNumber Nume, BigNumber Deno) { // 分数絶対値の乗算処理 BigNumber D = multBig(deno, Deno); BigNumber N = multBig(nume, Nume); return (new Fract(N, D)).commonDeno(); } public Fract multAbsFract(BigNumber Nume) {  // 分数絶対値の乗算処理(乗ずる値はBigNumber) BigNumber N = multBig(nume, Nume); return (new Fract(N, deno)).commonDeno(); } public Fract multAbsFract(Fract A) {  // 分数絶対値の乗算 return multAbsFract(A.nume, A.deno); } public Fract divAbsFract(BigNumber Nume, BigNumber Deno) {  // 分数絶対値の除算処理 BigNumber D = multBig(deno, Nume); BigNumber N = multBig(nume, Deno); return (new Fract(N, D)).commonDeno(); } public Fract divAbsFract(BigNumber Nume) {  // 分数絶対値の除算(除す値はBigNumber) BigNumber D = multBig(deno, Nume); return (new Fract(nume, D)).commonDeno(); } public Fract divAbsFract(int Nume) { // 分数絶対値の除算(除す値は整数) BigNumber D = deno.multMini((short)Nume); return (new Fract(nume, D)).commonDeno(); } public Fract divAbsFract(Fract A) {  // 分数絶対値の除算 return divAbsFract(A.nume, A.deno); } public override string ToString() { // 分数を文字列に変換 string S = ""; if (sign && nume.number.Length>0) S = "-"; return S + nume.ToString() + " / " + deno.ToString(); } public string ToString(int NumberOfDecimalPlaces) {  // 分数を10進数の小数に変換(桁数を指定。桁数が負のときは分数表現) string S=""; if (sign && nume.number.Length > 0) S = "-"; int N = NumberOfDecimalPlaces; if (N < 0) S = S + nume.ToString() + " / " + deno.ToString(); else {  Fract X = new Fract(false, nume, deno); BigNumber F = divBig(X.nume, X.deno); //整数部変換 S = S + F.ToString()+"."; X = X.subAbsFract(F);         //小数部に10を乗じた際, BigNumber B10 = new BigNumber(10);   //整数になった桁を  for (int i = 0; i < N; i++)      //その桁とする。 { X = X.multAbsFract(B10); F = divBig(X.nume , X.deno); S = S + F.ToString(); X = X.subAbsFract(F); } } return S; } } public static Fract addFract(Fract A, Fract B) {  //符号付き分数の加算(符号が同じとき絶対値加算,異なるとき絶対値減算) Fract C;  //減算のとき符号逆転したとき調整 if (A.sign == B.sign) { C = A.addAbsFract(B); C.sign = A.sign; } else { C = A.subAbsFract(B); C.sign = (C.sign != A.sign);} if (eq0(C.nume)) C.sign = false; return C; } public static Fract subFract(Fract A, Fract B) { //符号付き分数の減算(符号が異なるとき絶対値加算,同じとき絶対値減算) Fract C; //減算のとき符号逆転したとき調整 if (A.sign != B.sign) { C = A.addAbsFract(B); C.sign = A.sign; } else { C = A.subAbsFract(B); C.sign = (C.sign != A.sign); } if (eq0(C.nume)) C.sign = false; return C; } public static Fract multFract(Fract A, Fract B) { //符号付き分数の乗算(A,Bの符号が異なるときCは負。同じとき正) Fract C = A.multAbsFract(B); C.sign = (A.sign != B.sign); if (eq0(C.nume)) C.sign = false; return C; } public static Fract divFract(Fract A, Fract B) {  //符号付き分数の除算(分母・分子を逆転して乗算)(A,Bの符号が異なるときCは負。同じとき正) Fract C = A.divAbsFract(B); C.sign = (A.sign != B.sign);if (eq0(C.nume)) C.sign = false; return C; } public static Fract Evalue(int NumberOfLoop) // 分数版 { //マクローリン展開によるネイピア数(自然対数の底)の計算(引数は繰返し回数) Fract E = new Fract(0); BigNumber A = new BigNumber(1); BigNumber B1 = new BigNumber(1); for (int i = 1; i < NumberOfLoop; i++) { E = E.addAbsFract(reverseFract(A)); A = A.multMini((short)i); } return E; } public static Fract reverseFract(Fract A) { //分数の逆数(分母,分子を入れ替える) return new Fract(A.sign, A.deno, A.nume); } public static Fract reverseFract(BigNumber A) { //BigNumberの逆数(分子=1, 分母 = BigNumber) return new Fract(A.sign, new BigNumber(1), A); } public static BigNumber addBig(BigNumber A, BigNumber B) { //符号付きBigNumberの加算 BigNumber C; //符号が同じとき絶対値加算,異なるとき絶対値減算 if (A.sign == B.sign) {C = A.addAbs(B); C.sign = A.sign;} else { int check = A.compareAbs(B); if (check == 0) C= new BigNumber(0); else if (check > 0) { C = A.subAbs(B); C.sign = A.sign; } else { C = B.subAbs(A); C.sign = B.sign; } } return C; } public static BigNumber subBig(BigNumber A, BigNumber B) {  //符号付きBigNumberの減算 BigNumber C; //符号が同じとき絶対値減算,異なるとき絶対値加算 if (A.sign == B.sign){ int check = A.compareAbs(B); if (check == 0) C = new BigNumber(0); else if (check > 0) { C = A.subAbs(B); C.sign = A.sign; } else { C = B.subAbs(A); C.sign = !A.sign;} } else{ C = A.addAbs(B); C.sign = A.sign; } return C; } public static BigNumber multBig(BigNumber A, BigNumber B) {  //符号付きBigNumberの乗算。符号が異なるとき負,同じとき正 BigNumber C; C = A.multAbs(B); C.sign= (A.sign != B.sign); return C; } public static BigNumber divBig(BigNumber A, BigNumber B) {  //符号付きBigNumberの除算。符号が異なるとき負,同じとき正 BigNumber QR = A.divAbsQ(B); QR.sign= (A.sign != B.sign); return QR; } public static BigNumber modBig(BigNumber A, BigNumber B) {  //符号付きBigNumberの剰余。符号が異なるとき負,同じとき正 BigNumber QR = A.modAbs(B); QR.sign = (A.sign != B.sign); return QR; } public static BigNumber minusBig(BigNumber A) {  //符号付きBigNumberの符号逆転 if (A.number.Length == 0) return new BigNumber(0); return new BigNumber(!A.sign, A.number, A.number.Length); } public static bool eqBig(BigNumber A, BigNumber B) {  // A == B if (A.number.Length == 0) { if (B.number.Length == 0) return true; else return false; } else { if (B.number.Length == 0) return false; if (A.sign != B.sign) return false; if (A.compareAbs(B) == 0) return true; return false; } } public static bool neqBig(BigNumber A, BigNumber B) { // A != B return !eqBig(A, B); } public static bool gtBig(BigNumber A, BigNumber B) { // A > B if (A.number.Length == 0) { if (B.number.Length == 0) return false; // A = 0 & B = 0 if (B.sign) return true; // A = 0 & B < 0 return false; // A = 0 & B > 0 } else { if (B.number.Length == 0) { if (A.sign) return false; // A < 0 & B = 0 return true; // A > 0 & B = 0 } if (A.sign) { if (B.sign){ // A < 0 & B < 0 if (A.compareAbs(B) < 0) return true; //絶対値小 return false; } else return false; // A < 0 & B > 0 } if (B.sign) return true; // A > 0 & B < 0 if (A.compareAbs(B) > 0) return true; // A > 0 & B > 0 絶対値大 return false; } } public static bool ltBig(BigNumber A, BigNumber B) { // A < B if (A.number.Length == 0) { if (B.number.Length == 0) return false; // A = 0 & B = 0 if (B.sign) return false; // A = 0 & B < 0 return true; // A = 0 & B > 0 } else { if (B.number.Length == 0) { if (A.sign) return true; // A < 0 & B = 0 return false; // A > 0 & B = 0 } if (A.sign) { if (B.sign) { // A < 0 & B < 0 if (A.compareAbs(B) > 0) return true; //絶対値大 return false; } else return true; // A < 0 & B > 0 } if (B.sign) return false; // A > 0 & B < 0 if (A.compareAbs(B) < 0) return true; // A > 0 & B > 0 絶対値小 return false; } } public static bool geBig(BigNumber A, BigNumber B) // A >= B ( == !(AB)) { return !gtBig(A, B); } public static BigNumber compPi(int MX) // マチンの公式によるPiの計算 {  // π=161/((2n+1)5^(2n-1)) + 41/((2n+1)239^(2n-1)) int MXX = MX + 1; BigNumber U; BigNumber Pi = new BigNumber(0); BigNumber T = new BigNumber(false, MXX, 16); T= T.divMiniQ(5); BigNumber K = new BigNumber(1); U = T; do{ // 161/((2n+1)5^(2n-1))の計算 Pi = Pi.addAbs(U); T = T.divMiniQ(25); K = K.addMini(2); U = T.divAbsQ(K); Pi = Pi.subAbs(U); T = T.divMiniQ(25); K = K.addMini(2); U = T.divAbsQ(K); } while (U.number.Length != 0); T = new BigNumber(false,MXX, 4); BigNumber N239 = new BigNumber(239); BigNumber N239sq = N239.multAbs(N239); T = T.divAbsQ(N239); K = new BigNumber(1); U = T; do{  // 41/((2n+1)239^(2n-1))の計算 Pi = Pi.subAbs(U); T = T.divAbsQ(N239sq); K = K.addMini(2); U = T.divAbsQ(K); Pi = Pi.addAbs(U); T = T.divAbsQ(N239sq); K = K.addMini(2); U = T.divAbsQ(K); } while (U.number.Length != 0); return Pi; } public static BigNumber compE(int MX) { // BigNumberによる長桁数ネイピア数(自然対数の底)の計算 BigNumber E = new BigNumber(false, MX + 1, 1); BigNumber K = new BigNumber(1); BigNumber T = E; do { E = E.addAbs(T); K = K.addMini(1); T = T.divAbsQ(K); } while (T.number.Length != 0); return E; } public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { textBox3.Text = addBig(new BigNumber(textBox1.Text), new BigNumber(textBox2.Text)).ToString(); } private void button2_Click(object sender, EventArgs e) { textBox3.Text = subBig(new BigNumber(textBox1.Text), new BigNumber(textBox2.Text)).ToString(); } private void button3_Click(object sender, EventArgs e) { textBox3.Text = minusBig(new BigNumber(textBox1.Text)).ToString(); } private void button4_Click(object sender, EventArgs e) { textBox3.Text = multBig(new BigNumber(textBox1.Text), new BigNumber(textBox2.Text)).ToString(); } private void button5_Click(object sender, EventArgs e) { textBox3.Text = divBig(new BigNumber(textBox1.Text), new BigNumber(textBox2.Text)).ToString(); } private void button6_Click(object sender, EventArgs e) { textBox3.Text = modBig(new BigNumber(textBox1.Text), new BigNumber(textBox2.Text)).ToString(); } private void button7_Click(object sender, EventArgs e) { textBox3.Text = eqBig(new BigNumber(textBox1.Text), new BigNumber(textBox2.Text)).ToString(); } private void button8_Click(object sender, EventArgs e) { textBox3.Text = neqBig(new BigNumber(textBox1.Text), new BigNumber(textBox2.Text)).ToString(); } private void button9_Click(object sender, EventArgs e) { textBox3.Text = gtBig(new BigNumber(textBox1.Text), new BigNumber(textBox2.Text)).ToString(); } private void button10_Click(object sender, EventArgs e) { textBox3.Text = geBig(new BigNumber(textBox1.Text), new BigNumber(textBox2.Text)).ToString(); } private void button11_Click(object sender, EventArgs e) { textBox3.Text = ltBig(new BigNumber(textBox1.Text), new BigNumber(textBox2.Text)).ToString(); } private void button12_Click(object sender, EventArgs e) { textBox3.Text = leBig(new BigNumber(textBox1.Text), new BigNumber(textBox2.Text)).ToString(); } private void button13_Click(object sender, EventArgs e) { int K = (int.Parse(textBox6.Text) + 1) / 2; if (K < 1) K = 1; int N = int.Parse(textBox4.Text) / 2; if (N <= 5) MessageBox.Show("桁数が小さすぎます。"); else textBox3.Text = compPi(N+K).ToString(); } private void button14_Click(object sender, EventArgs e) { int N = int.Parse(textBox4.Text); int ist = int.Parse(textBox5.Text); string S = textBox3.Text; string R = ""; int k = 0; for (int i = ist; i < N; i += 10) { k++; if (((k-1) % 5) == 0) R += "("+i.ToString("0000")+") : "; R += S.Substring(i, 10)+" "; if ((k % 5)== 0) R += "\r\n"; } textBox3.Text = R; } private void button15_Click(object sender, EventArgs e) { int K = (int.Parse(textBox6.Text) + 1) / 2; if (K < 1) K = 1; int N = int.Parse(textBox4.Text) / 2; if (N <= 5) MessageBox.Show("桁数が小さすぎます。"); else textBox3.Text = compE(N+K).ToString(); } private void button16_Click(object sender, EventArgs e) { int[] Freq = new int[10]; string S0 = "0123456789"; string Str = textBox3.Text; for (int i = 0; i < Str.Length; i++) { string C = Str.Substring(i, 1); int k = S0.IndexOf((string)C); if (k >= 0) Freq[k]++; } Str = ""; for (int i = 0; i < 10; i++) { Str = Str + i + ":" + Freq[i] + ", "; } MessageBox.Show(Str); } private void button17_Click(object sender, EventArgs e) { textBox3.Text = GCD(new BigNumber(textBox1.Text), new BigNumber(textBox2.Text)).ToString(); } private void button18_Click(object sender, EventArgs e) { Fract X = new Fract(new BigNumber(textBox1.Text), new BigNumber(textBox7.Text)); Fract Y = new Fract(new BigNumber(textBox2.Text), new BigNumber(textBox8.Text)); Fract Z = addFract(X, Y); int M = int.Parse(textBox10.Text); textBox3.Text = "(" + X.ToString(-1)+ ") + (" + Y.ToString(-1) + ")\r\n = (" + Z.ToString(-1) + ") ( " + Z.ToString(M) + ")"; } private void button19_Click(object sender, EventArgs e) { Fract X = new Fract(new BigNumber(textBox1.Text), new BigNumber(textBox7.Text)); Fract Y = new Fract(new BigNumber(textBox2.Text), new BigNumber(textBox8.Text)); Fract Z = subFract(X,Y); int M = int.Parse(textBox10.Text); textBox3.Text ="(" + X.ToString(-1) + ") - (" + Y.ToString(-1) + ")\r\n = (" + Z.ToString(-1) + ") ( " + Z.ToString(M) + ")"; } private void button20_Click(object sender, EventArgs e) { Fract X = new Fract(new BigNumber(textBox1.Text), new BigNumber(textBox7.Text)); Fract Y = new Fract(new BigNumber(textBox2.Text), new BigNumber(textBox8.Text)); Fract Z = multFract(X, Y); int M = int.Parse(textBox10.Text); textBox3.Text = "(" + X.ToString(-1) + ") * (" + Y.ToString(-1) + ")\r\n = (" + Z.ToString(-1) + ") ( " + Z.ToString(M) + ")"; } private void button21_Click(object sender, EventArgs e) { Fract X = new Fract(new BigNumber(textBox1.Text), new BigNumber(textBox7.Text)); Fract Y = new Fract(new BigNumber(textBox2.Text), new BigNumber(textBox8.Text)); Fract Z = divFract(X,Y); int M = int.Parse(textBox10.Text); textBox3.Text = "(" + X.ToString(-1) + ") / (" + Y.ToString(-1) + ")\r\n = (" + Z.ToString(-1) + ") ( " + Z.ToString(M) + ")"; } private void button22_Click(object sender, EventArgs e) { int N=int.Parse(textBox9.Text); int M = int.Parse(textBox10.Text); Fract Z = Evalue(N); textBox3.Text = "(" + Z.ToString(-1) + ")\r\n( " + Z.ToString(M) + ")"; } } public class BigBig { // 二つのBigNumber(除算用) Q:商,R:剰余 public BigNumber Q; public BigNumber R; public BigBig(BigNumber quotient, BigNumber remainder) { Q = quotient; R = remainder; } } public class BigNumber { public Boolean sign; public short[] number; public BigNumber(int V) {  // 整数をBigNumberに変換 sign = false; int LL = V; if(LL==0)number=new short[0]; else { if(LL<0){ sign=true;LL = - LL; } int K = ((int)Math.Log(LL, 100)) + 1; number = new short[K]; for (int i = 0; i < K; i++) { number[i] =(short)( LL % 100); // 100のmodを各配列に入れる LL /= 100; } } } public BigNumber(bool s, short[] num,int N) {  // 配列データをBigNumberとして扱う処理 sign = s; number = new short[N]; for(int i=0;i= 0) s = c+s; } } int len=(s.Length+1)/2; //最後尾から2文字ずつ変換して配列に入れる。 short[] num=new short[len]; for (int i = 0; i < s.Length; i += 2) { string c=s.Substring(i,1); if((i+2)<=s.Length) c = s.Substring(i+1,1)+c; num[i/2] = short.Parse(c); } int k; for (k = len - 1; k >= 0; k--) if (num[k] != 0) break; number = new short[k + 1]; for (int i = 0; i <= k; i++) number[i] = num[i]; } public override string ToString() {  // BigNumberを文字列に変換 int Len=number.Length; if (Len == 0) return "0"; string S = ""; if (sign ) S = "-"; S += number[Len - 1].ToString(); for (int i = Len - 2; i >= 0; i--) S += number[i].ToString("00"); return S; } public BigNumber omit() { // 高位桁の0を省略する処理 int N = number.Length; if(N==0)return new BigNumber(0); int i=N-1; while (i >= 0) { if (number[i] != 0) return new BigNumber(sign,number,i+1); i--; } return new BigNumber(0); } public BigNumber addMini(short dt) // 0〜99を加算 {  int N=number.Length; if (N == 0) return new BigNumber((int)dt); short[] num = new short[N+1]; short dt2 = (short)(number[0] + dt); num[0]=(short)(dt2 % 100); for (int i = 1; i < N; i++) { //桁上がりを考慮した加算 dt2 /= 100; dt2 += number[i]; num[i]=(short)(dt2 % 100); } num[N] = (short)(dt2 / 100); if(num[N]!=0) N=N+1; return new BigNumber(sign, num, N); } public BigNumber addAbs(BigNumber dt) // 絶対値の加算 { int N1=number.Length; if (N1 == 0) return dt; int N2 = dt.number.Length; if (N2 == 0) return new BigNumber(sign, number, N1); int N = N1; if (N < N2) N = N2; short[] num = new short[N + 1]; short dt2 = (short)(number[0] + dt.number[0]); num[0] = (short)(dt2 % 100); for (int i = 1; i < N; i++) { dt2 /= 100; if (i < N1) dt2 += number[i]; if (i < N2) dt2 += dt.number[i]; num[i] = (short)(dt2 % 100); } num[N] = (short)(dt2 / 100); if (num[N] != 0) N = N + 1; return new BigNumber(sign, num, N); } public BigNumber subAbs(BigNumber dt) // 絶対値の減算(引かれる値の方が大きいことを前提) { int N1 = number.Length; if (N1 == 0) return new BigNumber(!dt.sign,dt.number,dt.number.Length); int N2 = dt.number.Length; if (N2 == 0) return new BigNumber(sign, number, N1); int N = N1; short[] num = new short[N]; short T = 0; for (int i = 0; i < N2; i++){ T =(short) (number[i] - dt.number[i] - T); if (T >= 0){ num[i] = T; T = 0; } else { num[i] = (short)(T + 100); T = 1;} } for (int i = N2; i < N1; i++){ T = (short)(number[i] - T); if (T >= 0){ num[i] = T; T = 0;} else { num[i] = (short)(T + 100); T = 1;} } BigNumber C=new BigNumber(sign,num,N); return C.omit(); } public int compareAbs(BigNumber dt) // 絶対値の大きさの比較 { int N1 = number.Length; int N2 = dt.number.Length; if (N1 == 0 && N2 == 0) return 0; if (N1 > N2) return 1; else if (N1 < N2) return -1; else{ for (int i = N1-1; i >= 0; i--){ if (number[i] > dt.number[i]) return 1; else if (number[i] < dt.number[i]) return -1; } return 0; } } public BigNumber multMini(short dt) // 0〜99を乗算 { int N = number.Length; if (N == 0 || dt==0) return new BigNumber(0); short[] num = new short[N + 1]; int T0 = 0; for (int i = 0; i < N; i++){ T0=number[i]*dt+T0; num[i] = (short)(T0 % 100); T0 /= 100; } num[N] = (short)T0; if (num[N] != 0) N = N + 1; return new BigNumber(sign, num, N); } public BigNumber multAbs(BigNumber dt) // BigNumber同士の乗算 { int i, j; int N1 = number.Length; int N2 = dt.number.Length; if (N1 == 0 || N2 == 0) return new BigNumber(0); int N = N1 + N2; short[] num = new short[N+1]; for (i = 0; i < num.Length; i++) num[i] = 0; for (j = 0; j < N2; j++){ // 被乗数の着目位置 = j int U = dt.number[j]; if (U != 0){ int T0 = 0; for (i = 0; i < N1; i++) { // 乗数の着目位置 = i T0 = num[i+j] + number[i] * U + T0; // 結果の位置 = i+j num[i+j] = (short)(T0 % 100); T0 = T0 / 100; } i = N1 + j; T0 = num[i] + T0; while (T0 >= 100){ num[i] = (short)(T0 - 100); i = i + 1;T0=num[i]+1; } num[i] = (short)T0; } } BigNumber X = new BigNumber(sign, num, N); return X.omit(); } public int divMiniProc(int N,short[] num, short dt) { int T0 = 0; for (int i = N - 1; i >= 0; i--){ T0 = T0 * 100 + number[i]; num[i] = (short)(T0 / dt); T0 = T0 - num[i] * dt; } return T0; } public BigBig divMini(short dt) // 0〜99で除算 { int N = number.Length; if (dt == 0) MessageBox.Show("0で除算しました"); if (N == 0 || dt == 0) return new BigBig(new BigNumber(0),new BigNumber(0)); short[] num = new short[N]; int T0= divMiniProc(N, num, dt); return new BigBig(new BigNumber(sign, num, N), new BigNumber((short)T0)); } public short modMini(short dt) // 0〜99で除算 { int N = number.Length; if (dt == 0) MessageBox.Show("0で除算しました"); if (N == 0 || dt == 0) return 0; short[] num = new short[N]; int T0 = divMiniProc(N, num, dt); return (short)T0; } public BigNumber divMiniQ(short dt) { int N = number.Length; if (dt == 0) MessageBox.Show("0で除算しました"); if (N == 0 || dt == 0) return new BigNumber(0); short[] num = new short[N]; int T0 = divMiniProc(N, num, dt); return (new BigNumber(sign, num, N)).omit(); } public int quot(int V, BigNumber dt, short[] C, short[] R, int j) { // 着目桁位置の商を求める int i, k, T; bool lessThan = true; int N2 = dt.number.Length; int Q1 = V / dt.number[N2 - 1]; while (lessThan) { for (i = 0; i <= N2; i++) C[i] = 0; T = 0; for (i = 0; i < N2; i++){      // 除数 T = dt.number[i] * Q1 + T; C[i] = (short)(T % 100); T /= 100; } C[N2] = (short)T; k = j + N2; lessThan = false; for (i = N2; i >= 0; i--) { if (R[k] > C[i]) break;   //被除数が大きければ終わり else if (R[k] < C[i]) { lessThan = true; Q1--; break; }//被除数が小さければQ1を減じて再試行 k--; } // 被除数 = Q * 除数のときも lessThan = false のままなので再試行なし } return Q1; } public void divProc(int N,int N2,BigNumber dt,short[]C, short[] R, short[] Q) { int i, j, Q1, T; int k = N2; int jk = N - 1; int V = 0; for (j = N - N2; j >= 0; j--) { V = V * 100 + R[N2 + j - 1]; if (V >= dt.number[N2 - 1]){ Q1 = quot(V, dt, C, R, j); T = 0; k = j; for (i = 0; i <= N2; i++){     // Q1*被除数を着目桁以上から差し引く T = (short)(R[k] - C[i] - T); // 差し引く if (T >= 0) { R[k] = (short)T; T = 0; } else { R[k] = (short)(T + 100); T = 1;} k++; } V = 0; for (i = N; i >= j + N2 - 1; i--) V = V * 100 + R[i]; Q[j] = (short)Q1; } } } public void moveShort(int N, short[] R) // 配列の移動 { for (int i = 0; i < N; i++) R[i] =number[i];} public BigBig divAbs(BigNumber dt) // 絶対値の除算処理で商と剰余を求める { int N = number.Length; int N2 = dt.number.Length; if ( N2== 0) MessageBox.Show("0で除算しました"); if (N == 0 || N2 == 0) return new BigBig(new BigNumber(0), new BigNumber(0)); if (N2 == 1) return divMini(dt.number[0]); int flag = compareAbs(dt); if (flag == 0) return new BigBig(new BigNumber(1), new BigNumber(0)); else if (flag < 0) return new BigBig(new BigNumber(0), dt); short[] R=new short[N+1]; short[] C=new short[N2+1]; int NR = N - N2+1; short[] Q = new short[NR]; moveShort(N, R); R[N]=0; divProc(N, N2, dt, C, R, Q); BigNumber QQ = new BigNumber(false, Q, NR); BigNumber RR = new BigNumber(false, R, N); return new BigBig(QQ.omit(), RR.omit()); } public BigNumber divAbsQ(BigNumber dt)//絶対値の除算 { int N = number.Length; int N2 = dt.number.Length; if (N2 == 0) MessageBox.Show("0で除算しました"); if (N == 0 || N2 == 0) return new BigNumber(0); if (N2 == 1) return divMiniQ(dt.number[0]); int flag = compareAbs(dt); if (flag == 0) return new BigNumber(1); else if (flag < 0) return new BigNumber(0); short[] R = new short[N + 1]; short[] C = new short[N2 + 1]; int NR = N - N2 + 1; short[] Q = new short[NR]; moveShort(N, R); R[N] = 0; divProc(N, N2, dt, C, R, Q); return (new BigNumber(false, Q, NR)).omit(); } public BigNumber modAbs(BigNumber dt) //絶対値の剰余 { int N = number.Length; int N2 = dt.number.Length; if (N2 == 0) MessageBox.Show("0で除算しました"); if (N == 0 || N2 == 0) return new BigNumber(0); if (N2 == 1) return new BigNumber(modMini(dt.number[0])); int flag = compareAbs(dt); if (flag == 0) return new BigNumber(0); else if (flag < 0) return dt; short[] R = new short[N + 1]; short[] C = new short[N2 + 1]; int NR = N - N2 + 1; short[] Q = new short[NR]; moveShort(N, R); R[N] = 0; divProc(N, N2, dt, C, R, Q); BigNumber QQ = new BigNumber(false, Q, NR); BigNumber RR = new BigNumber(false, R, N); return RR.omit(); } } }