请用pl/sql实现高精度输出pi1万位

[复制链接]
查看11 | 回复9 | 2012-5-21 10:19:41 | 显示全部楼层 |阅读模式
算法参考
http://www.itpub.net/viewthread. ... &extra=page%3D1
回复

使用道具 举报

千问 | 2012-5-21 10:19:41 | 显示全部楼层

create or replace procedure pi as
TYPE tint IS TABLE OF PLS_INTEGER;
s tint := tint();
r1 tint := tint();
r2 tint := tint();
r3 tint := tint();
r4 tint := tint();
d1 tint := tint();
d2 NUMBER;
d3 tint := tint();
d4 NUMBER;
N CONSTANT NUMBER :=7200;
M CONSTANT NUMBER :=10000;
B CONSTANT NUMBER :=10000;
L CONSTANT NUMBER :=4;
t number;
p number;
mp number;
tag number;
begin
s.EXTEND(trunc(M/L));
r1.EXTEND(N);
r2.EXTEND(N);
r3.EXTEND(N);
r4.EXTEND(N);
d1.EXTEND(N);
d3.EXTEND(N);
FOR I IN 1..N LOOP
r1(i):=0; r2(i):=0; r3(i):=0; r4(i):=0; d1(i):=0; d3(i):=0;
end loop;
mp:=trunc(M/L/20);
r1(1):=1; r1(2):=3; r3(1):=4;
FOR k IN 1..trunc(M/L)-1 LOOP

t:=r1(1)*B;

d1(1):=trunc(t/5);

r1(1):=mod(t,5);

t:=r3(1)*B;

d3(1):=trunc(t/239);

r3(1):=mod(t,239);

s(k):=d1(1)-d3(1);

tag:=0;

for i in 2..N-1 loop

t:=r1(i)*B+d1(i-1);

d1(i):=trunc(t/25);

r1(i):=mod(t,25);

t:=r2(i)*B+d1(i);

d2:=trunc(t/(2*i+1));

r2(i):=mod(t,(2*i+1));

t:=r3(i)*B+d3(i-1);

d3(i):=trunc(t/57121);

r3(i):=mod(t,57121);

t:=r4(i)*B+d3(i);

d4:=trunc(t/(2*i+1));

r4(i):=mod(t,(2*i+1));

if tag=1 then

s(k):=s(k)+(d2-d4);

tag:=0;

else

s(k):=s(k)+(d4-d2);

tag:=1;

end if;

end loop;

if p=mp then

p:=0;

else

p:=p+1;

end if;

end loop;
for i in REVERSEtrunc(M/L)..1 loop

while s(i)>=B loop

s(i-1):=s(i-1)+1;

s(i):=s(i)-B;

end loop;

while s(i)
int main(int argc, char* argv[])
{
int const N=7200;
int const M=10000;
int const B=10000;
int const L=4;
// Machin公式 计算pi到一万位
int s[M/L];
int r1[N]={0},r2[N]={0},d1[N]={0},d2;
int r3[N]={0},r4[N]={0},d3[N]={0},d4;
int i,k,t,p=0,mp=M/L/20;
r1[0]=1;
r1[1]=3;
r3[0]=4;
printf("正在计算,请等待\n____________________\n");
for(k=0;k");

p=0;

}

else

p++;
}
for(i=M/L-1;i>=0;i--)
{

while(s>=B)

{

s[i-1]++;

s-=B;

}

while(s复制代码
回复

使用道具 举报

千问 | 2012-5-21 10:19:41 | 显示全部楼层
很牛很变态


回复

使用道具 举报

千问 | 2012-5-21 10:19:41 | 显示全部楼层
知识点,reverse 后面的仍然要小的在前,大的在后
create or replace procedure pi as
TYPE tint IS TABLE OF PLS_INTEGER;
s tint := tint();
r1 tint := tint();
r2 tint := tint();
r3 tint := tint();
r4 tint := tint();
d1 tint := tint();
d2 NUMBER;
d3 tint := tint();
d4 NUMBER;
N CONSTANT NUMBER :=7200;
M CONSTANT NUMBER :=10000;
B CONSTANT NUMBER :=10000;
L CONSTANT NUMBER :=4;
t number;
p number;
mp number;
tag number;
i number;
begin
s.EXTEND(trunc(M/L));
r1.EXTEND(N);
r2.EXTEND(N);
r3.EXTEND(N);
r4.EXTEND(N);
d1.EXTEND(N);
d3.EXTEND(N);
FOR I IN 1..N LOOP
r1(i):=0; r2(i):=0; r3(i):=0; r4(i):=0; d1(i):=0; d3(i):=0;
end loop;
mp:=trunc(M/L/20);
r1(1):=1; r1(2):=3; r3(1):=4;
FOR k IN 1..trunc(M/L) LOOP

t:=r1(1)*B;

d1(1):=trunc(t/5);

r1(1):=mod(t,5);

t:=r3(1)*B;

d3(1):=trunc(t/239);

r3(1):=mod(t,239);

s(k):=d1(1)-d3(1);

--dbms_output.put('k('||k||')='||to_char(s(k),'0999'));

--if mod(k,10)=0 then

--dbms_output.put_line(' ');

--end if;

tag:=0;

for i in 2..N loop

t:=r1(i)*B+d1(i-1);

d1(i):=trunc(t/25);

r1(i):=mod(t,25);

t:=r2(i)*B+d1(i);

d2:=trunc(t/(2*i-1));

r2(i):=mod(t,(2*i-1));

t:=r3(i)*B+d3(i-1);

d3(i):=trunc(t/57121);

r3(i):=mod(t,57121);

t:=r4(i)*B+d3(i);

d4:=trunc(t/(2*i-1));

r4(i):=mod(t,(2*i-1));

if tag=1 then

s(k):=s(k)+(d2-d4);

tag:=0;

else

s(k):=s(k)+(d4-d2);

tag:=1;

end if;

end loop;

if p=mp then

p:=0;

else

p:=p+1;

end if;

end loop;
for i in REVERSE 1.. trunc(M/L) loop

while s(i)>=B loop

s(i-1):=s(i-1)+1;

s(i):=s(i)-B;

end loop;

while s(i)复制代码
SQL> exec pi
3.
1415 9265 3589 7932 3846 2643 3832 7950 2884 1971
6939 9375 1058 2097 4944 5923 0781 6406 2862 0899
8628 0348 2534 2117 0679 8214 8086 5132 8230 6647
0938 4460 9550 5822 3172 5359 4081 2848 1117 4502
8410 2701 9385 2110 5559 6446 2294 8954 9303 8196
4428 8109 7566 5933 4461 2847 5648 2337 8678 3165
2712 0190 9145 6485 6692 3460 3486 1045 4326 6482
1339 3607 2602 4914 1273 7245 8700 6606 3155 8817
4881 5209 2096 2829 2540 9171 5364 3678 9259 0360
0113 3053 0548 8204 6652 1384 1469 5194 1511 6094
3305 7270 3657 5959 1953 0921 8611 7381 9326 1179
3105 1185 4807 4462 3799 6274 9567 3518 8575 2724
8912 2793 8183 0119 4912 9833 6733 6244 0656 6430
8602 1394 9463 9522 4737 1907 0217 9860 9437 0277
0539 2171 7629 3176 7523 8467 4818 4676 6940 5132
0005 6812 7145 2635 6082 7785 7713 4275 7789 6091
7363 7178 7214 6844 0901 2249 5343 0146 5495 8537
1050 7922 7968 9258 9235 4201 9956 1121 2902 1960
8640 3441 8159 8136 2977 4771 3099 6051 8707 2113
4999 9998 3729 7804 9951 0597 3173 2816 0963 1859
5024 4594 5534 6908 3026 4252 2308 2533 4468 5035
2619 3118 8171 0100 0313 7838 7528 8658 7533 2083
8142 0617 1776 6914 7303 5982 5349 0428 7554 6873
1159 5628 6388 2353 7875 9375 1957 7818 5778 0532
1712 2680 6613 0019 2787 6611 1959 0921 6420 1989
3809 5257 2010 6548 5863 2788 6593 6153 3818 2796
8230 3019 5203 5301 8529 6899 5773 6225 9941 3891
2497 2177 5283 4791 3151 5574 8572 4245 4150 6959
5082 9533 1168 6172 7855 8890 7509 8381 7546 3746
4939 3192 5506 0400 9277 0167 1139 0098 4882 4012
8583 6160 3563 7076 6010 4710 1819 4295 5596 1989
4676 7837 4494 4825 5379 7747 2684 7104 0475 3464
6208 0466 8425 9069 4912 9331 3677 0289 8915 2104
7521 6205 6966 0240 5803 8150 1935 1125 3382 4300
3558 7640 2474 9647 3263 9141 9927 2604 2699 2279
6782 3547 8163 6009 3417 2164 1219 9245 8631 5030
2861 8297 4555 7067 4983 8505 4945 8858 6926 9956
BEGIN pi; END;
*
ERROR 位于第 1 行:
ORA-20000: ORU-10027: buffer overflow, limit of 2000 bytes
ORA-06512: 在"SYS.DBMS_OUTPUT", line 35
ORA-06512: 在"SYS.DBMS_OUTPUT", line 198
ORA-06512: 在"SYS.DBMS_OUTPUT", line 139
ORA-06512: 在"LT.PI", line 92
ORA-06512: 在line 1

已用时间:00: 02: 41.07
回复

使用道具 举报

千问 | 2012-5-21 10:19:41 | 显示全部楼层
set serverout on size unlimit就能全部输出了
最后1步用while 可能不如mod高效
回复

使用道具 举报

千问 | 2012-5-21 10:19:41 | 显示全部楼层
9276 4579 3106 5792 2955 2498 8727 5846 1012 6483
6999 8922 5695 9688 1592 0560 0101 6552 5637 5662
PL/SQL 过程已成功完成。
已用时间:00: 00: 57.45
create or replace procedure pi as
TYPE tint IS TABLE OF PLS_INTEGER;
s tint := tint();
r1 tint := tint();
r2 tint := tint();
r3 tint := tint();
r4 tint := tint();
d1 tint := tint();
d2 NUMBER;
d3 tint := tint();
d4 NUMBER;
N CONSTANT NUMBER :=7200;
M CONSTANT NUMBER :=10000;
B CONSTANT NUMBER :=10000;
L CONSTANT NUMBER :=4;
t number;
p number;
mp number;
tag number;
i number;
begin
s.EXTEND(trunc(M/L));
r1.EXTEND(N);
r2.EXTEND(N);
r3.EXTEND(N);
r4.EXTEND(N);
d1.EXTEND(N);
d3.EXTEND(N);
FOR I IN 1..N LOOP
r1(i):=0; r2(i):=0; r3(i):=0; r4(i):=0; d1(i):=0; d3(i):=0;
end loop;
mp:=trunc(M/L/20);
r1(1):=1; r1(2):=3; r3(1):=4;
FOR k IN 1..trunc(M/L) LOOP

t:=r1(1)*B;

d1(1):=trunc(t/5);

r1(1):=mod(t,5);

t:=r3(1)*B;

d3(1):=trunc(t/239);

r3(1):=mod(t,239);

s(k):=d1(1)-d3(1);

--dbms_output.put('k('||k||')='||to_char(s(k),'0999'));

--if mod(k,10)=0 then

--dbms_output.put_line(' ');

--end if;

tag:=0;

for i in 2..N loop

t:=r1(i)*B+d1(i-1);

d1(i):=trunc(t/25);

r1(i):=mod(t,25);

t:=r2(i)*B+d1(i);

d2:=trunc(t/(2*i-1));

r2(i):=mod(t,(2*i-1));

t:=r3(i)*B+d3(i-1);

d3(i):=trunc(t/57121);

r3(i):=mod(t,57121);

t:=r4(i)*B+d3(i);

d4:=trunc(t/(2*i-1));

r4(i):=mod(t,(2*i-1));

if tag=1 then

s(k):=s(k)+(d2-d4);

tag:=0;

else

s(k):=s(k)+(d4-d2);

tag:=1;

end if;

end loop;

if p=mp then

p:=0;

else

p:=p+1;

end if;

end loop;
for i in REVERSE 2.. trunc(M/L) loop
/* while s(i)>=B loop

s(i-1):=s(i-1)+1;

s(i):=s(i)-B;

end loop;

while s(i)复制代码
21:33:29 SQL> alter procedure pi compile PLSQL_code_type=native;
过程已更改。
已用时间:00: 00: 00.16
21:33:42 SQL> exec pi;
3.
1415 9265 3589 7932 3846 2643 3832 7950 2884 1971
。。。
9276 4579 3106 5792 2955 2498 8727 5846 1012 6483
6999 8922 5695 9688 1592 0560 0101 6552 5637 5662
PL/SQL 过程已成功完成。
已用时间:00: 00: 49.79
回复

使用道具 举报

千问 | 2012-5-21 10:19:41 | 显示全部楼层
不知道减少L能否计算正确
回复

使用道具 举报

千问 | 2012-5-21 10:19:41 | 显示全部楼层

create or replace procedure pi as
TYPE tint IS TABLE OF NUMBER;
s tint := tint();
r1 tint := tint();
r2 tint := tint();
r3 tint := tint();
r4 tint := tint();
d1 tint := tint();
d2 NUMBER;
d3 tint := tint();
d4 NUMBER;
N CONSTANT NUMBER :=7200;
M CONSTANT NUMBER :=10000;
B CONSTANT NUMBER :=100000000;
L CONSTANT NUMBER :=8;
t number;
p number;
mp number;
tag number;
i number;
begin
s.EXTEND(trunc(M/L));
r1.EXTEND(N);
r2.EXTEND(N);
r3.EXTEND(N);
r4.EXTEND(N);
d1.EXTEND(N);
d3.EXTEND(N);
FOR I IN 1..N LOOP
r1(i):=0; r2(i):=0; r3(i):=0; r4(i):=0; d1(i):=0; d3(i):=0;
end loop;
mp:=trunc(M/L/20);
r1(1):=1; r1(2):=3; r3(1):=4;
FOR k IN 1..trunc(M/L) LOOP

t:=r1(1)*B;

d1(1):=trunc(t/5);

r1(1):=mod(t,5);

t:=r3(1)*B;

d3(1):=trunc(t/239);

r3(1):=mod(t,239);

s(k):=d1(1)-d3(1);

--dbms_output.put('k('||k||')='||to_char(s(k),'0999'));

--if mod(k,10)=0 then

--dbms_output.put_line(' ');

--end if;

tag:=0;

for i in 2..N loop

t:=r1(i)*B+d1(i-1);

d1(i):=trunc(t/25);

r1(i):=mod(t,25);

t:=r2(i)*B+d1(i);

d2:=trunc(t/(2*i-1));

r2(i):=mod(t,(2*i-1));

t:=r3(i)*B+d3(i-1);

d3(i):=trunc(t/57121);

r3(i):=mod(t,57121);

t:=r4(i)*B+d3(i);

d4:=trunc(t/(2*i-1));

r4(i):=mod(t,(2*i-1));

if tag=1 then

s(k):=s(k)+(d2-d4);

tag:=0;

else

s(k):=s(k)+(d4-d2);

tag:=1;

end if;

end loop;

if p=mp then

p:=0;

else

p:=p+1;

end if;

end loop;
for i in REVERSE 2.. trunc(M/L) loop
/* while s(i)>=B loop

s(i-1):=s(i-1)+1;

s(i):=s(i)-B;

end loop;

while s(i)复制代码
21:41:25 SQL> alter procedure pi compile PLSQL_code_type=native;
过程已更改。
已用时间:00: 00: 00.07
21:41:27 SQL> exec pi;
3.
14159265 35897932 38462643 38327950 28841971 69399375 10582097 49445923 07816406
28620899
....
92764579 31065792 29552498 87275846 10126483 69998922 56959688 15920560 01016552
56375662
PL/SQL 过程已成功完成。
已用时间:00: 00: 19.46
回复

使用道具 举报

千问 | 2012-5-21 10:19:41 | 显示全部楼层
估计大部分时间都用在输出了吧?
回复

使用道具 举报

千问 | 2012-5-21 10:19:41 | 显示全部楼层
oracle的高精度计算减少了迭代次数
create or replace procedure pi as
TYPE tint IS TABLE OF NUMBER;
s tint := tint();
r1 tint := tint();
r2 tint := tint();
r3 tint := tint();
r4 tint := tint();
d1 tint := tint();
d2 NUMBER;
d3 tint := tint();
d4 NUMBER;
N CONSTANT NUMBER :=7200;
M CONSTANT NUMBER :=10000;
B CONSTANT NUMBER :=1E32;
L CONSTANT NUMBER :=32;
t number;
p number;
mp number;
tag number;
i number;
begin
s.EXTEND(trunc(M/L));
r1.EXTEND(N);
r2.EXTEND(N);
r3.EXTEND(N);
r4.EXTEND(N);
d1.EXTEND(N);
d3.EXTEND(N);
FOR I IN 1..N LOOP
r1(i):=0; r2(i):=0; r3(i):=0; r4(i):=0; d1(i):=0; d3(i):=0;
end loop;
mp:=trunc(M/L/20);
r1(1):=1; r1(2):=3; r3(1):=4;
FOR k IN 1..trunc(M/L) LOOP

t:=r1(1)*B;

d1(1):=trunc(t/5);

r1(1):=mod(t,5);

t:=r3(1)*B;

d3(1):=trunc(t/239);

r3(1):=mod(t,239);

s(k):=d1(1)-d3(1);

--dbms_output.put('k('||k||')='||to_char(s(k),'0999'));

--if mod(k,10)=0 then

--dbms_output.put_line(' ');

--end if;

tag:=0;

for i in 2..N loop

t:=r1(i)*B+d1(i-1);

d1(i):=trunc(t/25);

r1(i):=mod(t,25);

t:=r2(i)*B+d1(i);

d2:=trunc(t/(2*i-1));

r2(i):=mod(t,(2*i-1));

t:=r3(i)*B+d3(i-1);

d3(i):=trunc(t/57121);

r3(i):=mod(t,57121);

t:=r4(i)*B+d3(i);

d4:=trunc(t/(2*i-1));

r4(i):=mod(t,(2*i-1));

if tag=1 then

s(k):=s(k)+(d2-d4);

tag:=0;

else

s(k):=s(k)+(d4-d2);

tag:=1;

end if;

end loop;

if p=mp then

p:=0;

else

p:=p+1;

end if;

end loop;
for i in REVERSE 2.. trunc(M/L) loop
/* while s(i)>=B loop

s(i-1):=s(i-1)+1;

s(i):=s(i)-B;

end loop;

while s(i)复制代码
PL/SQL 过程已成功完成。
已用时间:00: 00: 05.34
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行