欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JavaScript实现计算圆周率到小数点后100位的方法示例

程序员文章站 2022-06-24 23:07:06
本文实例讲述了javascript实现计算圆周率到小数点后100位的方法。分享给大家供大家参考,具体如下: 浮点数的有效数位是16位,我自己做了一个大数类,能存储100位...

本文实例讲述了javascript实现计算圆周率到小数点后100位的方法。分享给大家供大家参考,具体如下:

浮点数的有效数位是16位,我自己做了一个大数类,能存储100位有效数位,并实现了大数类的基本运算。我用它来计算圆周率(割圆法,即多边形逼近),得到了小数点后一百位有效数字,比对了machin 公式的计算结果,没有误差。用时约2秒。

完整示例如下:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>www.jb51.net js计算圆周率</title>
</head>
<body>
<script>
<!--
function bignum(str, n, b)
{
  /*
   bignum -- 大数类
   私有成员:
         data -- 119 位数字,放在长度为 17 的数组里,每个数组元素存放 7 位数字。
         decimal_place -- 小数点的位置,从最左位开始算。
         positive -- 是否是正数。
         recalc() -- 为了尽可能存放最多的有效数位,去除前缀的 0,并重新计算小数点位置。
         init() -- 部分初始化工作。
   公有成员:
         bignum( string str, int n, bool b) --
              构造函数。参数:str -- 字符串,各个有效数位;n -- 整数,小数点位置,从最左位开始算,比如 bignum("123", 2) = 12.3; bignum("123", 0) = 0.123; bignum("123", -2) = 0.00123;b -- 布尔值,是否是正数。
         add( bignum num ) -- 加法。
         subtract( bignum num ) -- 减法。
         multiply( bignum num ) -- 乘法。
         divide( bignum num ) -- 除法。
         squareroot() -- 平方根。
         tostring() -- 转换为字符串(包括小数点),以便以文本形式输出计算结果。
         clone() -- 复制。
  */
  this.recalc = function() /* 去除前缀的 0,并重新计算小数点位置 */
  {
    for(var i = 0; i < 17; i ++)
    {
       if(this.data[0] != 0) break;
       this.data.shift();
       this.data.push(0);
       this.decimal_place --;
    }
  }
  this.init = function() /* 部分初始化工作 */
  {
    this.decimal_place = math.ceil( n / 7 ); //小数点位置
    this.data = new array(17); //保存有效数位的数组
    if(n % 7 > 0)
    {
       var arr = new array( 8 - n % 7 );
    }
    else
    {
       var arr = new array( 1 - n % 7 );
    }
    str = arr.join("0") + str;
    if(str.length > 119)
    {
       str = str.substr(0, 119);
    }
    else if(str.length < 119)
    {
       var arr = new array(120 - str.length);
       str += arr.join("0");
    }
    for( var i = 0; i < 17; i ++ )
    {
       this.data[i] = parseint( str.substr(i * 7, 7) , 10 );
    }
  }
  /* 初始化开始 */
  this.positive = b;
  if( ! /^0*$/.test(str) )
  {
    this.init();
    this.recalc();
  }
  else
  {
    this.data = new array(17);
    for( var i = 0; i < 17; i ++ )
    {
       this.data[i] = 0;
    }
    this.decimal_place = 0;
  }
  /* 初始化结束 */
  this.add = function(num) /* 加法 */
  {
    if(this.positive && !num.positive)
    {
       num.positive = true;
       var result = this.subtract(num);
       num.positive = false;
       return result;
    }
    else if(num.positive && !this.positive)
    {
       this.positive = true;
       var result = num.subtract(this);
       this.positive = false;
       return result;
    }
    var result = new bignum("", 0, this.positive);
    var num1,num2;
    if(this.decimal_place >= num.decimal_place)
    {
       num1 = this;
       num2 = num;
    }
    else
    {
       num1 = num;
       num2 = this;
    }
    result.decimal_place = num1.decimal_place;
    if(num1.decimal_place - num2.decimal_place >= 17)
    {
       for(var i = 0; i < 17; i ++)
       {
         result.data[i] = num1.data[i];
       }
       return result;
    }
    var noffdec = num1.decimal_place - num2.decimal_place;
    var ntmp = 0;
    for( var i = 16; i >= 0; i -- )
    {
       var ntmp1 = i - noffdec;
       var ntmp2 = 0;
       if(ntmp1 >= 0)
       {
         ntmp2 = num1.data[i] + num2.data[ntmp1];
       }
       else
       {
         ntmp2 = num1.data[i];
       }
       ntmp2 += ntmp;
       ntmp = math.floor(ntmp2 / 10000000);
       result.data[i] = ntmp2 % 10000000;
    }
    if(ntmp > 0)
    {
       result.data.unshift(ntmp);
       result.decimal_place ++;
    }
    return result;
  }
  this.subtract = function(num) /* 减法 */
  {
    if(this.positive && !num.positive)
    {
       num.positive = true;
       var result = this.add(num);
       num.positive = false;
       return result;
    }
    else if(!this.positive && num.positive)
    {
       this.positive = true;
       var result = this.add(num);
       result.positive = false;
       this.positive = false;
       return result;
    }
    else
    {
       var num1 = num2 = null;
       var bpositive;
       if(this.decimal_place > num.decimal_place)
       {
         num1 = this;
         num2 = num;
         bpositive = this.positive;
       }
       else if(this.decimal_place < num.decimal_place)
       {
         num1 = num;
         num2 = this;
         bpositive = !this.positive;
       }
       else
       {
         for( var i = 0; i < 17; i ++ )
         {
           if(this.data[i] > num.data[i])
           {
              num1 = this;
              num2 = num;
              bpositive = this.positive;
              break;
           }
           else if(this.data[i] < num.data[i])
           {
              num1 = num;
              num2 = this;
              bpositive = !this.positive;
              break;
           }
         }
       }
       if( num1 == null)
       {
         return new bignum("", 0, true);
       }
       else
       {
         if(num1.decimal_place - num2.decimal_place >= 17)
         {
           var result = new bignum("", 0, bpositive);
           for(var i = 0; i < 17; i ++)
           {
              result.data[i] = num1.data[i];
           }
           result.decimal_place = num1.decimal_place;
           return result;
         }
         var result = new bignum("", 0, bpositive);
         result.decimal_place = num1.decimal_place;
         var noffdec = num1.decimal_place - num2.decimal_place;
         var ntmp = 0;
         for( var i = 16; i >= 0; i -- )
         {
           var ntmp1 = i - noffdec;
           var ntmp2 = 0;
           if(ntmp1 >= 0)
           {
              ntmp2 = 10000000 + ntmp + num1.data[i] - num2.data[ntmp1];
           }
           else
           {
              ntmp2 = 10000000 + ntmp + num1.data[i];
           }
           if(ntmp2 >= 10000000)
           {
              result.data[i] = ntmp2 - 10000000;
              ntmp = 0;
           }
           else
           {
              result.data[i] = ntmp2;
              ntmp = -1;
           }
         }
         result.recalc();
         return result;
       }
    }
  }
  this.multiply = function(num) /* 乘法 */
  {
    var bpositive;
    var ndecimalplace = this.decimal_place + num.decimal_place - 1;
    if(this.positive == num.positive)
    {
       bpositive = true;
    }
    else
    {
       bpositive = false;
    }
    var result = new bignum("", 0, bpositive);
    var ntmpdata = 0;
    for( var i = 16; i >= 0; i -- )
    {
       for( var j = 16; j >= 0; j -- )
       {
         if(isnan(result.data[j + i]))
           result.data[j + i] = 0;
         result.data[j + i] += this.data[j] * num.data[i];
         if(result.data[j + i] >= 10000000)
         {
           if( j + i -1 >= 0 )
           {
              result.data[j + i -1] += math.floor(result.data[j + i] / 10000000);
           }
           else
           {
              ntmpdata += math.floor(result.data[j + i] / 10000000);
           }
           result.data[j + i] = result.data[j + i] % 10000000;
         }
       }
    }
    if(ntmpdata > 0)
    {
       result.data.unshift(ntmpdata);
       result.data.pop();
       ndecimalplace ++;
    }
    result.decimal_place += ndecimalplace;
    return result;
  }
  this.divide = function(num) /* 除法 */
  {
    var bpositive;
    var ndecimalplace = this.decimal_place - num.decimal_place + 1;
    if(this.positive == num.positive)
    {
       bpositive = true;
    }
    else
    {
       bpositive = false;
    }
    var result = new bignum("", 0, bpositive);
    var arrtemp = new array(17);
    for( var i = 0; i < 17; i ++ )
    {
       arrtemp[i] = this.data[i];
    }
    var btest = true;
    var ntest = 0;
    for( var i = 0; i < 17; i ++ )
    {
       if(btest)
       {
         ntest = math.floor( ( arrtemp[0] * 10000000 + arrtemp[1] ) / ( num.data[0] * 10000000 + num.data[1] ) );
       }
       else
       {
         btest = true;
       }
       if(ntest == 0)
       {
         result.data[i] = 0;
         arrtemp[1] += arrtemp[0] * 10000000;
         arrtemp.shift();
         arrtemp.push(0);
         continue;
       }
       var arrtemp1 = new array(17);
       for( var j = 0; j < 17; j ++ )
       {
         arrtemp1[j] = 0;
       }
       for( var j = 16; j >= 0; j -- )
       {
         arrtemp1[j] += ntest * num.data[j];
         if(arrtemp1[j] >= 10000000)
         {
           if(j != 0)
           {
              arrtemp1[j - 1] += math.floor( arrtemp1[j] / 10000000);
              arrtemp1[j] = arrtemp1[j] % 10000000;
           }
         }
       }
       for( var j = 0; j < 17; j ++ )
       {
         if(arrtemp[j] < arrtemp1[j])
         {
           btest = false;
           break;
         }
         else if(arrtemp[j] > arrtemp1[j])
         {
           break;
         }
       }
       if(btest)
       {
         result.data[i] = ntest;
         for( var j = 16; j >= 0; j -- )
         {
           if(arrtemp[j] >= arrtemp1[j])
           {
              arrtemp[j] -= arrtemp1[j];
           }
           else
           {
              arrtemp[j] = 10000000 + arrtemp[j] - arrtemp1[j];
              arrtemp[j - 1] --;
           }
         }
       }
       else
       {
         ntest --;
         i --;
         continue;
       }
       arrtemp[1] += arrtemp[0] * 10000000;
       arrtemp.shift();
       arrtemp.push(0);
    }
    result.decimal_place = ndecimalplace;
    result.recalc();
    return result;
  }
  this.squareroot = function() /* 平方根 */
  {
    var result = new bignum("", 0, true);
    ndecimalplace = math.ceil(this.decimal_place / 2);
    var arrtemp = new array(17);
    for(var i = 0; i < 17; i ++)
    {
       arrtemp[i] = this.data[i];
    }
    var btest = true;
    for(var i = 0; i < 17; i ++)
    {
       if( i == 0 )
       {
         if(this.decimal_place % 2 == 0)
         {
           var ntemp = arrtemp[0] * 10000000 + arrtemp[1];
           var ntemp1 = math.floor( math.sqrt( ntemp ) );
           var ntemp2 = ntemp - ntemp1 * ntemp1;
           arrtemp[0] = 0;
           arrtemp[1] = ntemp2;
           arrtemp.shift();
           arrtemp.push(0);
         }
         else
         {
           var ntemp1 = math.floor( math.sqrt( arrtemp[0] ) );
           var ntemp2 = arrtemp[0] - ntemp1 * ntemp1;
           arrtemp[0] = ntemp2;
         }
       }
       else
       {
         if(btest)
         {
           if( i == 1 )
           {
              ntemp1 = math.sqrt( (arrtemp[0] * 10000000 + arrtemp[1]) + 100000000000000 * math.pow(result.data[0], 2) ) - 10000000 * result.data[0];
              ntemp1 = math.floor(ntemp1);
           }
           else
           {
              ntemp = result.data[0] * 10000000 + result.data[1];
              ntemp1 = math.floor( ( arrtemp[0] * 10000000 + arrtemp[1] ) / ( 2 * ntemp ) );
           }
         }
         else
         {
           btest = true;
         }
         var arrtemp1 = new array(17);
         var ntemp3 = 0
         for( var j = i - 1; j >= 0; j -- )
         {
           arrtemp1[j] = result.data[j] * 2 + ntemp3;
           if( arrtemp1[j] >= 10000000 && j > 0 )
           {
              ntemp3 = 1;
              arrtemp1[j] = arrtemp1[j] % 10000000;
           }
           else
           {
              ntemp3 = 0;
           }
         }
         arrtemp1[i] = ntemp1;
         ntemp3 = 0;
         for( var j = i; j >= 0; j -- )
         {
           arrtemp1[j] = arrtemp1[j] * ntemp1 + ntemp3;
           if( arrtemp1[j] >= 10000000 && j > 0 )
           {
              ntemp3 = math.floor( arrtemp1[j] / 10000000 );
              arrtemp1[j] = arrtemp1[j] % 10000000;
           }
           else
           {
              ntemp3 = 0;
           }
         }
         var arrtemp2 = new array(17);
         for( var j = 0; j < 17; j ++ )
         {
           arrtemp2[j] = arrtemp[j];
         }
         for( var j = i; j >= 0; j -- )
         {
           if( arrtemp2[j] >= arrtemp1[j] )
           {
              arrtemp2[j] -= arrtemp1[j];
           }
           else
           {
              if(j > 0)
              {
                arrtemp2[j] = arrtemp2[j] + 10000000 - arrtemp1[j];
                arrtemp2[j - 1] --;
              }
              else
              {
                btest = false;
                break;
              }
           }
         }
         if(btest)
         {
           arrtemp = arrtemp2;
         }
         else
         {
           ntemp1 --;
           i --;
           continue;
         }
       }
       result.data[i] = ntemp1;
       arrtemp[1] += arrtemp[0] * 10000000;
       arrtemp.shift();
       arrtemp.push(0);
    }
    result.decimal_place = ndecimalplace;
    result.recalc();
    return result;
  }
  this.tostring = function() /* 转换为字符串(包括小数点),以便以文本形式输出计算结果 */
  {
    var szdata = "";
    var szoutput = "";
    this.recalc();
    for( var i = 0; i < 17; i ++ )
    {
       var sztmpdata = this.data[i].tostring()
       var arr = new array(8 - sztmpdata.length);
       szdata += arr.join("0") + sztmpdata;
    }
    if( /^0*$/.test(szdata) )
    {
       return "0";
    }
    var n = this.decimal_place * 7;
    for(var i = 0; i < 7; i++)
    {
       if(szdata.substr(i, 1) != 0) break;
       n --;
    }
    szdata = szdata.replace(/^0+/g,"");
    szdata = szdata.substr(0, 101);
    szdata = szdata.replace(/0+$/g,"");
    if( n < 1 )
    {
       szoutput = szdata.substr(0, 1) + 
         ( ( szdata.length > 1 ) ? "." : "" ) + 
         szdata.substr(1) + "e" + ( n - 1 ).tostring();
    }
    else if(n == szdata.length)
    {
       szoutput = szdata;
    }
    else if(n > szdata.length)
    {
       szoutput = szdata.substr(0, 1) + "." + szdata.substr(1) + "e+" + (n - 1).tostring();
    }
    else
    {
       szoutput = szdata.substr(0, n) + "." + szdata.substr(n);
    }
    return ( this.positive ? "" : "-" ) + szoutput;
  }
  this.clone = function()   /* 复制 */
  {
    var result = new bignum("", 0, true);
    for( var i = 0; i < 17; i ++)
    {
       result.data[i] = this.data[i];
    }
    result.decimal_place = this.decimal_place;
    result.positive = this.positive;
    return result;
  }
}
var a = new bignum("1", 1, true)
var count = 168;
var ntwo = new bignum("2", 1, true);
function loop(inttmpvar,intcount)
{
  if(intcount == 0) return inttmpvar;
  var v1 = inttmpvar.divide( ntwo );
  var v11 = v1.clone();
  var ntemp = v1.multiply( v11 );
  var a1 = a.clone();
  a1 = a.multiply(a1);
  var ntemp1 = a1.subtract( ntemp )
  v2 = ntemp1.squareroot();
  v3 = a.subtract( v2 );
  var v31 = v3.clone();
  var ntemp2 = v3.multiply( v31 );
  var ntemp3 = ntemp2.add(ntemp);
  v4 = ntemp3.squareroot();
  return loop( v4 , -- intcount )
}
var a1 = a.clone();
var ntemp = a.multiply(a1);
var ntemp1 = ntemp.clone();
ntemp = ntemp.add(ntemp1);
ntemp = loop(ntemp.squareroot(), count);
var nfour = new bignum("4", 1, true);
ntemp = ntemp.multiply( nfour );
ntemp1 = new bignum("2", 1, true);
var ntemp2 = new bignum("2", 1, true);
for(var i = 0; i < count - 1; i ++)
{
  ntemp1 = ntemp1.multiply( ntemp2 );
}
ntemp = ntemp.multiply( ntemp1 );
ntemp = ntemp.divide( ntwo );
ntemp = ntemp.divide( a );
document.write( ntemp )
//-->
</script>
</body>
</html>

运行结果:

3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679

ps:这里再为大家推荐几款计算工具供大家进一步参考借鉴:

在线一元函数(方程)求解计算工具:

科学计算器在线使用_高级计算器在线计算:

在线计算器_标准计算器:

更多关于javascript相关内容感兴趣的读者可查看本站专题:《javascript数学运算用法总结》、《javascript数据结构与算法技巧总结》、《javascript数组操作技巧总结》、《javascript事件相关操作与技巧大全》、《javascript操作dom技巧总结》及《javascript字符与字符串操作技巧总结

希望本文所述对大家javascript程序设计有所帮助。