// https://github.com/Naruyoko/ExpantaNum.js/blob/develop/ExpantaNum.js //Code snippets and templates from Decimal.js ;(function (globalScope) { "use strict"; // -- EDITABLE DEFAULTS -- // var ExpantaNum = { // The maximum number of operators stored in array. // If the number of operations exceed the limit, then the least significant operations will be discarded. // This is to prevent long loops and eating away of memory and processing time. // 1000 means there are at maximum of 1000 elements in array. // It is not recommended to make this number too big. // `ExpantaNum.maxOps = 1000;` maxOps: 1e3, // Specify what format is used when serializing for JSON.stringify // // JSON 0 JSON object // STRING 1 String serializeMode: 0, // Deprecated // Level of debug information printed in console // // NONE 0 Show no information. // NORMAL 1 Show operations. // ALL 2 Show everything. debug: 0 }, // -- END OF EDITABLE DEFAULTS -- // external = true, expantaNumError = "[ExpantaNumError] ", invalidArgument = expantaNumError + "Invalid argument: ", isExpantaNum = /^[-\+]*(Infinity|NaN|(J+|J\^\d+ )?(10(\^+|\{[1-9]\d*\})|\(10(\^+|\{[1-9]\d*\})\)\^[1-9]\d* )*((\d+(\.\d*)?|\d*\.\d+)?([Ee][-\+]*))*(0|\d+(\.\d*)?|\d*\.\d+))$/, MAX_SAFE_INTEGER = 9007199254740991, MAX_E = Math.log10(MAX_SAFE_INTEGER), //15.954589770191003 // ExpantaNum.prototype object P={}, // ExpantaNum static object Q={}, // ExpantaNum constants R={}; R.ZERO=0; R.ONE=1; R.E=Math.E; R.LN2=Math.LN2; R.LN10=Math.LN10; R.LOG2E=Math.LOG2E; R.LOG10E=Math.LOG10E; R.PI=Math.PI; R.SQRT1_2=Math.SQRT1_2; R.SQRT2=Math.SQRT2; R.MAX_SAFE_INTEGER=MAX_SAFE_INTEGER; R.MIN_SAFE_INTEGER=Number.MIN_SAFE_INTEGER; R.NaN=Number.NaN; R.NEGATIVE_INFINITY=Number.NEGATIVE_INFINITY; R.POSITIVE_INFINITY=Number.POSITIVE_INFINITY; R.E_MAX_SAFE_INTEGER="e"+MAX_SAFE_INTEGER; R.EE_MAX_SAFE_INTEGER="ee"+MAX_SAFE_INTEGER; R.TETRATED_MAX_SAFE_INTEGER="10^^"+MAX_SAFE_INTEGER; R.GRAHAMS_NUMBER="J^63 10^^^(10^)^7625597484984 3638334640023.7783"; // ExpantaNum prototype methods P.absoluteValue=P.abs=function(){ var x=this.clone(); x.sign=1; return x; }; Q.absoluteValue=Q.abs=function(x){ return new ExpantaNum(x).abs(); }; P.negate=P.neg=function (){ var x=this.clone(); x.sign=x.sign*-1; return x; }; Q.negate=Q.neg=function (x){ return new ExpantaNum(x).neg(); }; P.compareTo=P.cmp=function (other){ if (!(other instanceof ExpantaNum)) other=new ExpantaNum(other); if (isNaN(this.array[0][1])||isNaN(other.array[0][1])) return NaN; if (this.array[0][1]==Infinity&&other.array[0][1]!=Infinity) return this.sign; if (this.array[0][1]!=Infinity&&other.array[0][1]==Infinity) return -other.sign; if (this.array.length==1&&this.array[0][1]===0&&other.array.length==1&&other.array[0][1]===0) return 0; if (this.sign!=other.sign) return this.sign; var m=this.sign; var r; if (this.layer>other.layer) r=1; else if (this.layerf[0]||e[0]==f[0]&&e[1]>f[1]){ r=1; break; }else if (e[0]other.array.length){ e=this.array[this.array.length-l]; if (e[0]>=1||e[1]>10){ r=1; }else{ r=-1; } }else{ e=other.array[other.array.length-l]; if (e[0]>=1||e[1]>10){ r=-1; }else{ r=1; } } } } return r*m; }; Q.compare=Q.cmp=function (x,y){ return new ExpantaNum(x).cmp(y); }; P.greaterThan=P.gt=function (other){ return this.cmp(other)>0; }; Q.greaterThan=Q.gt=function (x,y){ return new ExpantaNum(x).gt(y); }; P.greaterThanOrEqualTo=P.gte=function (other){ return this.cmp(other)>=0; }; Q.greaterThanOrEqualTo=Q.gte=function (x,y){ return new ExpantaNum(x).gte(y); }; P.lessThan=P.lt=function (other){ return this.cmp(other)<0; }; Q.lessThan=Q.lt=function (x,y){ return new ExpantaNum(x).lt(y); }; P.lessThanOrEqualTo=P.lte=function (other){ return this.cmp(other)<=0; }; Q.lessThanOrEqualTo=Q.lte=function (x,y){ return new ExpantaNum(x).lte(y); }; P.equalsTo=P.equal=P.eq=function (other){ return this.cmp(other)===0; }; Q.equalsTo=Q.equal=Q.eq=function (x,y){ return new ExpantaNum(x).eq(y); }; P.notEqualsTo=P.notEqual=P.neq=function (other){ return this.cmp(other)!==0; }; Q.notEqualsTo=Q.notEqual=Q.neq=function (x,y){ return new ExpantaNum(x).neq(y); }; P.minimum=P.min=function (other){ return this.lt(other)?this.clone():new ExpantaNum(other); }; Q.minimum=Q.min=function (x,y){ return new ExpantaNum(x).min(y); }; P.maximum=P.max=function (other){ return this.gt(other)?this.clone():new ExpantaNum(other); }; Q.maximum=Q.max=function (x,y){ return new ExpantaNum(x).max(y); }; P.compareTo_tolerance=P.cmp_tolerance=function (other,tolerance){ if (!(other instanceof ExpantaNum)) other=new ExpantaNum(other); return this.eq_tolerance(other,tolerance)?0:this.cmp(other); }; Q.compare_tolerance=Q.cmp_tolerance=function (x,y,tolerance){ return new ExpantaNum(x).cmp_tolerance(y,tolerance); }; P.greaterThan_tolerance=P.gt_tolerance=function (other,tolerance){ if (!(other instanceof ExpantaNum)) other=new ExpantaNum(other); return !this.eq_tolerance(other,tolerance)&&this.gt(other); }; Q.greaterThan_tolerance=Q.gt_tolerance=function (x,y,tolerance){ return new ExpantaNum(x).gt_tolerance(y,tolerance); }; P.greaterThanOrEqualTo_tolerance=P.gte_tolerance=function (other,tolerance){ if (!(other instanceof ExpantaNum)) other=new ExpantaNum(other); return this.eq_tolerance(other,tolerance)||this.gt(other); }; Q.greaterThanOrEqualTo_tolerance=Q.gte_tolerance=function (x,y,tolerance){ return new ExpantaNum(x).gte_tolerance(y,tolerance); }; P.lessThan_tolerance=P.lt_tolerance=function (other,tolerance){ if (!(other instanceof ExpantaNum)) other=new ExpantaNum(other); return !this.eq_tolerance(other,tolerance)&&this.lt(other); }; Q.lessThan_tolerance=Q.lt_tolerance=function (x,y,tolerance){ return new ExpantaNum(x).lt_tolerance(y,tolerance); }; P.lessThanOrEqualTo_tolerance=P.lte_tolerance=function (other,tolerance){ if (!(other instanceof ExpantaNum)) other=new ExpantaNum(other); return this.eq_tolerance(other,tolerance)||this.lt(other); }; Q.lessThanOrEqualTo_tolerance=Q.lte_tolerance=function (x,y,tolerance){ return new ExpantaNum(x).lte_tolerance(y,tolerance); }; //From break_eternity.js //https://github.com/Patashu/break_eternity.js/blob/96901974c175cb28f66c7164a5a205cdda783872/src/index.ts#L2802 P.equalsTo_tolerance=P.equal_tolerance=P.eq_tolerance=function (other,tolerance){ if (!(other instanceof ExpantaNum)) other=new ExpantaNum(other); if (tolerance==null) tolerance=1e-7; if (this.isNaN()||other.isNaN()||this.isFinite()!=other.isFinite()) return false; if (this.sign!=other.sign) return false; if (Math.abs(this.layer-other.layer)>1) return false; var a,b; if (this.layer!=other.layer){ var x,y; if (this.layer>other.layer) x=this,y=other; else x=other,y=this; if (!(x.array.length==2&&x.array[0][0]===0&&x.array[1][0]==1&&x.array[1][1]==1)) return false; a=x.array[0][1]; if (y.array[y.array.length-1][1]>=10) b=Math.log10(y.array[y.array.length-1][0]+1); else b=Math.log10(y.array[y.array.length-1][0]); }else{ if (Math.abs(this.array[this.array.length-1][0]-other.array[other.array.length-1][0])>1) return false; for (var i=1;Math.max(this.array.length,other.array.length)-i>=0;++i){ var c=this.array[this.array.length-i][0]; var d=other.array[other.array.length-i][0]; var x,y,e,f; if (c!=d){ if (c>d) x=this,y=other; else x=other,y=this,c=d; e=x.array[x.array.length-i][1]; f=0; }else{ x=this; y=other; e=x.array[x.array.length-i][1]; f=y.array[y.array.length-i][1]; if (x.array.length-i==0){ a=e; b=f; break; } } if (Math.abs(e-f)>1) return false; if (e!=f){ if (!(x.array.length-i<2||x.array.length-i==2&&x.array[0][0]===0&&x.array[1][0]==1&&x.array[1][1]==1)) return false; a=x.array[0][1]; if (c==1) b=Math.log10(y.operator(0)); else if (c==2&&y.operator(0)>=1e10) b=Math.log10(y.operator(1)+2); else if (y.operator(c-2)>=10) b=Math.log10(y.operator(c-1)+1); else b=Math.log10(y.operator(c-1)); break; } } } return Math.abs(a-b)<=tolerance*Math.max(Math.abs(a),Math.abs(b)); }; Q.equalsTo_tolerance=Q.equal_tolerance=Q.eq_tolerance=function (x,y,tolerance){ return new ExpantaNum(x).eq_tolerance(y,tolerance); }; P.notEqualsTo_tolerance=P.notEqual_tolerance=P.neq_tolerance=function (other,tolerance){ return !this.eq_tolerance(other,tolerance); }; Q.notEqualsTo_tolerance=Q.notEqual_tolerance=Q.neq_tolerance=function (x,y,tolerance){ return new ExpantaNum(x).neq_tolerance(y,tolerance); }; P.isPositive=P.ispos=function (){ return this.gt(ExpantaNum.ZERO); }; Q.isPositive=Q.ispos=function (x){ return new ExpantaNum(x).ispos(); }; P.isNegative=P.isneg=function (){ return this.lt(ExpantaNum.ZERO); }; Q.isNegative=Q.isneg=function (x){ return new ExpantaNum(x).isneg(); }; P.isNaN=function (){ return isNaN(this.array[0][1]); }; Q.isNaN=function (x){ return new ExpantaNum(x).isNaN(); }; P.isFinite=function (){ return isFinite(this.array[0][1]); }; Q.isFinite=function (x){ return new ExpantaNum(x).isFinite(); }; P.isInfinite=function (){ return this.array[0][1]==Infinity; }; Q.isInfinite=function (x){ return new ExpantaNum(x).isInfinite(); }; P.isInteger=P.isint=function (){ if (this.sign==-1) return this.abs().isint(); if (this.gt(ExpantaNum.MAX_SAFE_INTEGER)) return true; return Number.isInteger(this.toNumber()); }; Q.isInteger=Q.isint=function (x){ return new ExpantaNum(x).isint(); }; P.floor=function (){ if (this.isInteger()) return this.clone(); return new ExpantaNum(Math.floor(this.toNumber())); }; Q.floor=function (x){ return new ExpantaNum(x).floor(); }; P.ceiling=P.ceil=function (){ if (this.isInteger()) return this.clone(); return new ExpantaNum(Math.ceil(this.toNumber())); }; Q.ceiling=Q.ceil=function (x){ return new ExpantaNum(x).ceil(); }; P.round=function (){ if (this.isInteger()) return this.clone(); return new ExpantaNum(Math.round(this.toNumber())); }; Q.round=function (x){ return new ExpantaNum(x).round(); }; var debugMessageSent=false; P.plus=P.add=function (other){ var x=this.clone(); other=new ExpantaNum(other); if (ExpantaNum.debug>=ExpantaNum.NORMAL){ console.log(this+"+"+other); if (!debugMessageSent) console.warn(expantaNumError+"Debug output via 'debug' is being deprecated and will be removed in the future!"),debugMessageSent=true; } if (x.sign==-1) return x.neg().add(other.neg()).neg(); if (other.sign==-1) return x.sub(other.neg()); if (x.eq(ExpantaNum.ZERO)) return other; if (other.eq(ExpantaNum.ZERO)) return x; if (x.isNaN()||other.isNaN()||x.isInfinite()&&other.isInfinite()&&x.eq(other.neg())) return ExpantaNum.NaN.clone(); if (x.isInfinite()) return x; if (other.isInfinite()) return other; var p=x.min(other); var q=x.max(other); var op0=q.operator(0); var op1=q.operator(1); var t; if (q.gt(ExpantaNum.E_MAX_SAFE_INTEGER)||q.div(p).gt(ExpantaNum.MAX_SAFE_INTEGER)){ t=q; }else if (!op1){ t=new ExpantaNum(x.toNumber()+other.toNumber()); }else if (op1==1){ var a=p.operator(1)?p.operator(0):Math.log10(p.operator(0)); t=new ExpantaNum([a+Math.log10(Math.pow(10,op0-a)+1),1]); } p=q=null; return t; }; Q.plus=Q.add=function (x,y){ return new ExpantaNum(x).add(y); }; P.minus=P.sub=function (other){ var x=this.clone(); other=new ExpantaNum(other); if (ExpantaNum.debug>=ExpantaNum.NORMAL) console.log(x+"-"+other); if (x.sign==-1) return x.neg().sub(other.neg()).neg(); if (other.sign==-1) return x.add(other.neg()); if (x.eq(other)) return ExpantaNum.ZERO.clone(); if (other.eq(ExpantaNum.ZERO)) return x; if (x.isNaN()||other.isNaN()||x.isInfinite()&&other.isInfinite()) return ExpantaNum.NaN.clone(); if (x.isInfinite()) return x; if (other.isInfinite()) return other.neg(); var p=x.min(other); var q=x.max(other); var n=other.gt(x); var op0=q.operator(0); var op1=q.operator(1); var t; if (q.gt(ExpantaNum.E_MAX_SAFE_INTEGER)||q.div(p).gt(ExpantaNum.MAX_SAFE_INTEGER)){ t=q; t=n?t.neg():t; }else if (!op1){ t=new ExpantaNum(x.toNumber()-other.toNumber()); }else if (op1==1){ var a=p.operator(1)?p.operator(0):Math.log10(p.operator(0)); t=new ExpantaNum([a+Math.log10(Math.pow(10,op0-a)-1),1]); t=n?t.neg():t; } p=q=null; return t; }; Q.minus=Q.sub=function (x,y){ return new ExpantaNum(x).sub(y); }; P.times=P.mul=function (other){ var x=this.clone(); other=new ExpantaNum(other); if (ExpantaNum.debug>=ExpantaNum.NORMAL) console.log(x+"*"+other); if (x.sign*other.sign==-1) return x.abs().mul(other.abs()).neg(); if (x.sign==-1) return x.abs().mul(other.abs()); if (x.isNaN()||other.isNaN()||x.eq(ExpantaNum.ZERO)&&other.isInfinite()||x.isInfinite()&&other.abs().eq(ExpantaNum.ZERO)) return ExpantaNum.NaN.clone(); if (other.eq(ExpantaNum.ZERO)) return ExpantaNum.ZERO.clone(); if (other.eq(ExpantaNum.ONE)) return x.clone(); if (x.isInfinite()) return x; if (other.isInfinite()) return other; if (x.max(other).gt(ExpantaNum.EE_MAX_SAFE_INTEGER)) return x.max(other); var n=x.toNumber()*other.toNumber(); if (n<=MAX_SAFE_INTEGER) return new ExpantaNum(n); return ExpantaNum.pow(10,x.log10().add(other.log10())); }; Q.times=Q.mul=function (x,y){ return new ExpantaNum(x).mul(y); }; P.divide=P.div=function (other){ var x=this.clone(); other=new ExpantaNum(other); if (ExpantaNum.debug>=ExpantaNum.NORMAL) console.log(x+"/"+other); if (x.sign*other.sign==-1) return x.abs().div(other.abs()).neg(); if (x.sign==-1) return x.abs().div(other.abs()); if (x.isNaN()||other.isNaN()||x.isInfinite()&&other.isInfinite()||x.eq(ExpantaNum.ZERO)&&other.eq(ExpantaNum.ZERO)) return ExpantaNum.NaN.clone(); if (other.eq(ExpantaNum.ZERO)) return ExpantaNum.POSITIVE_INFINITY.clone(); if (other.eq(ExpantaNum.ONE)) return x.clone(); if (x.eq(other)) return ExpantaNum.ONE.clone(); if (x.isInfinite()) return x; if (other.isInfinite()) return ExpantaNum.ZERO.clone(); if (x.max(other).gt(ExpantaNum.EE_MAX_SAFE_INTEGER)) return x.gt(other)?x.clone():ExpantaNum.ZERO.clone(); var n=x.toNumber()/other.toNumber(); if (n<=MAX_SAFE_INTEGER) return new ExpantaNum(n); var pw=ExpantaNum.pow(10,x.log10().sub(other.log10())); var fp=pw.floor(); if (pw.sub(fp).lt(new ExpantaNum(1e-9))) return fp; return pw; }; Q.divide=Q.div=function (x,y){ return new ExpantaNum(x).div(y); }; P.reciprocate=P.rec=function (){ if (ExpantaNum.debug>=ExpantaNum.NORMAL) console.log(this+"^-1"); if (this.isNaN()||this.eq(ExpantaNum.ZERO)) return ExpantaNum.NaN.clone(); if (this.abs().gt("2e323")) return ExpantaNum.ZERO.clone(); return new ExpantaNum(1/this); }; Q.reciprocate=Q.rec=function (x){ return new ExpantaNum(x).rec(); }; P.modular=P.mod=function (other){ other=new ExpantaNum(other); if (other.eq(ExpantaNum.ZERO)) return ExpantaNum.ZERO.clone(); if (this.sign*other.sign==-1) return this.abs().mod(other.abs()).neg(); if (this.sign==-1) return this.abs().mod(other.abs()); return this.sub(this.div(other).floor().mul(other)); }; Q.modular=Q.mod=function (x,y){ return new ExpantaNum(x).mod(y); }; //All of these are from Patashu's break_eternity.js //from HyperCalc source code var f_gamma=function (n){ if (!isFinite(n)) return n; if (n<-50){ if (n==Math.trunc(n)) return Number.NEGATIVE_INFINITY; return 0; } var scal1=1; while (n<10){ scal1=scal1*n; ++n; } n-=1; var l=0.9189385332046727; //0.5*Math.log(2*Math.PI) l+=(n+0.5)*Math.log(n); l-=n; var n2=n*n; var np=n; l+=1/(12*np); np*=n2; l-=1/(360*np); np*=np*n2; l+=1/(1260*np); np*=n2; l-=1/(1680*np); np*=n2; l+=1/(1188*np); np*=n2; l-=691/(360360*np); np*=n2; l+=7/(1092*np); np*=n2; l-=3617/(122400*np); return Math.exp(l)/scal1; }; //from HyperCalc source code P.gamma=function (){ var x=this.clone(); if (x.gt(ExpantaNum.TETRATED_MAX_SAFE_INTEGER)) return x; if (x.gt(ExpantaNum.E_MAX_SAFE_INTEGER)) return ExpantaNum.exp(x); if (x.gt(ExpantaNum.MAX_SAFE_INTEGER)) return ExpantaNum.exp(ExpantaNum.mul(x,ExpantaNum.ln(x).sub(1))); var n=x.operator(0); if (n>1){ if (n<24) return new ExpantaNum(f_gamma(x.sign*n)); var t=n-1; var l=0.9189385332046727; //0.5*Math.log(2*Math.PI) l+=((t+0.5)*Math.log(t)); l-=t; var n2=t*t; var np=t; var lm=12*np; var adj=1/lm; var l2=l+adj; if (l2==l) return ExpantaNum.exp(l); l=l2; np*=n2; lm=360*np; adj=1/lm; l2=l-adj; if (l2==l) return ExpantaNum.exp(l); l=l2; np*=n2; lm=1260*np; var lt=1/lm; l+=lt; np*=n2; lm=1680*np; lt=1/lm; l-=lt; return ExpantaNum.exp(l); }else return this.rec(); }; Q.gamma=function (x){ return new ExpantaNum(x).gamma(); }; //end break_eternity.js excerpt Q.factorials=[1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800,479001600,6227020800,87178291200,1307674368000,20922789888000,355687428096000,6402373705728000,121645100408832000,2432902008176640000,51090942171709440000,1.1240007277776076800e+21,2.5852016738884978213e+22,6.2044840173323941000e+23,1.5511210043330986055e+25,4.0329146112660565032e+26,1.0888869450418351940e+28,3.0488834461171387192e+29,8.8417619937397018986e+30,2.6525285981219106822e+32,8.2228386541779224302e+33,2.6313083693369351777e+35,8.6833176188118859387e+36,2.9523279903960415733e+38,1.0333147966386145431e+40,3.7199332678990125486e+41,1.3763753091226345579e+43,5.2302261746660111714e+44,2.0397882081197444123e+46,8.1591528324789768380e+47,3.3452526613163807956e+49,1.4050061177528799549e+51,6.0415263063373834074e+52,2.6582715747884488694e+54,1.1962222086548018857e+56,5.5026221598120891536e+57,2.5862324151116817767e+59,1.2413915592536072528e+61,6.0828186403426752249e+62,3.0414093201713375576e+64,1.5511187532873821895e+66,8.0658175170943876846e+67,4.2748832840600254848e+69,2.3084369733924137924e+71,1.2696403353658276447e+73,7.1099858780486348103e+74,4.0526919504877214100e+76,2.3505613312828784949e+78,1.3868311854568983861e+80,8.3209871127413898951e+81,5.0758021387722483583e+83,3.1469973260387939390e+85,1.9826083154044400850e+87,1.2688693218588416544e+89,8.2476505920824715167e+90,5.4434493907744306945e+92,3.6471110918188683221e+94,2.4800355424368305480e+96,1.7112245242814129738e+98,1.1978571669969892213e+100,8.5047858856786230047e+101,6.1234458376886084639e+103,4.4701154615126843855e+105,3.3078854415193862416e+107,2.4809140811395399745e+109,1.8854947016660503806e+111,1.4518309202828587210e+113,1.1324281178206296794e+115,8.9461821307829757136e+116,7.1569457046263805709e+118,5.7971260207473678414e+120,4.7536433370128420198e+122,3.9455239697206587884e+124,3.3142401345653531943e+126,2.8171041143805501310e+128,2.4227095383672734128e+130,2.1077572983795278544e+132,1.8548264225739843605e+134,1.6507955160908460244e+136,1.4857159644817615149e+138,1.3520015276784029158e+140,1.2438414054641308179e+142,1.1567725070816415659e+144,1.0873661566567430754e+146,1.0329978488239059305e+148,9.9167793487094964784e+149,9.6192759682482120384e+151,9.4268904488832479837e+153,9.3326215443944153252e+155,9.3326215443944150966e+157,9.4259477598383598816e+159,9.6144667150351270793e+161,9.9029007164861804721e+163,1.0299016745145628100e+166,1.0813967582402909767e+168,1.1462805637347083683e+170,1.2265202031961380050e+172,1.3246418194518290179e+174,1.4438595832024936625e+176,1.5882455415227430287e+178,1.7629525510902445874e+180,1.9745068572210740115e+182,2.2311927486598137657e+184,2.5435597334721876552e+186,2.9250936934930159967e+188,3.3931086844518980862e+190,3.9699371608087210616e+192,4.6845258497542909237e+194,5.5745857612076058231e+196,6.6895029134491271205e+198,8.0942985252734440920e+200,9.8750442008336010580e+202,1.2146304367025329301e+205,1.5061417415111409314e+207,1.8826771768889261129e+209,2.3721732428800468512e+211,3.0126600184576594309e+213,3.8562048236258040716e+215,4.9745042224772874590e+217,6.4668554892204741474e+219,8.4715806908788206314e+221,1.1182486511960043298e+224,1.4872707060906857134e+226,1.9929427461615187928e+228,2.6904727073180504073e+230,3.6590428819525488642e+232,5.0128887482749919605e+234,6.9177864726194885808e+236,9.6157231969410893532e+238,1.3462012475717525742e+241,1.8981437590761708898e+243,2.6953641378881628530e+245,3.8543707171800730787e+247,5.5502938327393044385e+249,8.0479260574719917061e+251,1.1749972043909107097e+254,1.7272458904546389230e+256,2.5563239178728653927e+258,3.8089226376305697893e+260,5.7133839564458546840e+262,8.6272097742332399855e+264,1.3113358856834524492e+267,2.0063439050956822953e+269,3.0897696138473507759e+271,4.7891429014633940780e+273,7.4710629262828942235e+275,1.1729568794264144743e+278,1.8532718694937349890e+280,2.9467022724950384028e+282,4.7147236359920616095e+284,7.5907050539472189932e+286,1.2296942187394494177e+289,2.0044015765453026266e+291,3.2872185855342959088e+293,5.4239106661315886750e+295,9.0036917057784375454e+297,1.5036165148649991456e+300,2.5260757449731984219e+302,4.2690680090047051083e+304,7.2574156153079990350e+306]; P.factorial=P.fact=function (){ var x=this.clone(); var f=ExpantaNum.factorials; if (x.lt(ExpantaNum.ZERO)||!x.isint()) return x.add(1).gamma(); if (x.lte(170)) return new ExpantaNum(f[+x]); var errorFixer=1; var e=+x; if (e<500) e+=163879/209018880*Math.pow(e,5); if (e<1000) e+=-571/2488320*Math.pow(e,4); if (e<50000) e+=-139/51840*Math.pow(e,3); if (e<1e7) e+=1/288*Math.pow(e,2); if (e<1e20) e+=1/12*e; return x.div(ExpantaNum.E).pow(x).mul(x.mul(ExpantaNum.PI).mul(2).sqrt()).times(errorFixer); }; Q.factorial=Q.fact=function (x){ return new ExpantaNum(x).fact(); }; P.toPower=P.pow=function (other){ other=new ExpantaNum(other); if (ExpantaNum.debug>=ExpantaNum.NORMAL) console.log(this+"^"+other); if (other.eq(ExpantaNum.ZERO)) return ExpantaNum.ONE.clone(); if (other.eq(ExpantaNum.ONE)) return this.clone(); if (other.lt(ExpantaNum.ZERO)) return this.pow(other.neg()).rec(); if (this.lt(ExpantaNum.ZERO)&&other.isint()){ if (other.mod(2).lt(ExpantaNum.ONE)) return this.abs().pow(other); return this.abs().pow(other).neg(); } if (this.lt(ExpantaNum.ZERO)) return ExpantaNum.NaN.clone(); if (this.eq(ExpantaNum.ONE)) return ExpantaNum.ONE.clone(); if (this.eq(ExpantaNum.ZERO)) return ExpantaNum.ZERO.clone(); if (this.max(other).gt(ExpantaNum.TETRATED_MAX_SAFE_INTEGER)) return this.max(other); if (this.eq(10)){ if (other.gt(ExpantaNum.ZERO)){ other.operator(1,(other.operator(1)+1)||1); other.normalize(); return other; }else{ return new ExpantaNum(Math.pow(10,other.toNumber())); } } if (other.lt(ExpantaNum.ONE)) return this.root(other.rec()); var n=Math.pow(this.toNumber(),other.toNumber()); if (n<=MAX_SAFE_INTEGER) return new ExpantaNum(n); return ExpantaNum.pow(10,this.log10().mul(other)); }; Q.toPower=Q.pow=function (x,y){ return new ExpantaNum(x).pow(y); }; P.exponential=P.exp=function (){ return ExpantaNum.pow(Math.E,this); }; Q.exponential=Q.exp=function (x){ return ExpantaNum.pow(Math.E,x); }; P.squareRoot=P.sqrt=function (){ return this.root(2); }; Q.squareRoot=Q.sqrt=function (x){ return new ExpantaNum(x).root(2); }; P.cubeRoot=P.cbrt=function (){ return this.root(3); }; Q.cubeRoot=Q.cbrt=function (x){ return new ExpantaNum(x).root(3); }; P.root=function (other){ other=new ExpantaNum(other); if (ExpantaNum.debug>=ExpantaNum.NORMAL) console.log(this+"root"+other); if (other.eq(ExpantaNum.ONE)) return this.clone(); if (other.lt(ExpantaNum.ZERO)) return this.root(other.neg()).rec(); if (other.lt(ExpantaNum.ONE)) return this.pow(other.rec()); if (this.lt(ExpantaNum.ZERO)&&other.isint()&&other.mod(2).eq(ExpantaNum.ONE)) return this.neg().root(other).neg(); if (this.lt(ExpantaNum.ZERO)) return ExpantaNum.NaN.clone(); if (this.eq(ExpantaNum.ONE)) return ExpantaNum.ONE.clone(); if (this.eq(ExpantaNum.ZERO)) return ExpantaNum.ZERO.clone(); if (this.max(other).gt(ExpantaNum.TETRATED_MAX_SAFE_INTEGER)) return this.gt(other)?this.clone():ExpantaNum.ZERO.clone(); return ExpantaNum.pow(10,this.log10().div(other)); }; Q.root=function (x,y){ return new ExpantaNum(x).root(y); }; P.generalLogarithm=P.log10=function (){ var x=this.clone(); if (ExpantaNum.debug>=ExpantaNum.NORMAL) console.log("log"+this); if (x.lt(ExpantaNum.ZERO)) return ExpantaNum.NaN.clone(); if (x.eq(ExpantaNum.ZERO)) return ExpantaNum.NEGATIVE_INFINITY.clone(); if (x.lte(ExpantaNum.MAX_SAFE_INTEGER)) return new ExpantaNum(Math.log10(x.toNumber())); if (!x.isFinite()) return x; if (x.gt(ExpantaNum.TETRATED_MAX_SAFE_INTEGER)) return x; x.operator(1,x.operator(1)-1); return x.normalize(); }; Q.generalLogarithm=Q.log10=function (x){ return new ExpantaNum(x).log10(); }; P.logarithm=P.logBase=function (base){ if (base===undefined) base=Math.E; return this.log10().div(ExpantaNum.log10(base)); }; Q.logarithm=Q.logBase=function (x,base){ return new ExpantaNum(x).logBase(base); }; P.naturalLogarithm=P.log=P.ln=function (){ return this.logBase(Math.E); }; Q.naturalLogarithm=Q.log=Q.ln=function (x){ return new ExpantaNum(x).ln(); }; //All of these are from Patashu's break_eternity.js var OMEGA=0.56714329040978387299997; //W(1,0) //from https://math.stackexchange.com/a/465183 //The evaluation can become inaccurate very close to the branch point var f_lambertw=function (z,tol,principal){ if (tol===undefined) tol=1e-10; if (principal===undefined) principal=true; var w; if (!Number.isFinite(z)) return z; if (principal){ if (z===0) return z; if (z===1) return OMEGA; if (z<10) w=0; else w=Math.log(z)-Math.log(Math.log(z)); }else{ if (z===0) return -Infinity; if (z<=-0.1) w=-2; else w=Math.log(-z)-Math.log(-Math.log(-z)); } for (var i=0;i<100;++i){ var wn=(z*Math.exp(-w)+w*w)/(w+1); if (Math.abs(wn-w)=ExpantaNum.NORMAL) console.log(t+"^^"+other); var negln; if (other.isInfinite()&&other.sign>0){ if (t.gte(Math.exp(1/Math.E))) return ExpantaNum.POSITIVE_INFINITY.clone(); //Formula for infinite height power tower. negln = t.ln().neg(); return negln.lambertw().div(negln); } if (other.lte(-2)) return ExpantaNum.NaN.clone(); if (t.eq(ExpantaNum.ZERO)){ if (other.eq(ExpantaNum.ZERO)) return ExpantaNum.NaN.clone(); if (other.mod(2).eq(ExpantaNum.ZERO)) return ExpantaNum.ZERO.clone(); return ExpantaNum.ONE.clone(); } if (t.eq(ExpantaNum.ONE)){ if (other.eq(ExpantaNum.ONE.neg())) return ExpantaNum.NaN.clone(); return ExpantaNum.ONE.clone(); } if (other.eq(ExpantaNum.ONE.neg())) return ExpantaNum.ZERO.clone(); if (other.eq(ExpantaNum.ZERO)) return ExpantaNum.ONE.clone(); if (other.eq(ExpantaNum.ONE)) return t; if (other.eq(2)) return t.pow(t); if (t.eq(2)){ if (other.eq(3)) return new ExpantaNum(16); if (other.eq(4)) return new ExpantaNum(65536); } var m=t.max(other); if (m.gt("10^^^"+MAX_SAFE_INTEGER)) return m; if (m.gt(ExpantaNum.TETRATED_MAX_SAFE_INTEGER)||other.gt(ExpantaNum.MAX_SAFE_INTEGER)){ if (this.lt(Math.exp(1/Math.E))){ negln = t.ln().neg(); return negln.lambertw().div(negln); } var j=t.slog(10).add(other); j.operator(2,(j.operator(2)||0)+1); j.normalize(); return j; } var y=other.toNumber(); var f=Math.floor(y); var r=t.pow(y-f); var l=ExpantaNum.NaN; for (var i=0,w=new ExpantaNum(ExpantaNum.E_MAX_SAFE_INTEGER);f!==0&&r.lt(w)&&i<100;++i){ if (f>0){ r=t.pow(r); if (l.eq(r)){ f=0; break; } l=r; --f; }else{ r=r.logBase(t); if (l.eq(r)){ f=0; break; } l=r; ++f; } } if (i==100||this.lt(Math.exp(1/Math.E))) f=0; r.operator(1,(r.operator(1)+f)||f); r.normalize(); return r; }; Q.tetrate=Q.tetr=function (x,y,payload){ return new ExpantaNum(x).tetr(y,payload); }; //Implementation of functions from break_eternity.js P.iteratedexp=function (other,payload){ return this.tetr(other,payload); }; Q.iteratedexp=function (x,y,payload){ return new ExpantaNum(x).iteratedexp(y,payload); }; //This implementation is highly inaccurate and slow, and probably be given custom code P.iteratedlog=function (base,other){ if (base===undefined) base=10; if (other===undefined) other=ExpantaNum.ONE.clone(); var t=this.clone(); base=new ExpantaNum(base); other=new ExpantaNum(other); if (other.eq(ExpantaNum.ZERO)) return t; if (other.eq(ExpantaNum.ONE)) return t.logBase(base); return base.tetr(t.slog(base).sub(other)); }; Q.iteratedlog=function (x,y,z){ return new ExpantaNum(x).iteratedlog(y,z); }; P.layeradd=function (other,base){ if (base===undefined) base=10; if (other===undefined) other=ExpantaNum.ONE.clone(); var t=this.clone(); base=new ExpantaNum(base); other=new ExpantaNum(other); return base.tetr(t.slog(base).add(other)); }; Q.layeradd=function (x,y,z){ return new ExpantaNum(x).layeradd(y,z); }; P.layeradd10=function (other){ return this.layeradd(other); }; Q.layeradd10=function (x,y){ return new ExpantaNum(x).layeradd10(y); }; //End implementation from break_eternity.js //All of these are from Patashu's break_eternity.js //The super square-root function - what number, tetrated to height 2, equals this? //Other sroots are possible to calculate probably through guess and check methods, this one is easy though. //https://en.wikipedia.org/wiki/Tetration#Super-root P.ssqrt=P.ssrt=function (){ var x=this.clone(); if (x.lt(Math.exp(-1/Math.E))) return ExpantaNum.NaN.clone(); if (!x.isFinite()) return x; if (x.gt(ExpantaNum.TETRATED_MAX_SAFE_INTEGER)) return x; if (x.gt(ExpantaNum.EE_MAX_SAFE_INTEGER)){ x.operator(1,x.operator(1)-1); return x; } var l=x.ln(); return l.div(l.lambertw()); }; Q.ssqrt=Q.ssrt=function (x){ return new ExpantaNum(x).ssqrt(); }; //Uses linear approximation //For more information, please see the break_eternity.js source: //https://github.com/Patashu/break_eternity.js/blob/848736e3dc37d8e7b5cc238f46e3ddb277d0dce2/src/index.ts#L4008 P.linear_sroot=function (degree){ var x=new ExpantaNum(this); degree=new ExpantaNum(degree); if (degree.isNaN()) return ExpantaNum.NaN.clone(); var degreeNum=Number(degree); if (degreeNum==1) return x; if (x.eq(ExpantaNum.POSITIVE_INFINITY)) return ExpantaNum.POSITIVE_INFINITY.clone(); if (!x.isFinite()) return ExpantaNum.NaN.clone(); if (degreeNum>0&°reeNum<1) return x.root(degree); if (degreeNum>-2&°reeNum<-1) return degree.add(2).pow(x.rec()); if (degreeNum<=0) return ExpantaNum.NaN.clone(); if (degree.gt(ExpantaNum.MAX_SAFE_INTEGER)){ var xNum=Number(x); if (xNum1/Math.E) return x.pow(x.rec()); if (x.gt(ExpantaNum.TETRATED_MAX_SAFE_INTEGER)){ var nh=x.slog(10).sub(degree); if (nh.lte(ExpantaNum.ZERO)) return new ExpantaNum(Math.exp(1/Math.E)); return ExpantaNum.tetr(10,nh); } return ExpantaNum.NaN.clone(); } if (x.eq(ExpantaNum.ONE)) return ExpantaNum.ONE.clone(); if (x.lt(ExpantaNum.ZERO)) return ExpantaNum.NaN.clone(); if (x.eq(ExpantaNum.ZERO)) return ExpantaNum.ZERO.clone(); if (x.gt(ExpantaNum.ONE)){ var upperBound; if (degreeNum<=1) upperBound=x.root(degree); else if (x.gte(ExpantaNum.tetr(10,degree))) upperBound=x.iteratedlog(10,degreeNum-1); else upperBound=new ExpantaNum(10); var lower=ExpantaNum.ZERO; var layer=upperBound.array[2]||0; var upper=upperBound.iteratedlog(10,layer); var guess=upper.div(2); while (true){ if (ExpantaNum.iteratedexp(10,layer,guess).tetr(degree).gt(x)) upper=guess; else lower=guess; var newguess=lower.add(upper).div(2); if (newguess.eq(guess)) break; guess=newguess; } return ExpantaNum.iteratedexp(10,layer,guess); }else{ var BIG=new ExpantaNum("10^^10"); var stage=1; var minimum=BIG; var maximum=BIG; var lower=BIG var upper=new ExpantaNum(1e-16) var prevspan=ExpantaNum.ZERO; var difference=BIG; var upperBound=ExpantaNum.pow(10,upper).rec(); var distance=ExpantaNum.ZERO; var prevPoint=upperBound; var nextPoint=upperBound; var evenDegree=Math.ceil(degreeNum)%2==0; var range=0; var lastValid=BIG; var infLoopDetector=false; var previousUpper=ExpantaNum.ZERO; var decreasingFound=false; while (stage<4){ if (stage==2){ if (evenDegree) break; lower=BIG; upper=minimum; stage=3; difference=BIG; lastValid=BIG; } infLoopDetector=false; while (upper.neq(lower)){ previousUpper=upper; var up10r=ExpantaNum.pow(10,upper).rec(); var up10rtd=up10r.tetr(degree); if (up10rtd.eq(ExpantaNum.ONE)&&up10r.lt(0.4)){ upperBound=up10r; prevPoint=up10r; nextPoint=up10r; distance=ExpantaNum.ZERO; range=-1; if (stage==3) lastValid=upper; }else if (up10rtd.eq(up10r)&&!evenDegree&&up10r.lt(0.4)){ upperBound=up10r; prevPoint=up10r; nextPoint=up10r; distance=ExpantaNum.ZERO; range=0; }else if (up10rtd.eq(up10r.mul(2).tetr(degree))){ upperBound=up10r; prevPoint=ExpantaNum.ZERO; nextPoint=upperBound.mul(2); distance=upperBound; if (evenDegree) range=-1; else range=0; }else{ prevspan=upper.mul(1.2e-16); upperBound=up10r; prevPoint=ExpantaNum.pow(10,upper.add(prevspan)).rec(); distance=upperBound.sub(prevPoint); nextPoint=upperBound.add(distance); var ubtd=upperBound.tetr(degree); //upperBound does not change during lifetime var pptd; var nptd; while (prevPoint.gte(upperBound)||nextPoint.lte(upperBound)||(pptd=prevPoint.tetr(degree)).eq(ubtd)||(nptd=nextPoint.tetr(degree)).eq(ubtd)){ prevspan=prevspan.mul(2); prevPoint=ExpantaNum.pow(10,upper.add(prevspan)).rec(); distance=upperBound.sub(prevPoint); nextPoint=upperBound.add(distance); } //pptd and nptd are up-to-date if (stage==1&&nptd.gt(ubtd)&&pptd.gt(ubtd)||stage==3&&nptd.lt(ubtd)&&pptd.lt(ubtd)) lastValid=upper; if (nptd.lt(ubtd)) range=-1; else if (evenDegree) range=1; else if (stage==3&&upper.gt_tolerance(minimum,1e-8)) range=0; else{ while (prevPoint.gte(upperBound)||nextPoint.lte(upperBound)||(pptd=prevPoint.tetr(degree)).eq_tolerance(ubtd,1e-8)||(nptd=nextPoint.tetr(degree)).eq_tolerance(ubtd,1e-8)){ prevspan=prevspan.mul(2); prevPoint=ExpantaNum.pow(10,upper.add(prevspan)).rec(); distance=upperBound.sub(prevPoint); nextPoint=upperBound.add(distance); } //pptd and nptd are up-to-date if (nptd.sub(ubtd).lt(ubtd.sub(pptd))) range=0; else range=1; } } if (range==-1) decreasingFound=true; if (stage==1&&range==1||stage==3&&range!=0){ if (lower.eq(BIG)) upper=upper.mul(2); else{ upper=upper.add(lower).div(2); if (infLoopDetector&&(range==1&&stage==1||range==-1&&stage==3)) break; } }else{ if (lower.eq(BIG)){ lower=upper; upper=upper.div(2); }else{ lower=lower.sub(difference); upper=upper.sub(difference); if (infLoopDetector&&(range==1&&stage==1||range==-1&&stage==3)) break; } } var newDifference=lower.sub(upper).div(2).abs(); if (newDifference.gt(difference.mul(1.5))) infLoopDetector=true; difference=newDifference; if (upper.gt(1e18)||upper.eq(previousUpper)) break; } if (upper.gt(1e18)) break; if (!decreasingFound) break; if (lastValid.eq(BIG)) break; if (stage==1) minimum=lastValid; else if (stage==3) maximum=lastValid; stage++; } lower=minimum; upper=new ExpantaNum(1e-18); var previous=upper; var guess=ExpantaNum.ZERO; var loopGoing=true; while (loopGoing){ if (lower.eq(BIG)) guess=upper.mul(2); else guess=lower.add(upper).div(2); if (ExpantaNum.pow(10,guess).rec().tetr(degree).gt(x)) upper=guess; else lower=guess; if (guess.eq(previous)) loopGoing=false; else previous=guess; if (upper.gt(1e18)) return ExpantaNum.NaN.clone(); } if (guess.neq_tolerance(minimum,1e-15)) return ExpantaNum.pow(10,guess).rec(); else{ if (maximum.eq(BIG)) return ExpantaNum.NaN.clone(); lower=BIG; upper=maximum; previous=upper; guess=ExpantaNum.ZERO; var loopGoing=true; while (loopGoing){ if (lower.eq(BIG)) guess=upper.mul(2); else guess=lower.add(upper).div(2); if (ExpantaNum.pow(10,guess).rec().tetr(degree).gt(x)) upper=guess; else lower=guess; if (guess.eq(previous)) loopGoing=false; else previous=guess; if (upper.gt(1e18)) return ExpantaNum.NaN.clone(); } return ExpantaNum.pow(10,guess).rec(); } } }; Q.linear_sroot=function (x,y){ return new ExpantaNum(x).linear_sroot(y); }; //Super-logarithm, one of tetration's inverses, tells you what size power tower you'd have to tetrate base to to get number. By definition, will never be higher than 1.8e308 in break_eternity.js, since a power tower 1.8e308 numbers tall is the largest representable number. //Uses linear approximation //https://en.wikipedia.org/wiki/Super-logarithm P.slog=function (base){ if (base===undefined) base=10; var x=this.clone(); base=new ExpantaNum(base); if (x.isNaN()||base.isNaN()||x.isInfinite()&&base.isInfinite()) return ExpantaNum.NaN.clone(); if (x.isInfinite()) return x; if (base.isInfinite()) return ExpantaNum.ZERO.clone(); if (x.eq(ExpantaNum.ZERO)) return ExpantaNum.ONE.neg(); if (x.eq(ExpantaNum.ONE)) return ExpantaNum.ZERO.clone(); if (x.eq(base)) return ExpantaNum.ONE.clone(); if (base.lt(Math.exp(1/Math.E))){ var a=ExpantaNum.tetr(base,Infinity); if (x.eq(a)) return ExpantaNum.POSITIVE_INFINITY.clone(); if (x.gt(a)) return ExpantaNum.NaN.clone(); } if (x.max(base).gt("10^^^"+MAX_SAFE_INTEGER)){ if (x.gt(base)) return x; return ExpantaNum.ZERO.clone(); } if (x.max(base).gt(ExpantaNum.TETRATED_MAX_SAFE_INTEGER)){ if (x.gt(base)){ x.operator(2,x.operator(2)-1); x.normalize(); return x.sub(x.operator(1)); } return ExpantaNum.ZERO.clone(); } if (x.lt(ExpantaNum.ZERO)) return base.pow(x).sub(2); //Inversion of x^^y=log_x(2+y) for -23){ var l=t-3; r+=l; x.operator(1,x.operator(1)-l); } for (var i=0;i<100;++i){ if (x.lte(ExpantaNum.ONE)) return new ExpantaNum(r+x.toNumber()-1); ++r; x=ExpantaNum.logBase(x,base); } return ExpantaNum.NaN.clone(); //Failed to converge }; Q.slog=function (x,y){ return new ExpantaNum(x).slog(y); }; //end break_eternity.js excerpt P.pentate=P.pent=function (other){ return this.arrow(3)(other); }; Q.pentate=Q.pent=function (x,y){ return ExpantaNum.arrow(x,3,y); }; P.penta_log=function (other){ return this.arrow_height_inverse(3)(other); }; Q.penta_log=function (x,y){ return ExpantaNum.arrow_height_inverse(x,3,y); }; //Uses linear approximations for real height P.arrow=function (arrows){ var t=this.clone(); arrows=new ExpantaNum(arrows); if (!arrows.isint()||arrows.lt(ExpantaNum.ZERO)) return function(other){return ExpantaNum.NaN.clone();}; if (arrows.eq(ExpantaNum.ZERO)) return function(other){return t.mul(other);}; if (arrows.eq(ExpantaNum.ONE)) return function(other){return t.pow(other);}; if (arrows.eq(2)) return function(other,payload){return t.tetr(other,payload);}; return function (other,payload,depth){ if (payload===undefined) payload=ExpantaNum.ONE; if (depth===undefined) depth=0; other=new ExpantaNum(other); payload=new ExpantaNum(payload); if (t.isNaN()||other.isNaN()||payload.isNaN()) return ExpantaNum.NaN.clone(); if (payload.neq(ExpantaNum.ONE)) other=other.add(payload.arrow_height_inverse(arrows)(t)); if (ExpantaNum.debug>=ExpantaNum.NORMAL) console.log(t+"{"+arrows+"}"+other); if (t.eq(ExpantaNum.ZERO)){ if (other.eq(ExpantaNum.ONE)) return ExpantaNum.ZERO.clone(); return ExpantaNum.NaN.clone(); } if (t.eq(ExpantaNum.ONE)) return ExpantaNum.ONE.clone(); if (other.eq(ExpantaNum.ZERO)) return ExpantaNum.ONE.clone(); if (other.eq(ExpantaNum.ONE)) return t.clone(); //By induction: See initialization of r in the fallthrough branch if (other.gt(ExpantaNum.ZERO)&&other.lt(ExpantaNum.ONE)) return t.pow(other); if (other.gt(ExpantaNum.ONE)&&arrows.gt(ExpantaNum.MAX_SAFE_INTEGER)){ var r=arrows.clone(); r.layer++; return r; } var arrowsNum=arrows.toNumber(); if (other.eq(2)) return t.arrow(arrowsNum-1)(t,ExpantaNum.ONE,depth+1); if (t.max(other).gt("10{"+(arrowsNum+1)+"}"+MAX_SAFE_INTEGER)) return t.max(other); if (t.gt("10{"+arrowsNum+"}"+MAX_SAFE_INTEGER)||other.gt(ExpantaNum.MAX_SAFE_INTEGER)){ var r; if (t.gt("10{"+arrowsNum+"}"+MAX_SAFE_INTEGER)){ r=t.clone(); r.operator(arrowsNum,r.operator(arrowsNum)-1); r.normalize(); }else if (t.gt("10{"+(arrowsNum-1)+"}"+MAX_SAFE_INTEGER)){ r=new ExpantaNum(t.operator(arrowsNum-1)); }else{ r=ExpantaNum.ZERO; } var j=r.add(other); j.operator(arrowsNum,(j.operator(arrowsNum)||0)+1); j.normalize(); return j; } if (depth>=ExpantaNum.maxOps+10){ return new ExpantaNum([[0,10],[arrowsNum,1]]); } var y=other.toNumber(); var f=Math.floor(y); var arrows_m1=arrows.sub(ExpantaNum.ONE); var r=t.arrow(arrows_m1)(y-f,ExpantaNum.ONE,depth+1); var l=ExpantaNum.NaN; for (var i=0,m=new ExpantaNum("10{"+(arrowsNum-1)+"}"+MAX_SAFE_INTEGER);f!==0&&r.lt(m)&&i<100;++i){ if (f>0){ r=t.arrow(arrows_m1)(r,ExpantaNum.ONE,depth+1); if (l.eq(r)){ f=0; break; } l=r; --f; }else{ r=r.arrow_height_inverse(arrows_m1)(t); if (l.eq(r)){ f=0; break; } l=r; ++f; } } if (i==100) f=0; r.operator(arrowsNum-1,(r.operator(arrowsNum-1)+f)||f); r.normalize(); return r; }; }; P.chain=function (other,arrows){ return this.arrow(arrows)(other); }; Q.arrow=function (x,z,y,payload){ return new ExpantaNum(x).arrow(z)(y,payload); }; Q.chain=function (x,y,z){ return new ExpantaNum(x).arrow(z)(y); }; Q.hyper=function (z){ z=new ExpantaNum(z); if (z.eq(ExpantaNum.ZERO)) return function(x,y){return new ExpantaNum(y).eq(ExpantaNum.ZERO)?new ExpantaNum(x):new ExpantaNum(x).add(ExpantaNum.ONE);}; if (z.eq(ExpantaNum.ONE)) return function(x,y){return ExpantaNum.add(x,y);}; return function(x,y,payload){return new ExpantaNum(x).arrow(z.sub(2))(y,payload);}; }; //arrow_height_inverse{z}_x(x{z}y)=y //See also: https://github.com/Patashu/break_eternity.js/blob/848736e3dc37d8e7b5cc238f46e3ddb277d0dce2/src/index.ts#L4647 P.arrow_height_inverse=function (arrows){ var x=this.clone(); arrows=new ExpantaNum(arrows); if (!arrows.isint()||arrows.lt(ExpantaNum.ONE)) return function(other){return ExpantaNum.NaN.clone();}; if (arrows.eq(ExpantaNum.ONE)) return function(base){return x.logBase(base);}; if (arrows.eq(2)) return function(base){return x.slog(base);}; return function (base,depth){ if (base===undefined) base=10; if (depth===undefined) depth=0; base=new ExpantaNum(base); if (x.isNaN()||base.isNaN()||x.isInfinite()&&base.isInfinite()) return ExpantaNum.NaN.clone(); if (base.lte(ExpantaNum.ONE)) return ExpantaNum.NaN.clone(); if (x.isInfinite()) return x; if (base.isInfinite()) return ExpantaNum.ZERO.clone(); if (x.eq(ExpantaNum.ZERO)) return ExpantaNum.ONE.neg(); if (x.eq(ExpantaNum.ONE)) return ExpantaNum.ZERO.clone(); if (x.eq(base)) return ExpantaNum.ONE.clone(); //Inverse of shortcut for 00) return x; return ExpantaNum.ONE.clone(); //base{arrows}(1+epsilon) explodes } var arrowsNum=arrows.toNumber(); if (arrowsNum==2&&x.lt(ExpantaNum.ONE.neg())){ if (x.lt(-2)) return ExpantaNum.NaN.clone(); var infrcmp=x.cmp(base.arrow(arrows.sub(ExpantaNum.ONE))(x)); if (infrcmp==0) return ExpantaNum.NEGATIVE_INFINITY.clone(); if (infrcmp>0) return ExpantaNum.NaN.clone(); } if (x.max(base).gt("10{"+(arrowsNum+1)+"}"+MAX_SAFE_INTEGER)){ if (x.gt(base)) return x; return ExpantaNum.ZERO.clone(); } if (x.max(base).gt("10{"+arrowsNum+"}"+MAX_SAFE_INTEGER)){ if (x.gt(base)){ x.operator(arrowsNum,x.operator(arrowsNum)-1); x.normalize(); return x.sub(x.operator(arrowsNum-1)); } return ExpantaNum.ZERO.clone(); } var r=0; var t=(x.operator(arrowsNum-1)||0)-(base.operator(arrowsNum-1)||0); if (depth>=ExpantaNum.maxOps+10) return new ExpantaNum(t); if (t>3){ var l=t-3; r+=l; x.operator(arrowsNum-1,x.operator(arrowsNum-1)-l); } var arrows_m1=arrows.sub(ExpantaNum.ONE); for (var i=0;i<100;++i){ if (x.lt(ExpantaNum.ZERO)){ x=base.arrow(arrows_m1)(x); --r; }else if (x.lte(ExpantaNum.ONE)){ return new ExpantaNum(r+x.toNumber()-1); }else{ ++r; x=x.arrow_height_inverse(arrows_m1)(base,depth+1); } } return ExpantaNum.NaN.clone(); //Failed to converge }; }; Q.arrow_height_inverse=function (x,z,y){ return new ExpantaNum(x).arrow_height_inverse(z)(y); } P.expansion=function (other){ var t=this.clone(); other=new ExpantaNum(other); var r; if (ExpantaNum.debug>=ExpantaNum.NORMAL) console.log("{"+t+","+other+",1,2}"); if (other.lte(ExpantaNum.ZERO)||!other.isint()) return ExpantaNum.NaN.clone(); if (other.eq(ExpantaNum.ONE)) return t.clone(); if (!t.isint()) return ExpantaNum.NaN.clone(); if (t.eq(2)) return new ExpantaNum(4); if (other.gt(ExpantaNum.MAX_SAFE_INTEGER)) return ExpantaNum.POSITIVE_INFINITY.clone(); var f=other.toNumber()-1; r=t; for (var i=0;f!==0&&r.lt(ExpantaNum.MAX_SAFE_INTEGER)&&i<100;++i){ if (f>0){ r=t.arrow(r)(t); --f; } } if (i==100) f=0; r.layer+=f; r.normalize(); return r; }; Q.expansion=function (x,y){ return new ExpantaNum(x).expansion(y); }; // All of these are from Patashu's break_eternity.js Q.affordGeometricSeries = function (resourcesAvailable, priceStart, priceRatio, currentOwned) { /* If you have resourcesAvailable, the price of something starts at priceStart, and on each purchase it gets multiplied by priceRatio, and you have already bought currentOwned, how many of the object can you buy. */ resourcesAvailable=new ExpantaNum(resourcesAvailable); priceStart=new ExpantaNum(priceStart); priceRatio=new ExpantaNum(priceRatio); var actualStart = priceStart.mul(priceRatio.pow(currentOwned)); return ExpantaNum.floor(resourcesAvailable.div(actualStart).mul(priceRatio.sub(ExpantaNum.ONE)).add(ExpantaNum.ONE).log10().div(priceRatio.log10())); }; Q.affordArithmeticSeries = function (resourcesAvailable, priceStart, priceAdd, currentOwned) { /* If you have resourcesAvailable, the price of something starts at priceStart, and on each purchase it gets increased by priceAdd, and you have already bought currentOwned, how many of the object can you buy. */ resourcesAvailable=new ExpantaNum(resourcesAvailable); priceStart=new ExpantaNum(priceStart); priceAdd=new ExpantaNum(priceAdd); currentOwned=new ExpantaNum(currentOwned); var actualStart = priceStart.add(currentOwned.mul(priceAdd)); var b = actualStart.sub(priceAdd.div(2)); var b2 = b.pow(2); return b.neg().add(b2.add(priceAdd.mul(resourcesAvailable).mul(2)).sqrt()).div(priceAdd).floor(); }; Q.sumGeometricSeries = function (numItems, priceStart, priceRatio, currentOwned) { /* If you want to buy numItems of something, the price of something starts at priceStart, and on each purchase it gets multiplied by priceRatio, and you have already bought currentOwned, what will be the price of numItems of something. */ priceStart=new ExpantaNum(priceStart); priceRatio=new ExpantaNum(priceRatio); return priceStart.mul(priceRatio.pow(currentOwned)).mul(ExpantaNum.sub(ExpantaNum.ONE, priceRatio.pow(numItems))).div(ExpantaNum.sub(ExpantaNum.ONE, priceRatio)); }; Q.sumArithmeticSeries = function (numItems, priceStart, priceAdd, currentOwned) { /* If you want to buy numItems of something, the price of something starts at priceStart, and on each purchase it gets increased by priceAdd, and you have already bought currentOwned, what will be the price of numItems of something. */ numItems=new ExpantaNum(numItems); priceStart=new ExpantaNum(priceStart); currentOwned=new ExpantaNum(currentOwned); var actualStart = priceStart.add(currentOwned.mul(priceAdd)); return numItems.div(2).mul(actualStart.mul(2).plus(numItems.sub(ExpantaNum.ONE).mul(priceAdd))); }; // Binomial Coefficients n choose k Q.choose = function (n, k) { /* If you have n items and you take k out, how many ways could you do this? */ return new ExpantaNum(n).factorial().div(new ExpantaNum(k).factorial().mul(new ExpantaNum(n).sub(new ExpantaNum(k)).factorial())); }; P.choose = function (other) { return ExpantaNum.choose(this, other); }; //end break_eternity.js excerpt P.normalize=function (){ var b; var x=this; if (ExpantaNum.debug>=ExpantaNum.ALL) console.log(x.toString()); if (!x.array||!x.array.length) x.array=[[0,0]]; if (x.sign!=1&&x.sign!=-1){ if (typeof x.sign!="number") x.sign=Number(x.sign); x.sign=x.sign<0?-1:1; } if (x.layer>MAX_SAFE_INTEGER){ x.array=[[0,Infinity]]; x.layer=0; return x; } if (Number.isInteger(x.layer)) x.layer=Math.floor(x.layer); for (var i=0;i=ExpantaNum.ALL) console.log(x.toString()); b=false; x.array.sort(function (a,b){return a[0]>b[0]?1:a[0]ExpantaNum.maxOps) x.array.splice(0,x.array.length-ExpantaNum.maxOps); if (!x.array.length) x.array=[[0,0]]; if (x.array[x.array.length-1][0]>MAX_SAFE_INTEGER){ x.layer++; x.array=[[0,x.array[x.array.length-1][0]]]; b=true; }else if (x.layer&&x.array.length==1&&x.array[0][0]===0){ x.layer--; if (x.array[0][1]===0) x.array=[[0,10]]; else x.array=[[0,10],[Math.round(x.array[0][1]),1]]; b=true; } if (x.array.lengthMAX_SAFE_INTEGER){ if (x.array.length>=2&&x.array[1][0]==1){ x.array[1][1]++; }else{ x.array.splice(1,0,[1,1]); } x.array[0][1]=Math.log10(x.array[0][1]); b=true; } while (x.array.length>=2&&x.array[0][0]===0&&x.array[0][1]1){ x.array[1][1]--; }else{ x.array.splice(1,1); } b=true; } while (x.array.length>=2&&x.array[0][0]===0&&x.array[0][1]==1&&x.array[1][1]){ if (x.array[1][1]>1){ x.array[1][1]--; }else{ x.array.splice(1,1); } x.array[0][1]=10; } if (x.array.length>=2&&x.array[0][0]===0&&x.array[1][0]!=1){ var p=1; if (Math.floor(x.array[0][1])) x.array.splice(1,0,[x.array[1][0]-1,Math.floor(x.array[0][1])]),p++; x.array[0][1]=Math.pow(10,x.array[0][1]-Math.floor(x.array[0][1])); if (x.array[p][1]>1){ x.array[p][1]--; }else{ x.array.splice(p,1); } b=true; } for (i=0;iMAX_SAFE_INTEGER){ if (i!=x.array.length-1&&x.array[i+1][0]==x.array[i][0]+1){ x.array[i+1][1]++; }else{ x.array.splice(i+1,0,[x.array[i][0]+1,1]); } x.array.splice(0,i+1,[0,x.array[i][1]+1]); b=true; } } }while(b); if (!x.array.length) x.array=[[0,0]]; return x; }; var standardizeMessageSent=false; P.standardize=function (){ if (!standardizeMessageSent) console.warn(expantaNumError+"'standardize' method is being deprecated in favor of 'normalize' and will be removed in the future!"),standardizeMessageSent=true; return this.normalize(); } P.toNumber=function (){ //console.log(this.array); if (this.sign==-1) return -1*this.abs(); if (this.layer>0||this.array.length>=2&&(this.array[1][0]>=2||this.array[1][1]>=2||this.array[1][1]==1&&this.array[0][1]>Math.log10(Number.MAX_VALUE))) return Infinity; if (this.array.length>=2&&this.array[1][1]==1) return Math.pow(10,this.array[0][1]); return this.array[0][1]; }; P.toString=function (){ if (this.sign==-1) return "-"+this.abs(); if (isNaN(this.array[0][1])) return "NaN"; if (!isFinite(this.array[0][1])) return "Infinity"; var s=""; if (!this.layer) s+=""; else if (this.layer<3) s+="J".repeat(this.layer); else s+="J^"+this.layer+" "; if (this.array.length>=3||this.array.length==2&&this.array[1][0]>=2){ for (var i=this.array.length-1;i>=2;--i){ var e=this.array[i]; var q=e[0]>=5?"{"+e[0]+"}":"^".repeat(e[0]); if (e[1]>1) s+="(10"+q+")^"+e[1]+" "; else if (e[1]==1) s+="10"+q; } } var op0=this.operator(0); var op1=this.operator(1); if (!op1) s+=String(op0); else if (op1<3) s+="e".repeat(op1-1)+Math.pow(10,op0-Math.floor(op0))+"e"+Math.floor(op0); else if (op1<8) s+="e".repeat(op1)+op0; else s+="(10^)^"+op1+" "+op0; return s; }; //from break_eternity.js var decimalPlaces=function decimalPlaces(value,places){ var len=places+1; var numDigits=Math.ceil(Math.log10(Math.abs(value))); if (numDigits<100) numDigits=0; //A hack-y solution to https://github.com/Naruyoko/ExpantaNum.js/issues/22 var rounded=Math.round(value*Math.pow(10,len-numDigits))*Math.pow(10,numDigits-len); return parseFloat(rounded.toFixed(Math.max(len-numDigits,0))); }; P.toStringWithDecimalPlaces=function (places,applyToOpNums){ if (this.sign==-1) return "-"+this.abs(); if (isNaN(this.array[0][1])) return "NaN"; if (!isFinite(this.array[0][1])) return "Infinity"; var b=0; var s=""; var m=Math.pow(10,places); if (!this.layer) s+=""; else if (this.layer<3) s+="J".repeat(this.layer); else s+="J^"+this.layer+" "; if (this.array.length>=3||this.array.length==2&&this.array[1][0]>=2){ for (var i=this.array.length-1;!b&&i>=2;--i){ var e=this.array[i]; var w=e[0]; var x=e[1]; if (applyToOpNums&&x>=m){ ++w; b=x; x=1; }else if (applyToOpNums&&this.array[i-1][0]==w-1&&this.array[i-1][1]>=m){ ++x; b=this.array[i-1][1]; } var q=w>=5?"{"+w+"}":"^".repeat(w); if (x>1) s+="(10"+q+")^"+x+" "; else if (x==1) s+="10"+q; } } var k=this.operator(0); var l=this.operator(1); if (k>m){ k=Math.log10(k); ++l; } if (b) s+=decimalPlaces(b,places); else if (!l) s+=String(decimalPlaces(k,places)); else if (l<3) s+="e".repeat(l-1)+decimalPlaces(Math.pow(10,k-Math.floor(k)),places)+"e"+decimalPlaces(Math.floor(k),places); else if (l<8) s+="e".repeat(l)+decimalPlaces(k,places); else if (applyToOpNums) s+="(10^)^"+decimalPlaces(l,places)+" "+decimalPlaces(k,places); else s+="(10^)^"+l+" "+decimalPlaces(k,places); return s; }; //these are from break_eternity.js as well P.toExponential=function (places,applyToOpNums){ if (this.array.length==1) return (this.sign*this.array[0][1]).toExponential(places); return this.toStringWithDecimalPlaces(places,applyToOpNums); }; P.toFixed=function (places,applyToOpNums){ if (this.array.length==1) return (this.sign*this.array[0][1]).toFixed(places); return this.toStringWithDecimalPlaces(places,applyToOpNums); }; P.toPrecision=function (places,applyToOpNums){ if (this.array[0][1]===0) return (this.sign*this.array[0][1]).toFixed(places-1,applyToOpNums); if (this.array.length==1&&this.array[0][1]<1e-6) return this.toExponential(places-1,applyToOpNums); if (this.array.length==1&&places>Math.log10(this.array[0][1])) return this.toFixed(places-Math.floor(Math.log10(this.array[0][1]))-1,applyToOpNums); return this.toExponential(places-1,applyToOpNums); }; P.valueOf=function (){ return this.toString(); }; //Note: toArray() would be impossible without changing the layout of the array or lose the information about the sign P.toJSON=function (){ if (ExpantaNum.serializeMode==ExpantaNum.JSON){ var a=[]; for (var i=0;i=BigInt(1)<BigInt(0)){ if (input>=BigInt(1)<>cutbits; return Math.log10(Number(firstbits))+Math.LOG10E/Math.LOG2E*Number(cutbits); } Q.fromBigInt=function (input){ if (typeof input!="bigint") throw Error(invalidArgument+"Expected BigInt"); var x=new ExpantaNum(); var abs=input=2&&x.array[1][0]==1){ x.array[1][1]+=c; }else{ x.array.splice(1,0,[1,c]); } }else if (arrows==2){ a=x.array.length>=2&&x.array[1][0]==1?x.array[1][1]:0; b=x.array[0][1]; if (b>=1e10) ++a; if (b>=10) ++a; x.array[0][1]=a; if (x.array.length>=2&&x.array[1][0]==1) x.array.splice(1,1); d=x.getOperatorIndex(2); if (Number.isInteger(d)) x.array[d][1]+=c; else x.array.splice(Math.ceil(d),0,[2,c]); }else{ a=x.operator(arrows-1); b=x.operator(arrows-2); if (b>=10) ++a; d=x.getOperatorIndex(arrows); x.array.splice(1,Math.ceil(d)-1); x.array[0][1]=a; if (Number.isInteger(d)) x.array[1][1]+=c; else x.array.splice(1,0,[arrows,c]); } }else{ break; } } a=input.split(/[Ee]/); b=[x.array[0][1],0]; c=1; for (i=a.length-1;i>=0;--i){ //The things that are already there if (b[0]=LONG_STRING_MIN_LENGTH) b[0]=Math.log10(b[0])+log10LongString(a[i].substring(0,intPartLen)),b[1]=1; else if (a[i]) b[0]*=Number(a[i]); }else{ d=intPartLen>=LONG_STRING_MIN_LENGTH?log10LongString(a[i].substring(0,intPartLen)):a[i]?Math.log10(Number(a[i])):0; if (b[1]==1){ b[0]+=d; }else if (b[1]==2&&b[0]MAX_SAFE_INTEGER){ b[0]=Math.log10(b[0]); b[1]++; } } x.array[0][1]=b[0]; if (b[1]){ if (x.array.length>=2&&x.array[1][0]==1) x.array[1][1]+=b[1]; else x.array.splice(1,0,[1,b[1]]); } } if (negateIt) x.sign*=-1; x.normalize(); return x; }; Q.fromArray=function (input1,input2,input3){ var array,layer,sign; if (input1 instanceof Array&&(input2===undefined||typeof input2=="number")&&(input3===undefined||typeof input3=="number")){ array=input1; sign=input2; layer=input3||0; }else if (typeof input1=="number"&&input2 instanceof Array&&(input3===undefined||typeof input3=="number")){ array=input2; sign=input1; layer=input3||0; }else if (typeof input1=="number"&&typeof input2=="number"&&input3 instanceof Array){ array=input3; sign=input1; layer=input2; }else{ throw Error(invalidArgument+"Expected an Array [and 1 or 2 Number]"); } var x=new ExpantaNum(); var i; if (!array.length) x.array=[[0,0]]; else if (typeof array[0]=="number"){ x.array=[]; for (i=0;i=2){ --t; } x.array[i]=[i,t]; } } if (negateIt) x.sign*=-1; x.normalize(); return x; }; P.getOperatorIndex=function (i){ if (typeof i!="number") i=Number(i); if (!isFinite(i)) throw Error(invalidArgument+"Index out of range."); var a=this.array; var min=0,max=a.length-1; if (a[max][0]i) return -0.5; while (min!=max){ if (a[min][0]==i) return min; if (a[max][0]==i) return max; var mid=Math.floor((min+max)/2); if (min==mid||a[mid][0]==i){ min=mid; break; } if (a[mid][0]i) max=mid; } return a[min][0]==i?min:min+0.5; }; P.getOperator=function (i){ if (typeof i!="number") i=Number(i); if (!isFinite(i)) throw Error(invalidArgument+"Index out of range."); var ai=this.getOperatorIndex(i); if (Number.isInteger(ai)) return this.array[ai][1]; else return i===0?10:0; }; P.setOperator=function (i,value){ if (typeof i!="number") i=Number(i); if (!isFinite(i)) throw Error(invalidArgument+"Index out of range."); var ai=this.getOperatorIndex(i); if (Number.isInteger(ai)) this.array[ai][1]=value; else{ ai=Math.ceil(ai); this.array.splice(ai,0,[i,value]); } this.normalize(); }; P.operator=function (i,value){ if (value===undefined) return this.getOperator(i); else this.setOperator(i,value); }; P.clone=function (){ var temp=new ExpantaNum(); var array=[]; for (var i=0;i= ps[i + 1] && v <= ps[i + 2]) this[p] = v; else throw Error(invalidArgument + p + ': ' + v); } } return this; } // Create and configure initial ExpantaNum constructor. ExpantaNum=clone(ExpantaNum); ExpantaNum=defineConstants(ExpantaNum); ExpantaNum['default']=ExpantaNum.ExpantaNum=ExpantaNum; // Export. // AMD. if (typeof define == 'function' && define.amd) { define(function () { return ExpantaNum; }); // Node and other environments that support module.exports. } else if (typeof module != 'undefined' && module.exports) { module.exports = ExpantaNum; // Browser. } else { if (!globalScope) { globalScope = typeof self != 'undefined' && self && self.self == self ? self : Function('return this')(); } globalScope.ExpantaNum = ExpantaNum; } })(this);