Board logo

标题: 【厉害】纯批计算圆周率,精确到小数点100位 [打印本页]

作者: plp626     时间: 2008-4-30 11:01    标题: 【厉害】纯批计算圆周率,精确到小数点100位
给大家出了个题目^_^,比较难, 没有任何实用价值,只为提供挑战平台。 [ Last edited by plp626 on 2009-11-30 at 14:33 ]

作者: plp626     时间: 2008-4-30 13:48
好久没来现在附代码如下:此贴已结!
@echo off&title 计算圆周率 by plp626@cn-dos.net
setlocal enabledelayedexpansion
if not %1.==. (set c=%1) else set c=100
set/a c=(c*100/3)+70,cc=c/10,count=0
for /l %%a in (1 1 %cc%)do set/a f_%%a=2000
for /l %%a in (%c% -132 100)do (set/a n=%%a/10,m=2*n-1
set/a "d=f_!n!*10000,f_!b!=d%%m,d=d/m,n-=1"
for /l %%b in (!n! -1 1)do (set/a n=%%b,m=2*n-1
   set/a "d=d*n+f_!n!*10000,f_!n!=d%%m,d=d/m,n-=1"
)
set/a "an=e+d/10000,e=d%%10000"
if !an! lss 1000 set an=000!an!
set/p=!an:~-4!<nul
)
echo\&echo/&set/p=数学爱好者加我QQ:************,
[ Last edited by plp626 on 2010-10-5 at 15:31 ]

作者: zh159     时间: 2008-4-30 13:58
说实话,我不知道圆周率是怎样计算的^_^

作者: Climbing     时间: 2008-4-30 14:09
呵呵,我也不知道。

作者: Climbing     时间: 2008-4-30 14:11
其实,没有所谓的纯批处理,所谓的纯只是限定用系统内置的命令(包括外部命令)。所以,只要将相关的外部命令(例如汇编程序)用批处理写入磁盘,然后调用,也就是纯批处理。这个应该不是很难吧? [ Last edited by Climbing on 2008-4-30 at 02:12 PM ]

作者: plp626     时间: 2008-4-30 14:17
...... [ Last edited by plp626 on 2008-5-1 at 06:45 PM ]

作者: plp626     时间: 2008-4-30 14:43
Originally posted by Climbing at 2008-4-30 02:11 PM: 其实,没有所谓的纯批处理,所谓的纯只是限定用系统内置的命令(包括外部命令)。所以,只要将相关的外部命令(例如汇编程序)用批处理写入磁 ...
那个可能更复杂了,你不觉得吗?set位运行,/a参数不是现成的工具吗?

作者: HAT     时间: 2008-4-30 14:43
大学里的微积分知识全都还给老师了,看到就头晕。

作者: ansipeter     时间: 2008-4-30 15:20
我都不知道圆周率是什么东西,小的中学毕业,唉,惭愧

作者: zh159     时间: 2008-4-30 15:51
网上找到的一段VBS的圆周率计算说明
Atn 函数返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧度值。此比值是该角对边的长度与邻边长度之比。 结果的范围是从 -pi/2 到 pi/2 弧度。 弧度变换为角度的方法是将弧度乘以 pi/180。反之,角度变换为弧度的方法是将角度乘以180/pi 。 下面的示例利用 Atn 来计算 pi 的值: Dim pipi = 4 * Atn(1) ' 计算 pi 的值。注意 Atn 是 Tan(将角作为参数返回直角三角形两边的比值)的反三角函数。不要混淆 Atn 与余切(正切的倒数 (1/tangent))函数。
这是一段计算圆周率的VBS,不过很费时,我的机子花了30多秒才计算了6位(Abs(t) > 0.0000001,小数点后有多少个0,就精确到多少位)
k = 1: s = 1: t = 1: m = 1
time_ = timer
While Abs(t) > 0.0000001
k = k + 2  
m = -m  
t = m / k  
s = s + t  
Wend
tt = timer - time_
MsgBox tt & vbCrLf & "圆周率π=" & 4 * s

作者: plp626     时间: 2008-4-30 16:02
C 语言的: 这个强悍,一瞬间(不到1秒)输出800位(已更正):
#include < stdio.h>
long a=10000, b, c=2800, d, e, f[2801], g; 
main(){
for(;b-c;)f[b++]=a/5; 
for(;d=0,g=c*2;c-=14,printf("%.4d",e+d/a),e=d%a) 
for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b);
} 
原帖:wangcong.org/articles/puzzle.html (上面代码和这个一样)这个大家能看懂(用的就是方案2):
#include < stdio.h>
long b, c=2800, d, e, f[2801]; 
main(){
    while(b-c!=0){
        f[b]=2000;
        b++;
        }

    while(c!=0){
        b=c;
        d=f[b]*10000;
        f[b]=d%(b*2-1);
        d=d/(b*2-1);
        --b;
        while(b!=0){
            d=d*b+f[b]*10000;
            f[b]=d%(b*2-1);
            d=d/(b*2-1);
            --b;
            }
        c-=14;
        printf("%.4d",e+d/10000);
        e=d%10000;
        }
    } 
要真想算100位小数就得有好算法,即使高级语言也不例外,C能提供的实型数据最高精度也才19位(查书),这个代码是把每步除法的的余数存放在数组里,保证不会有截断误差, 那这么看来,只要P能实现任意位数, 的两个整数除法,我们就可以用第二个方案算出Pi. ------------------------------------------------- baidu批处理吧搜的分数化小数(或循环小数即任意精度),对分子分母不超过2^30的分数可行: tieba.baidu.com/f?ct=335675392 ... 咱论坛不得不爱版主有个算整数除法的代码,支持被除数任意位数,除数不超过8位数的(102楼): www.cn-dos.net/forum/viewthrea ... 似乎达到我们的要求? [ Last edited by plp626 on 2008-4-30 at 05:04 PM ]

作者: slore     时间: 2008-4-30 16:35
C 语言的: 这个强悍,一瞬间(不到1秒)输出2800位: 代码不知道你调试了没?反正看着是有错误。代码输出的是余数?貌似全是0 for的那部分有错误。。 如果对的话,还想改成VBS看看速度呢。 zh159的VBS不要用while,直接用for i=0 to 1000000....next 这个才3秒多就14位了。 改大点就好了。 不过……貌似还是14位……还是数据类型不好呀。

作者: BWSkyer     时间: 2008-4-30 16:38
沒有看懂, 大學就沒有去學微積分~~~

作者: plp626     时间: 2008-4-30 16:42
Originally posted by slore at 2008-4-30 04:35 PM: C 语言的: 这个强悍,一瞬间(不到1秒)输出2800位: 代码不知道你调试了没?反正看着是有错误。代码输出的是余数?貌似全是0 for的那部分有 ...
调试了,有源代码,exe文件在此。 upload.cn-dos.net/img/345.rar 你没加头文件#include <stdio.h>? 我粘贴有点匆忙,现在补上了。 [ Last edited by plp626 on 2008-4-30 at 05:16 PM ]

作者: slore     时间: 2008-4-30 16:49
你看FOR语句就不对^b f[b] 不过找到了代码了。 #include <stdio.h> long a=10000,b,c=2800,d,e,f[2801],g; void main() { for(;b-c;) f[b++]=a/5; for(;d=0,g=c*2;c-=14,printf("%04d",e+d/a),e=d%a) for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b); } 但是这个是(2800/14)*4位……

作者: zh159     时间: 2008-4-30 17:11
这个VBS的很快,不过受VBS限制位数
n=100
for i = 1 to n
  str=2+(n+1-i)/((n+1-i)*2+1)*str
next
msgbox str
如果转为批处理则为:
@echo off
setlocal EnableDelayedExpansion
set str=1
for /l %%i in (100,1,1) do set/a str=2+%%i/(%%i*2+1)*!str!
echo %str%
pause
可惜set/a不能计算小数

作者: plp626     时间: 2008-4-30 17:25
Originally posted by zh159 at 2008-4-30 05:11 PM: 这个VBS的很快,不过受VBS限制位数
n=100
for i = 1 to n
  str=2+(n+1-i)/((n+1-i)*2+1)*str
next
msgbox str
如果转为批处理则为: [code]@echo off setlocal E ...
这用的就是方案2,很好,小数计算你看不得不爱版主的那个代码看怎么样?

作者: slore     时间: 2008-4-30 23:35
'将那个C的代码用VBS处理了下,速度很快,因为是 '每位用一个数处理的,所以没有位数限制。 '恩,记得用CScript调用…… Dim b, c, d, e,n, f() n = 100 '在这里定义位数 c = n / 4 * 14 ReDim f(c) For b = 0 To c f(b) = 2000 Next Do While(c) b = c d = f(b) * 10000 f(b) = d Mod (b * 2 - 1) d = d \ (b * 2 - 1) b = b - 1 Do While(b) d = d * b + f(b) * 10000 f(b) = d Mod (b * 2 - 1) d = d \ (b * 2 - 1) b = b - 1 Loop c = c - 14 i = e + d \ 10000 i = Right("0000" & i,4) If k < 10 Then k = k + 1 ShowLine = ShowLine & i Else k = 0 WSH.Echo ShowLine ShowLine = "" End If e = d Mod 10000 Loop WSH.Echo ShowLine

作者: slore     时间: 2008-4-30 23:42
数字不要太大哦~1000差不多也就1秒~ 加个0就…………
'将那个C的代码用VBS处理了下,速度很快,因为是 '每位用一个数处理的,所以没有位数限制。 '恩,记得用CScript调用…… '这个是连续运算最后输出,比一行一行的输出速度快。 Dim b, c, d, e,n, f() n = 1000 '在这里定义位数 c = n / 4 * 14 ReDim f(c) For b = 0 To c f(b) = 2000 Next Do While(c) b = c d = f(b) * 10000 f(b) = d Mod (b * 2 - 1) d = d \ (b * 2 - 1) b = b - 1 Do While(b) d = d * b + f(b) * 10000 f(b) = d Mod (b * 2 - 1) d = d \ (b * 2 - 1) b = b - 1 Loop c = c - 14 i = e + d \ 10000 i = Right("0000" & i,4) If k < 10 Then k = k + 1 ShowLine = ShowLine & i Else k = 0 'WSH.Echo ShowLine ShowLine = ShowLine & vbCrLf End If e = d Mod 10000 Loop WSH.Echo ShowLine

作者: slore     时间: 2008-4-30 23:50
恩,这个算法没有浮点运算哦~ +-*/取余运算。 有功夫的试这改成BAT吧。 没有看最大的数是多少,希望BAT可以支持到。

作者: xtanbmy     时间: 2008-5-1 03:51
好牛X,膜拜了!

作者: xtanbmy     时间: 2008-5-1 03:52
大虾们,能不能把结果输出到一个文本文件中呀?

作者: slore     时间: 2008-5-1 08:39
Originally posted by xtanbmy at 2008-5-1 03:52: 大虾们,能不能把结果输出到一个文本文件中呀?
把SHOWLINE前的echo换成FSO对象,文本读写操作的对象,然后write下…… 在CSCRIPT下可以复制结果嘛。。。

作者: PPdos     时间: 2008-5-1 08:54
古算术法
355/113=3.1415926535897...

作者: slore     时间: 2008-5-1 09:03
Originally posted by PPdos at 2008-5-1 08:54: 古算术法
=。= 你自己打的吧?还是我的CALC有问题呢?

作者: zh159     时间: 2008-5-1 10:13
Originally posted by PPdos at 2008-5-1 08:54: 古算术法
这个只能精确到6位

作者: 26933062     时间: 2008-5-2 12:02
弱弱的问一句,圆周率 可以理解为 a 除以 b 吗?是两个正整数吗? 貌似那个 1 除以 2003 的代码可以更简单,精确到 任意位小数。(cmd 范围内)

作者: slore     时间: 2008-5-2 12:15
不存在a/b=Pi的a和b的值……

作者: 26933062     时间: 2008-5-2 12:19
难怪我看到网上说用 22除以7 ,我用计算器算结果却不对。。

作者: terse     时间: 2008-5-2 12:45
if "π"=="无理的数" echo π 不可以用分数来表示

作者: lena     时间: 2008-5-2 21:35
3.1415%%%%%%%%%%%%%%%%%%%

作者: knoppix7     时间: 2008-5-2 22:01
分数都是近似的...不过还是得感谢那些算出这些分数的前辈..

作者: 523066680     时间: 2008-8-22 09:18
那大家求一下,用批处理求值类似于圆周率的分数