您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

怎样使用JS实现计算圆周率到小数点后100位

2025/3/22 20:51:46发布22次查看
这次给大家带来怎样使用js实现计算圆周率到小数点后100位,使用js实现计算圆周率到小数点后100位的注意事项有哪些,下面就是实战案例,一起来看一下。
浮点数的有效数位是16位,我自己做了一个大数类,能存储100位有效数位,并实现了大数类的基本运算。我用它来计算圆周率(割圆法,即多边形逼近),得到了小数点后一百位有效数字,比对了machin 公式的计算结果,没有误差。用时约2秒。
完整示例如下:
<!doctype html> <html> <head> <meta charset="utf-8"> <title> 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 ) -- 乘法。 pide( 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.pide = 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.pide( 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.pide( ntwo ); ntemp = ntemp.pide( a ); document.write( ntemp ) //--> </script> </body> </html>
运行结果:
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
相信看了本文案例你已经掌握了方法,更多精彩请关注其它相关文章!
推荐阅读:
js常用算法累加、迭代、穷举、递归实现(附代码)
js callback回调函数使用步骤详解
以上就是怎样使用js实现计算圆周率到小数点后100位的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product