2011-08-02 21:50:36Morris
[手動][大數][三角函數] sin x 運算
sin x = x - x 3 / 3! + x 5 / 5! - x 7 / 7! + ...
for all x.
x 單位是弧度,
下面程式碼是我自己做的, 有錯誤的話, 請多多包涵, 由於只會做到 x^499/499!
所以 x 不能太大, 不然收斂不到, 我沒有做同餘的處理, 請多多包涵
範例輸入:
-0.523593766666666666666666666666666666666666666666666666 //-30度
50
範例輸出:
-0.49999566213168835891110783336543526239570962009857942732098781699100110611002
57315819223394605303886564414913897841757255904112772246821605497279605025577762
9952351298307494694247274622940860856025771
-0.26237485370392878591439364691262254588666596497123852294393559241445895258995
07517889236912853523696585990137026532086111068236521550086251743962915519539144
6454176291446477811029972808232469547290065
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define L 1000
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 = 200 - 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 == 200) 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 < 200; 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 x[200], y[20];
while(scanf("%s", x) == 1) {
BigNumber s1, s2, Ans, A;
sprintf(y, "%d", 1);
s1 = Change(x), s2 = Change(y);
A = s1;
sprintf(y, "%d", 0);
Ans = Change(y);
int a, t = 0;
for(a = 1; a < 500; a += 2, t = 1-t) {
if(t == 0)
Ans = addit(Ans, divis(s1, s2));
else
Ans = minus(Ans, divis(s1, s2));
/*Print(s1);
puts("");
Print(s2);
puts("");*/
s1 = multi(A, multi(s1, A));
sprintf(y, "%d", (a+1)*(a+2));
s2 = multi(s2, Change(y));
}
Print(Ans);
puts("");
}
system("pause");
return 0;
}
/*
-0.523593766666666666666666666666666666666666666666666666
*/
x 單位是弧度,
下面程式碼是我自己做的, 有錯誤的話, 請多多包涵, 由於只會做到 x^499/499!
所以 x 不能太大, 不然收斂不到, 我沒有做同餘的處理, 請多多包涵
範例輸入:
-0.523593766666666666666666666666666666666666666666666666 //-30度
50
範例輸出:
-0.49999566213168835891110783336543526239570962009857942732098781699100110611002
57315819223394605303886564414913897841757255904112772246821605497279605025577762
9952351298307494694247274622940860856025771
-0.26237485370392878591439364691262254588666596497123852294393559241445895258995
07517889236912853523696585990137026532086111068236521550086251743962915519539144
6454176291446477811029972808232469547290065
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define L 1000
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 = 200 - 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 == 200) 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 < 200; 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 x[200], y[20];
while(scanf("%s", x) == 1) {
BigNumber s1, s2, Ans, A;
sprintf(y, "%d", 1);
s1 = Change(x), s2 = Change(y);
A = s1;
sprintf(y, "%d", 0);
Ans = Change(y);
int a, t = 0;
for(a = 1; a < 500; a += 2, t = 1-t) {
if(t == 0)
Ans = addit(Ans, divis(s1, s2));
else
Ans = minus(Ans, divis(s1, s2));
/*Print(s1);
puts("");
Print(s2);
puts("");*/
s1 = multi(A, multi(s1, A));
sprintf(y, "%d", (a+1)*(a+2));
s2 = multi(s2, Change(y));
}
Print(Ans);
puts("");
}
system("pause");
return 0;
}
/*
-0.523593766666666666666666666666666666666666666666666666
*/