2011-08-02 20:10:22Morris
[手動][函式] 大數浮點數加減乘除開根號, 精準100位
我沒有用 /0 溢位的處理, 請自行處理
範例輸入 :
1 -951.123548987 213548.2158
2 654.555 3158
3 0 10.665214
4 3.6 7
5 16.32458
範例輸出 :
-951.123548987 + 213548.2158
= 212597.092251013
654.555 - 3158
= -2503.445
0 * 10.665214
= 0
3.6 / 7
= 0.51428571428571428571428571428571428571428571428571428571428571428571428571
4285714285714285714285714
sqrt( 16.32458 )
= 4.04036879504829360818257528981444228496635244984506
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define L 100
typedef struct {
char neg;
int pv[L], pl;
int hv[L], hl;
}BigNumber;
/*
123.456
pv[] = '321'
hv[] = '456'
*/
BigNumber minus(BigNumber , BigNumber );
int compare(BigNumber A, BigNumber B) {/*兩個都是正數*/
int a, h;
if(A.pl > B.pl) return 1;
if(A.pl < B.pl) return 0;
for(a = A.pl; a >=0; a--)
if(A.pv[a] > B.pv[a])
return 1;
else if(A.pv[a] < B.pv[a])
return 0;
for(a = 0; a <= A.hl && a <= B.hl; a++)
if(A.hv[a] > B.hv[a])
return 1;
else if(A.hv[a] < B.hv[a])
return 0;
if(A.hl > B.hl) return 1;
else if(A.hl < B.hl) return 0;
return 1;
}
BigNumber addit(BigNumber A, BigNumber B) {
if(A.neg == 0 && B.neg == 1) {
B.neg = 0;return minus(A, B);
}
else if(A.neg == 1 && B.neg == 0) {
A.neg = 0;return minus(B, A);
}
int a, p, h;
BigNumber C;
C.neg = A.neg;
for(a = 0; a < L; a++) C.pv[a] = C.hv[a] = 0;
for(a = 0; a <= A.pl; a++) C.pv[a] += A.pv[a];
for(a = 0; a <= B.pl; a++) C.pv[a] += B.pv[a];
for(a = 0; a <= A.hl; a++) C.hv[a] += A.hv[a];
for(a = 0; a <= B.hl; a++) C.hv[a] += B.hv[a];
h = (A.hl < B.hl) ? A.hl : B.hl;/*min*/
for(a = h; a >= 1; a--)
C.hv[a-1] += C.hv[a]/10, C.hv[a] %= 10;
C.pv[0] += C.hv[0]/10, C.hv[0] %= 10;
p = (A.hl > B.hl) ? A.hl : B.hl;/*max*/
for(a = 0; a <= p; a++)
C.pv[a+1] += C.pv[a]/10, C.pv[a] %= 10;
p = L-1, h = L-1;
while(C.pv[p] == 0 && p >= 0) p--;
while(C.hv[h] == 0 && h >= 0) h--;
C.pl = p, C.hl = h;
return C;
}
BigNumber minus(BigNumber A, BigNumber B) {
if(A.neg == 1 && B.neg == 1) {
B.neg = 0, A.neg = 0;return minus(B, A);
}
else if(A.neg == 1 && B.neg == 0) {
A.neg = 0;
BigNumber C = addit(A, B);
C.neg = 1;
return C;
}
else if(A.neg == 0 && B.neg == 1) {
B.neg = 0;return addit(A, B);
}
if(compare(A, B) == 0) {
A.neg = 0;
BigNumber C = minus(B, A);
C.neg = 1;
return C;
}
int a, p, h;
BigNumber C;
for(a = 0; a < L; a++) C.pv[a] = C.hv[a] = 0;
for(a = 0; a <= A.pl; a++) C.pv[a] = A.pv[a];
for(a = 0; a <= A.hl; a++) C.hv[a] = A.hv[a];
for(a = 0; a <= B.pl; a++) C.pv[a] -= B.pv[a];
for(a = 0; a <= B.hl; a++) C.hv[a] -= B.hv[a];
for(a = L-1; a >= 1; a--)
while(C.hv[a] < 0)
C.hv[a-1]--, C.hv[a] += 10;
while(C.hv[0] < 0)
C.pv[0]--, C.hv[0] += 10;
for(a = 0; a < L; a++)
while(C.pv[a] < 0)
C.pv[a+1]--, C.pv[a] += 10;
p = L-1, h = L-1;
while(C.pv[p] == 0 && p >= 0) p--;
while(C.hv[h] == 0 && h >= 0) h--;
C.pl = p, C.hl = h;
return C;
}
BigNumber multi(BigNumber A, BigNumber B) {
BigNumber C;
int Aa[2*L], Bb[2*L], Cc[4*L+1] = {};
int a, b, Al = 0, Bl = 0, p, h;
for(a = 0; a < L; a++) C.pv[a] = C.hv[a] = 0;
for(a = A.hl; a >= 0; a--) Aa[Al++] = A.hv[a];
for(a = 0; a <= A.pl; a++) Aa[Al++] = A.pv[a];
for(a = B.hl; a >= 0; a--) Bb[Bl++] = B.hv[a];
for(a = 0; a <= B.pl; a++) Bb[Bl++] = B.pv[a];
for(a = 0; a < Al; a++) {
for(b = 0; b < Bl; b++)
Cc[a+b] += Aa[a]*Bb[b];
}
for(a = 0; a < 2*L; a++)
Cc[a+1] += Cc[a]/10, Cc[a] %= 10;
int cut = (A.hl+1)+(B.hl+1);
for(a = cut, b = 0; a < 4*L && b < L; a++, b++)
C.pv[b] = Cc[a];
for(a = cut-1, b = 0; a >= 0 && b < 100; a--, b++)
C.hv[b] = Cc[a];
p = L-1, h = L-1;
while(C.pv[p] == 0 && p >= 0) p--;
while(C.hv[h] == 0 && h >= 0) h--;
C.pl = p, C.hl = h;
C.pl = p, C.hl = h;
C.neg = A.neg^B.neg;
return C;
}
int Check(int a[], int b[], int lb, int lc) {
int i;
for(i = lb-1; i >= 0; i--) {
if(a[i+lc] < b[i]) return 0;
if(a[i+lc] > b[i]) return 1;
}
return 1;
}
BigNumber divis(BigNumber A, BigNumber B) {
BigNumber C;
int Aa[3*L] = {}, Bb[3*L] = {}, Cc[4*L+1] = {};
int a, b, Al = L, Bl = 0, p, h, i, j;
for(a = 0; a < L; a++) C.pv[a] = C.hv[a] = 0;
for(a = A.hl; a >= 0; a--) Aa[Al++] = A.hv[a];
for(a = 0; a <= A.pl; a++) Aa[Al++] = A.pv[a];
for(a = B.hl; a >= 0; a--) Bb[Bl++] = B.hv[a];
for(a = 0; a <= B.pl; a++) Bb[Bl++] = B.pv[a];
Al++, Bl++;
for(i = Al-Bl; i >= 0; i--) {
while(Check(Aa, Bb, Bl, i)){
Cc[i]++;
for(j = 0; j < Bl; j++) {
Aa[i+j] -= Bb[j];
if(Aa[i+j] < 0) {
Aa[i+j] += 10;
Aa[i+j+1]--;
}
}
}
}
int cut = L - B.hl + A.hl;
for(a = cut, b = 0; a < 4*L && b < L; a++, b++)
C.pv[b] = Cc[a];
for(a = cut-1, b = 0; a >= 0 && b < L; a--, b++)
C.hv[b] = Cc[a];
p = L-1, h = L-1;
while(C.pv[p] == 0 && p >= 0) p--;
while(C.hv[h] == 0 && h >= 0) h--;
C.pl = p, C.hl = h;
C.neg = A.neg^B.neg;
return C;
}
BigNumber msqrt(BigNumber A) {
BigNumber C;
int Aa[5*L] = {}, Cc[5*L+1] = {};
int a, b, c, d, Al = L - A.hl - 1, Cl = 0, p, h;
int cut;
for(a = 0; a < L; a++) C.pv[a] = C.hv[a] = 0;
for(a = A.hl; a >= 0; a--) Aa[Al++] = A.hv[a];
for(a = 0; a <= A.pl; a++) Aa[Al++] = A.pv[a];
int B[5*L] = {}, top = Al, Bl = 1;
for(a=(Al-1)/2*2 ; a >= 0; a -= 2, Bl++) {
if(top > a+Bl-2)
for(b = 9;b >= 0;b--) {
int T[5*L]={0};
B[0]=b;
for(d=0;d <= Bl;d++) {
T[a+d] += (b*B[d]);
T[a+d+1] += (T[a+d]/10);
T[a+d] %= 10;
}
int find = 0;
for(c = Bl+a+1; c >= 0; c--)
if(Aa[c] > T[c]) {find = 1;break;}
else if(T[c] > Aa[c]) break;
if(find == 1 || c == -1) {
for(c = 0; c <= top;c++) {
Aa[c] -= T[c];
if(Aa[c]<0) {
int temp=((-Aa[c])/10+((-Aa[c])%10!=0));
Aa[c] += 10*temp;
Aa[c+1] -= temp;
}
}
break;
}
}
else b = 0;
Cc[Cl++] = b;
if(a == 100) cut = Cl;
if(top != -1) {
B[0] += b;
for(b = 0; b <= Bl+1; b++)
if(B[b] >= 10) {
B[b+1] += (B[b]/10);
B[b] %= 10;
}
else break;
for(b = Bl+1;b >= 0; b--) B[b+1] = B[b];
B[0]=0;
for(b = top;b >= 0; b--)
if(Aa[b] != 0) {top = b;break;}
if(b == -1) top = -1;
}
}
for(a = cut-1, b = 0; a >= 0 && b < L; a--, b++)
C.pv[b] = Cc[a];
for(a = cut, b = 0; a < 3*L && b < L; a++, b++)
C.hv[b] = Cc[a];
p = L-1, h = L-1;
while(C.pv[p] == 0 && p >= 0) p--;
while(C.hv[h] == 0 && h >= 0) h--;
C.pl = p, C.hl = h;
C.neg = A.neg;
return C;
}
void Print(BigNumber A) {
int a;
if(A.neg == 1) printf("-");
for(a = A.pl; a >= 0; a--)
printf("%d", A.pv[a]);
if(A.pl == -1) printf("0");
if(A.hl != -1) printf(".");
for(a = 0; a <= A.hl; a++)
printf("%d", A.hv[a]);
}
BigNumber Change(char s[]) {
int a, l = strlen(s), cut = l, b, p, h, neg = 0;
BigNumber C;
if(s[0] == '-') neg = 1;
for(a = 0; a < L; a++) C.pv[a] = C.hv[a] = 0;
for(a = neg; a < l; a++)
if(s[a] == '.') cut = a;
for(a = cut-1, b = 0; a >= neg; a--, b++)
C.pv[b] = s[a] - '0';
for(a = cut+1, b = 0; a < l; a++, b++)
C.hv[b] = s[a] - '0';
p = L-1, h = L-1;
while(C.pv[p] == 0 && p >= 0) p--;
while(C.hv[h] == 0 && h >= 0) h--;
C.pl = p, C.hl = h;
C.neg = neg;
return C;
}
main() {
char s1[200], s2[200], k[2];
printf("(1)A+B (2)A-B (3)A*B (4)A/B (5)sqrt(A)\n");
while(scanf("%s", k) == 1) {
BigNumber A, B, C;
switch(k[0]) {
case '1'...'4': {
scanf("%s %s", s1, s2);
A = Change(s1), B = Change(s2);
Print(A);
switch(k[0]) {
case '1':C = addit(A, B);printf(" + ");
break;
case '2':C = minus(A, B);printf(" - ");
break;
case '3':C = multi(A, B);printf(" * ");
break;
case '4':C = divis(A, B);printf(" / ");
break;
}
Print(B);
printf("\n = ");
Print(C);
break;
}
case '5':
scanf("%s", s1);
A = Change(s1);
C = msqrt(A);
printf("sqrt( "), Print(A);
printf(" )\n= ");
Print(C);
break;
}
puts("");
system("pause");
system("cls");
printf("(1)A+B (2)A-B (3)A*B (4)A/B (5)sqrt(A)\n");
}
system("pause");
return 0;
}
/*
1 -951.123548987 213548.2158
2 654.555 3158
3 0 10.665214
4 3.6 7
5 16.32458
*/
範例輸入 :
1 -951.123548987 213548.2158
2 654.555 3158
3 0 10.665214
4 3.6 7
5 16.32458
範例輸出 :
-951.123548987 + 213548.2158
= 212597.092251013
654.555 - 3158
= -2503.445
0 * 10.665214
= 0
3.6 / 7
= 0.51428571428571428571428571428571428571428571428571428571428571428571428571
4285714285714285714285714
sqrt( 16.32458 )
= 4.04036879504829360818257528981444228496635244984506
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define L 100
typedef struct {
char neg;
int pv[L], pl;
int hv[L], hl;
}BigNumber;
/*
123.456
pv[] = '321'
hv[] = '456'
*/
BigNumber minus(BigNumber , BigNumber );
int compare(BigNumber A, BigNumber B) {/*兩個都是正數*/
int a, h;
if(A.pl > B.pl) return 1;
if(A.pl < B.pl) return 0;
for(a = A.pl; a >=0; a--)
if(A.pv[a] > B.pv[a])
return 1;
else if(A.pv[a] < B.pv[a])
return 0;
for(a = 0; a <= A.hl && a <= B.hl; a++)
if(A.hv[a] > B.hv[a])
return 1;
else if(A.hv[a] < B.hv[a])
return 0;
if(A.hl > B.hl) return 1;
else if(A.hl < B.hl) return 0;
return 1;
}
BigNumber addit(BigNumber A, BigNumber B) {
if(A.neg == 0 && B.neg == 1) {
B.neg = 0;return minus(A, B);
}
else if(A.neg == 1 && B.neg == 0) {
A.neg = 0;return minus(B, A);
}
int a, p, h;
BigNumber C;
C.neg = A.neg;
for(a = 0; a < L; a++) C.pv[a] = C.hv[a] = 0;
for(a = 0; a <= A.pl; a++) C.pv[a] += A.pv[a];
for(a = 0; a <= B.pl; a++) C.pv[a] += B.pv[a];
for(a = 0; a <= A.hl; a++) C.hv[a] += A.hv[a];
for(a = 0; a <= B.hl; a++) C.hv[a] += B.hv[a];
h = (A.hl < B.hl) ? A.hl : B.hl;/*min*/
for(a = h; a >= 1; a--)
C.hv[a-1] += C.hv[a]/10, C.hv[a] %= 10;
C.pv[0] += C.hv[0]/10, C.hv[0] %= 10;
p = (A.hl > B.hl) ? A.hl : B.hl;/*max*/
for(a = 0; a <= p; a++)
C.pv[a+1] += C.pv[a]/10, C.pv[a] %= 10;
p = L-1, h = L-1;
while(C.pv[p] == 0 && p >= 0) p--;
while(C.hv[h] == 0 && h >= 0) h--;
C.pl = p, C.hl = h;
return C;
}
BigNumber minus(BigNumber A, BigNumber B) {
if(A.neg == 1 && B.neg == 1) {
B.neg = 0, A.neg = 0;return minus(B, A);
}
else if(A.neg == 1 && B.neg == 0) {
A.neg = 0;
BigNumber C = addit(A, B);
C.neg = 1;
return C;
}
else if(A.neg == 0 && B.neg == 1) {
B.neg = 0;return addit(A, B);
}
if(compare(A, B) == 0) {
A.neg = 0;
BigNumber C = minus(B, A);
C.neg = 1;
return C;
}
int a, p, h;
BigNumber C;
for(a = 0; a < L; a++) C.pv[a] = C.hv[a] = 0;
for(a = 0; a <= A.pl; a++) C.pv[a] = A.pv[a];
for(a = 0; a <= A.hl; a++) C.hv[a] = A.hv[a];
for(a = 0; a <= B.pl; a++) C.pv[a] -= B.pv[a];
for(a = 0; a <= B.hl; a++) C.hv[a] -= B.hv[a];
for(a = L-1; a >= 1; a--)
while(C.hv[a] < 0)
C.hv[a-1]--, C.hv[a] += 10;
while(C.hv[0] < 0)
C.pv[0]--, C.hv[0] += 10;
for(a = 0; a < L; a++)
while(C.pv[a] < 0)
C.pv[a+1]--, C.pv[a] += 10;
p = L-1, h = L-1;
while(C.pv[p] == 0 && p >= 0) p--;
while(C.hv[h] == 0 && h >= 0) h--;
C.pl = p, C.hl = h;
return C;
}
BigNumber multi(BigNumber A, BigNumber B) {
BigNumber C;
int Aa[2*L], Bb[2*L], Cc[4*L+1] = {};
int a, b, Al = 0, Bl = 0, p, h;
for(a = 0; a < L; a++) C.pv[a] = C.hv[a] = 0;
for(a = A.hl; a >= 0; a--) Aa[Al++] = A.hv[a];
for(a = 0; a <= A.pl; a++) Aa[Al++] = A.pv[a];
for(a = B.hl; a >= 0; a--) Bb[Bl++] = B.hv[a];
for(a = 0; a <= B.pl; a++) Bb[Bl++] = B.pv[a];
for(a = 0; a < Al; a++) {
for(b = 0; b < Bl; b++)
Cc[a+b] += Aa[a]*Bb[b];
}
for(a = 0; a < 2*L; a++)
Cc[a+1] += Cc[a]/10, Cc[a] %= 10;
int cut = (A.hl+1)+(B.hl+1);
for(a = cut, b = 0; a < 4*L && b < L; a++, b++)
C.pv[b] = Cc[a];
for(a = cut-1, b = 0; a >= 0 && b < 100; a--, b++)
C.hv[b] = Cc[a];
p = L-1, h = L-1;
while(C.pv[p] == 0 && p >= 0) p--;
while(C.hv[h] == 0 && h >= 0) h--;
C.pl = p, C.hl = h;
C.pl = p, C.hl = h;
C.neg = A.neg^B.neg;
return C;
}
int Check(int a[], int b[], int lb, int lc) {
int i;
for(i = lb-1; i >= 0; i--) {
if(a[i+lc] < b[i]) return 0;
if(a[i+lc] > b[i]) return 1;
}
return 1;
}
BigNumber divis(BigNumber A, BigNumber B) {
BigNumber C;
int Aa[3*L] = {}, Bb[3*L] = {}, Cc[4*L+1] = {};
int a, b, Al = L, Bl = 0, p, h, i, j;
for(a = 0; a < L; a++) C.pv[a] = C.hv[a] = 0;
for(a = A.hl; a >= 0; a--) Aa[Al++] = A.hv[a];
for(a = 0; a <= A.pl; a++) Aa[Al++] = A.pv[a];
for(a = B.hl; a >= 0; a--) Bb[Bl++] = B.hv[a];
for(a = 0; a <= B.pl; a++) Bb[Bl++] = B.pv[a];
Al++, Bl++;
for(i = Al-Bl; i >= 0; i--) {
while(Check(Aa, Bb, Bl, i)){
Cc[i]++;
for(j = 0; j < Bl; j++) {
Aa[i+j] -= Bb[j];
if(Aa[i+j] < 0) {
Aa[i+j] += 10;
Aa[i+j+1]--;
}
}
}
}
int cut = L - B.hl + A.hl;
for(a = cut, b = 0; a < 4*L && b < L; a++, b++)
C.pv[b] = Cc[a];
for(a = cut-1, b = 0; a >= 0 && b < L; a--, b++)
C.hv[b] = Cc[a];
p = L-1, h = L-1;
while(C.pv[p] == 0 && p >= 0) p--;
while(C.hv[h] == 0 && h >= 0) h--;
C.pl = p, C.hl = h;
C.neg = A.neg^B.neg;
return C;
}
BigNumber msqrt(BigNumber A) {
BigNumber C;
int Aa[5*L] = {}, Cc[5*L+1] = {};
int a, b, c, d, Al = L - A.hl - 1, Cl = 0, p, h;
int cut;
for(a = 0; a < L; a++) C.pv[a] = C.hv[a] = 0;
for(a = A.hl; a >= 0; a--) Aa[Al++] = A.hv[a];
for(a = 0; a <= A.pl; a++) Aa[Al++] = A.pv[a];
int B[5*L] = {}, top = Al, Bl = 1;
for(a=(Al-1)/2*2 ; a >= 0; a -= 2, Bl++) {
if(top > a+Bl-2)
for(b = 9;b >= 0;b--) {
int T[5*L]={0};
B[0]=b;
for(d=0;d <= Bl;d++) {
T[a+d] += (b*B[d]);
T[a+d+1] += (T[a+d]/10);
T[a+d] %= 10;
}
int find = 0;
for(c = Bl+a+1; c >= 0; c--)
if(Aa[c] > T[c]) {find = 1;break;}
else if(T[c] > Aa[c]) break;
if(find == 1 || c == -1) {
for(c = 0; c <= top;c++) {
Aa[c] -= T[c];
if(Aa[c]<0) {
int temp=((-Aa[c])/10+((-Aa[c])%10!=0));
Aa[c] += 10*temp;
Aa[c+1] -= temp;
}
}
break;
}
}
else b = 0;
Cc[Cl++] = b;
if(a == 100) cut = Cl;
if(top != -1) {
B[0] += b;
for(b = 0; b <= Bl+1; b++)
if(B[b] >= 10) {
B[b+1] += (B[b]/10);
B[b] %= 10;
}
else break;
for(b = Bl+1;b >= 0; b--) B[b+1] = B[b];
B[0]=0;
for(b = top;b >= 0; b--)
if(Aa[b] != 0) {top = b;break;}
if(b == -1) top = -1;
}
}
for(a = cut-1, b = 0; a >= 0 && b < L; a--, b++)
C.pv[b] = Cc[a];
for(a = cut, b = 0; a < 3*L && b < L; a++, b++)
C.hv[b] = Cc[a];
p = L-1, h = L-1;
while(C.pv[p] == 0 && p >= 0) p--;
while(C.hv[h] == 0 && h >= 0) h--;
C.pl = p, C.hl = h;
C.neg = A.neg;
return C;
}
void Print(BigNumber A) {
int a;
if(A.neg == 1) printf("-");
for(a = A.pl; a >= 0; a--)
printf("%d", A.pv[a]);
if(A.pl == -1) printf("0");
if(A.hl != -1) printf(".");
for(a = 0; a <= A.hl; a++)
printf("%d", A.hv[a]);
}
BigNumber Change(char s[]) {
int a, l = strlen(s), cut = l, b, p, h, neg = 0;
BigNumber C;
if(s[0] == '-') neg = 1;
for(a = 0; a < L; a++) C.pv[a] = C.hv[a] = 0;
for(a = neg; a < l; a++)
if(s[a] == '.') cut = a;
for(a = cut-1, b = 0; a >= neg; a--, b++)
C.pv[b] = s[a] - '0';
for(a = cut+1, b = 0; a < l; a++, b++)
C.hv[b] = s[a] - '0';
p = L-1, h = L-1;
while(C.pv[p] == 0 && p >= 0) p--;
while(C.hv[h] == 0 && h >= 0) h--;
C.pl = p, C.hl = h;
C.neg = neg;
return C;
}
main() {
char s1[200], s2[200], k[2];
printf("(1)A+B (2)A-B (3)A*B (4)A/B (5)sqrt(A)\n");
while(scanf("%s", k) == 1) {
BigNumber A, B, C;
switch(k[0]) {
case '1'...'4': {
scanf("%s %s", s1, s2);
A = Change(s1), B = Change(s2);
Print(A);
switch(k[0]) {
case '1':C = addit(A, B);printf(" + ");
break;
case '2':C = minus(A, B);printf(" - ");
break;
case '3':C = multi(A, B);printf(" * ");
break;
case '4':C = divis(A, B);printf(" / ");
break;
}
Print(B);
printf("\n = ");
Print(C);
break;
}
case '5':
scanf("%s", s1);
A = Change(s1);
C = msqrt(A);
printf("sqrt( "), Print(A);
printf(" )\n= ");
Print(C);
break;
}
puts("");
system("pause");
system("cls");
printf("(1)A+B (2)A-B (3)A*B (4)A/B (5)sqrt(A)\n");
}
system("pause");
return 0;
}
/*
1 -951.123548987 213548.2158
2 654.555 3158
3 0 10.665214
4 3.6 7
5 16.32458
*/