新闻资讯
看你所看,想你所想

梅钦公式

梅钦公式

梅钦公式是一个至今仍被广泛套用的计算 π 值的公式。

基本介绍

  • 中文名:梅钦公式
  • 外文名:Machin formula

简介

1706年,英国人 约翰·梅钦( John Machin) 发明了一个用于计算
值的公式:
或者写为:
梅钦公式是格里高利/莱布尼茨计算
的公式的变体,但是更实用,它的收敛速度显着增加,这使得它成为了更实用的计算
的方法,虽然有若干种类梅钦(Machin-like)公式,但梅钦公式至今仍然是计算
值的主要公式。

实现

这里给出一种 JavaScript 实现,如下:
/** @Author: suifengtec* @Date:   2017-08-22 05:40:48* @Last Modified by:   suifengtec* @Last Modified time: 2017-08-23 03:18:37**//*用JavaScript 和 梅钦公式计算 PI。使用node pi.js */var getPi = (function () {    function getPi(space) {        this.aX = [];        this.cellSize = 11;           this.tStart = new Date();        this.spaceStr = space ? space : "  ";        this.aBigInt = Math.pow(10, this.cellSize);    }    getPi.prototype.getIt = function (length) {        var digitsLenAfterDot = Number(length);        var cellSize = this.cellSize;        var coeff = Array(10),         iAng = Array(10);        var arrLen = Math.ceil(1 + digitsLenAfterDot / cellSize);        var aPI = Array(arrLen);        var aArctan = Array(arrLen);        coeff[0] = 4;        coeff[1] = -1;        coeff[2] = 0;        iAng[0] = 5;        iAng[1] = 239;        iAng[2] = 0;        aPI = this.makeArr(arrLen, aPI, 0);        for (var i = 0; coeff[i] != 0; i++) {            aArctan = this.getArcTan(iAng[i], arrLen, aArctan);            aArctan = this.Mul(arrLen, aArctan, Math.abs(coeff[i]));            if (coeff[i] > 0) {                aPI = this.Add(arrLen, aPI, aArctan);            }            else {                aPI = this.Sub(arrLen, aPI, aArctan);            }        }        aPI = this.Mul(arrLen, aPI, 4);        var sPI = "3.";          var tempPI = "";        for (var i = 0; i < aPI.length; i++) {            aPI[i] = String(aPI[i]);            if (aPI[i].length < cellSize && i != 0) {                while (aPI[i].length < cellSize) {                    aPI[i] = "0" + aPI[i];                }            }            tempPI += aPI[i];        }        for (var i = 0; i + 1 <= digitsLenAfterDot; i++) {            if (i == 0) {                sPI += tempPI.charAt(i + 1);            }            else {                var newLineSymbol = this.spaceStr, spForPer5Digits = this.spaceStr;                if ((i + 1) % 50 == 0 && i != 0) {                    sPI += tempPI.charAt(i + 1) + newLineSymbol;                }                else {                    if ((i + 1) % 5 == 0) {                        sPI += tempPI.charAt(i + 1) + spForPer5Digits;                    }                    else {                        sPI += tempPI.charAt(i + 1);                    }                }            }        }        var tShutdown = new Date();        var timeTaken = (tShutdown.getTime() - this.tStart.getTime()) / 1000;        var timeSp = "耗时: " + timeTaken + " 秒";        return sPI + " \n" + timeSp;    };    getPi.prototype.Mul = function (n, aX, iMult) {        var carry = 0;        var prod;        for (var i = n - 1; i >= 0; i--) {            prod = (aX[i]) * iMult;            prod += carry;            if (prod >= this.aBigInt) {                carry = Math.floor(prod / this.aBigInt);                prod -= (carry * this.aBigInt);            }            else {                carry = 0;            }            aX[i] = prod;        }        return aX;    };    getPi.prototype.Div = function (n, aX, iDiv, aY) {        var carry = 0;        var currVal;        var theDiv;        for (var i = 0; i < n; i++) {            currVal = Number(aX[i]) + Number(carry * this.aBigInt);            theDiv = Math.floor(currVal / iDiv);            carry = currVal - theDiv * iDiv;            aY[i] = theDiv;        }        return aY;    };    getPi.prototype.Add = function (n, aX, aY) {        var carry = 0;        for (var i = n - 1; i >= 0; i--) {            aX[i] += Number(aY[i]) + Number(carry);            if (aX[i] < this.aBigInt) {                carry = 0;            }            else {                carry = 1;                aX[i] = Number(aX[i]) - Number(this.aBigInt);            }        }        return aX;    };    getPi.prototype.Sub = function (n, aX, aY) {        for (var i = n - 1; i >= 0; i--) {            aX[i] -= aY[i];            if (aX[i] < 0) {                if (i > 0) {                    aX[i] += this.aBigInt;                    aX[i - 1]--;                }            }        }        return aX;    };    getPi.prototype.isEmpty = function (aX) {        var empty = true;        for (var i = 0; i < aX.length; i++) {            if (aX[i]) {                empty = false;                break;            }        }        return empty;    };    getPi.prototype.getArcTan = function (iAng, n, aX) {        var iAng_squared = iAng * iAng;        var k = 3;        var sign = 0;        var arrAngle = [];        var aDivK = [];        aX = this.makeArr(n, aX, 0);         arrAngle = this.makeArr(n, arrAngle, 1);        arrAngle = this.Div(n, arrAngle, iAng, arrAngle);        aX = this.Add(n, aX, arrAngle);        while (!this.isEmpty(arrAngle)) {            arrAngle = this.Div(n, arrAngle, iAng_squared, arrAngle);                       aDivK = this.Div(n, arrAngle, k, aDivK);             if (sign) {                aX = this.Add(n, aX, aDivK);             }            else {                aX = this.Sub(n, aX, aDivK);            }            k += 2;            sign = 1 - sign;        }        return aX;    };    getPi.prototype.makeArr = function (n1, arr, n2) {        for (var i = 0; i < n1; i++) {            arr[i] = null;        }        arr[0] = n2;        return arr;    };    return getPi;}());/*tsc pi.ts && node pi.js验证3.14159 26535 89793 23846 26433 83279 50288 41971 69399 37510 58209 74944 59230 78164 06286 20899 86280 34825 34211 70679计算所得(小数点后100位)3.14159 26535 89793 23846 26433 83279 50288 41971 69399 37510 58209 74944 59230 78164 06286 20899 86280 34825 34211 70679耗时: 0.001 秒 */var spaceSymbol = "  ";var app = new getPi(spaceSymbol);var pi = app.getIt(100);console.log(pi);
上述实现一般情况下计算出来的精确度大于 JavaSript 的浮点数允许的精确值, 所以仅能以字元串形式输出,不能参与运算。

转载请注明出处安可林文章网 » 梅钦公式

相关推荐

    声明:此文信息来源于网络,登载此文只为提供信息参考,并不用于任何商业目的。如有侵权,请及时联系我们:fendou3451@163.com