HTML5实验室
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

实验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位是准确的。