实验4 超越祖冲之
简介
中国数学家刘徽在注释《九章算术》(公元263年)时只用圆内接正多边形就求得π的近似值,也得出精确到两位小数的π值,他的方法被后人称为割圆术。他用割圆术一直算到圆内接正192边形。
南北朝时代的数学家祖冲之(公元429年—公元500年)进一步得出精确到小数点后7位的π值(约5世纪下半叶),给出不足近似值3.1415926和过剩近似值3.1415927,还得到两个近似分数值,密率355/113和约率22/7。其中,密率在西方直到公元1573年才由德国人奥托得到,并于1625年发表于荷兰工程师安托尼斯的著作中,欧洲称之为安托尼斯率。
计算机的快速发展使π的精度越来越高,那么怎么通过计算机计算π值呢?在上一个实验当中,N个线段画出了一个圆形,所以可以把这些线段的总长度除以圆的直径,得出π的大小。
使用公式:
π=C /d
其中,C是圆的周长,d是圆的直径。
在支持HTML5的浏览器里运行下面代码:
<canvasid="myCanvas"width="480"height="300"style="border: 1px solid #c3c3c3;"> Your browser does not support the canvas element. </canvas> <scripttype="text/javascript"> var c=document.getElementById("myCanvas"); var cxt=c.getContext("2d"); var x=150; var y=150; var r=100; var girth=0; for (var i=x-r; i < x+r+1; i +=1) { var tempY1=Math.pow(r * r-(x-i) * (x-i), 1 / 2); \注:这里代表x坐标\ cxt.lineTo(i, y+tempY1); var tempX=r * r-(x-i+1) * (x-i+1); var tempY2=Math.pow(r * r-(x-i+1) * (x-i+1), 1 / 2); \注:这里的+1代表下一个x坐标\ var temp=getLengthOfTwoPoint({ x: i-1, y: tempY2 }, { x: i, y: tempY1 }); if (tempX >=0) { girth +=temp; } } alert("π的是值为:"+girth / r) function getLengthOfTwoPoint(startPoint, endPoint) { \注:用于求两点之间的距离\ var calX=Math.abs(startPoint.x-endPoint.x); var calY=Math.abs(startPoint.y-endPoint.y); return Math.pow((calX * calX+calY * calY), 0.5); } </script>
上面的计算方法是把半个圆上的每段相邻两点之间的距离求和,然后除以r得出π的值。运行之后发现π的值为:3.1412985671602183,和标准的3.1415926535897932384626433 832795028841971693993751058209749相差甚远。
如何修改上面的代码,提高精确度呢?数学家祖冲之得出了精确到小数点后7位,我们能超过他吗?
因为是用的N条线段模拟圆,只要N越大,就越接近圆。所以可以增大半径r,这样需要的线段越多,求出的π就越接近标准值。将r增大至400000:
var c=document.getElementById("myCanvas"); var cxt=c.getContext("2d"); var x=150; var y=150; var r=400000; var girth=0; for (var i=x-r; i < x+r+1; i +=1) { var tempY1=Math.pow(r * r-(x-i) * (x-i), 1 / 2); cxt.lineTo(i, y+tempY1); var tempX=r * r-(x-i+1) * (x-i+1); var tempY2=Math.pow(r * r-(x-i+1) * (x-i+1), 1 / 2); var temp=getLengthOfTwoPoint({ x: i-1, y: tempY2 }, { x: i, y: tempY1 }); if (tempX >=0) { girth +=temp; } } alert("π的是值为:"+girth / r) function getLengthOfTwoPoint(startPoint, endPoint) { var calX=Math.abs(startPoint.x-endPoint.x); var calY=Math.abs(startPoint.y-endPoint.y); return Math.pow((calX * calX+calY * calY), 0.5); }
结果如图1-18所示。
图1-18 计算机计算的π值
可以看到,我们得到的π值小数点后前8位是准确的。