diff --git a/index.html b/index.html index e17fee0..101b130 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ The Prestige Tree - + @@ -86,6 +86,12 @@
  • Implemented some new milestones
  • Balanced up to 5 Hindrance Spirit & 5 Quirks
  • +

    Beta v1.1 Alpha 3

    +





    @@ -220,6 +226,8 @@ 2 Hindrance Spirit
    Keep all third row milestones on all fourth row resets, and start with your best-ever Space 4 Hindrance Spirit
    Keep Time, Enhance, and Space Upgrades on all fourth row resets 5 Hindrance Spirit
    Automatically purchase Extra Time Capsules    + 10 Hindrance Spirit
    Keep Prestige & Super-Booster Upgrades on all fourth row resets + 15 Hindrance Spirit
    Automatically purchase Super-Boosters   
    @@ -228,6 +236,8 @@ 2 Quirks
    You can buy max Time Capsules & Space Energy 4 Quirks
    Keep Space Buildings on all fourth row resets 5 Quirks
    Automatically purchase Enhancers    + 10 Quirks
    Automatically purchase Time Capsules & Space Energy
      + 15 Quirks
    Gain 100% of Enhance Point gain every second

    diff --git a/js/break_eternity.js b/js/break_eternity.js new file mode 100644 index 0000000..1c87339 --- /dev/null +++ b/js/break_eternity.js @@ -0,0 +1,2746 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = global || self, global.Decimal = factory()); +}(this, function () { 'use strict'; + + var padEnd = function (string, maxLength, fillString) { + + if (string === null || maxLength === null) { + return string; + } + + var result = String(string); + var targetLen = typeof maxLength === 'number' + ? maxLength + : parseInt(maxLength, 10); + + if (isNaN(targetLen) || !isFinite(targetLen)) { + return result; + } + + + var length = result.length; + if (length >= targetLen) { + return result; + } + + + var filled = fillString === null ? '' : String(fillString); + if (filled === '') { + filled = ' '; + } + + + var fillLen = targetLen - length; + + while (filled.length < fillLen) { + filled += filled; + } + + var truncated = filled.length > fillLen ? filled.substr(0, fillLen) : filled; + + return result + truncated; + }; + + var MAX_SIGNIFICANT_DIGITS = 17; //Maximum number of digits of precision to assume in Number + + var EXP_LIMIT = 9e15; //If we're ABOVE this value, increase a layer. (9e15 is close to the largest integer that can fit in a Number.) + + var LAYER_DOWN = Math.log10(9e15); //If we're BELOW this value, drop down a layer. About 15.954. + + var FIRST_NEG_LAYER = 1/9e15; //At layer 0, smaller non-zero numbers than this become layer 1 numbers with negative mag. After that the pattern continues as normal. + + var NUMBER_EXP_MAX = 308; //The largest exponent that can appear in a Number, though not all mantissas are valid here. + + var NUMBER_EXP_MIN = -324; //The smallest exponent that can appear in a Number, though not all mantissas are valid here. + + var MAX_ES_IN_A_ROW = 5; //For default toString behaviour, when to swap from eee... to (e^n) syntax. + + var powerOf10 = function () { + // We need this lookup table because Math.pow(10, exponent) + // when exponent's absolute value is large is slightly inaccurate. + // You can fix it with the power of math... or just make a lookup table. + // Faster AND simpler + var powersOf10 = []; + + for (var i = NUMBER_EXP_MIN + 1; i <= NUMBER_EXP_MAX; i++) { + powersOf10.push(Number("1e" + i)); + } + + var indexOf0InPowersOf10 = 323; + return function (power) { + return powersOf10[power + indexOf0InPowersOf10]; + }; + }(); + + var D = function D(value) { + return Decimal.fromValue_noAlloc(value); + }; + + var FC = function FC(sign, layer, mag) { + return Decimal.fromComponents(sign, layer, mag); + }; + + var FC_NN = function FC_NN(sign, layer, mag) { + return Decimal.fromComponents_noNormalize(sign, layer, mag); + }; + + var ME = function ME(mantissa, exponent) { + return Decimal.fromMantissaExponent(mantissa, exponent); + }; + + var ME_NN = function ME_NN(mantissa, exponent) { + return Decimal.fromMantissaExponent_noNormalize(mantissa, exponent); + }; + + var decimalPlaces = function decimalPlaces(value, places) { + var len = places + 1; + var numDigits = Math.ceil(Math.log10(Math.abs(value))); + var rounded = Math.round(value * Math.pow(10, len - numDigits)) * Math.pow(10, numDigits - len); + return parseFloat(rounded.toFixed(Math.max(len - numDigits, 0))); + }; + + var f_maglog10 = function(n) { + return Math.sign(n)*Math.log10(Math.abs(n)); + } + + //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 = l + (n+0.5)*Math.log(n); + l = l - n; + var n2 = n*n; + var np = n; + l = l+1/(12*np); + np = np*n2; + l = l+1/(360*np); + np = np*n2; + l = l+1/(1260*np); + np = np*n2; + l = l+1/(1680*np); + np = np*n2; + l = l+1/(1188*np); + np = np*n2; + l = l+691/(360360*np); + np = np*n2; + l = l+7/(1092*np); + np = np*n2; + l = l+3617/(122400*np); + + return Math.exp(l)/scal1; + }; + + var twopi = 6.2831853071795864769252842; // 2*pi + var EXPN1 = 0.36787944117144232159553; // exp(-1) + 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 = 1e-10) { + var w; + var wn; + + if (!Number.isFinite(z)) { return z; } + 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)); + } + + for (var i = 0; i < 100; ++i) + { + wn = (z * Math.exp(-w) + w * w)/(w + 1); + if (Math.abs(wn - w) < tol*Math.abs(wn)) + { + return wn; + } + else + { + w = wn; + } + } + + throw Error("Iteration failed to converge: " + z); + //return Number.NaN; + } + + var Decimal = + /** @class */ + function () { + + function Decimal(value) { + + this.sign = Number.NaN; + this.layer = Number.NaN; + this.mag = Number.NaN; + + if (value instanceof Decimal) { + this.fromDecimal(value); + } else if (typeof value === "number") { + this.fromNumber(value); + } else if (typeof value === "string") { + this.fromString(value); + } else { + this.sign = 0; + this.layer = 0; + this.mag = 0; + } + + if (isNaN(this.sign)) this.sign = 0 + if (isNaN(this.layer)) this.layer = 0 + if (isNaN(this.mag)) this.mag = 0 + } + + Object.defineProperty(Decimal.prototype, "m", { + get: function get() { + if (this.sign === 0) + { + return 0; + } + else if (this.layer === 0) + { + var exp = Math.floor(Math.log10(this.mag)); + //handle special case 5e-324 + var man; + if (this.mag === 5e-324) + { + man = 5; + } + else + { + man = this.mag / powerOf10(exp); + } + return this.sign*man; + } + else if (this.layer === 1) + { + var residue = this.mag-Math.floor(this.mag); + return this.sign*Math.pow(10, residue); + } + else + { + //mantissa stops being relevant past 1e9e15 / ee15.954 + return this.sign; + } + }, + set: function set(value) { + if (this.layer <= 2) + { + this.fromMantissaExponent(value, this.e); + } + else + { + //don't even pretend mantissa is meaningful + this.sign = Math.sign(value); + if (this.sign === 0) { this.layer === 0; this.exponent === 0; } + } + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Decimal.prototype, "e", { + get: function get() { + if (this.sign === 0) + { + return 0; + } + else if (this.layer === 0) + { + return Math.floor(Math.log10(this.mag)); + } + else if (this.layer === 1) + { + return Math.floor(this.mag); + } + else if (this.layer === 2) + { + return Math.floor(Math.sign(this.mag)*Math.pow(10, Math.abs(this.mag))); + } + else + { + return this.mag*Number.POSITIVE_INFINITY; + } + }, + set: function set(value) { + this.fromMantissaExponent(this.m, value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Decimal.prototype, "s", { + get: function get() { + return this.sign; + }, + set: function set(value) { + if (value === 0) { + this.sign = 0; + this.layer = 0; + this.mag = 0; + } + else + { + this.sign = value; + } + }, + enumerable: true, + configurable: true + }); + + Object.defineProperty(Decimal.prototype, "mantissa", { + get: function get() { + return this.m; + }, + set: function set(value) { + this.m = value; + }, + enumerable: true, + configurable: true + }); + + Object.defineProperty(Decimal.prototype, "exponent", { + get: function get() { + return this.e; + }, + set: function set(value) { + this.e = value; + }, + enumerable: true, + configurable: true + }); + + Decimal.fromComponents = function (sign, layer, mag) { + return new Decimal().fromComponents(sign, layer, mag); + }; + + Decimal.fromComponents_noNormalize = function (sign, layer, mag) { + return new Decimal().fromComponents_noNormalize(sign, layer, mag); + }; + + Decimal.fromMantissaExponent = function (mantissa, exponent) { + return new Decimal().fromMantissaExponent(mantissa, exponent); + }; + + Decimal.fromMantissaExponent_noNormalize = function (mantissa, exponent) { + return new Decimal().fromMantissaExponent_noNormalize(mantissa, exponent); + }; + + Decimal.fromDecimal = function (value) { + return new Decimal().fromDecimal(value); + }; + + Decimal.fromNumber = function (value) { + return new Decimal().fromNumber(value); + }; + + Decimal.fromString = function (value) { + return new Decimal().fromString(value); + }; + + Decimal.fromValue = function (value) { + return new Decimal().fromValue(value); + }; + + Decimal.fromValue_noAlloc = function (value) { + return value instanceof Decimal ? value : new Decimal(value); + }; + + Decimal.abs = function (value) { + return D(value).abs(); + }; + + Decimal.neg = function (value) { + return D(value).neg(); + }; + + Decimal.negate = function (value) { + return D(value).neg(); + }; + + Decimal.negated = function (value) { + return D(value).neg(); + }; + + Decimal.sign = function (value) { + return D(value).sign(); + }; + + Decimal.sgn = function (value) { + return D(value).sign(); + }; + + Decimal.round = function (value) { + return D(value).round(); + }; + + Decimal.floor = function (value) { + return D(value).floor(); + }; + + Decimal.ceil = function (value) { + return D(value).ceil(); + }; + + Decimal.trunc = function (value) { + return D(value).trunc(); + }; + + Decimal.add = function (value, other) { + return D(value).add(other); + }; + + Decimal.plus = function (value, other) { + return D(value).add(other); + }; + + Decimal.sub = function (value, other) { + return D(value).sub(other); + }; + + Decimal.subtract = function (value, other) { + return D(value).sub(other); + }; + + Decimal.minus = function (value, other) { + return D(value).sub(other); + }; + + Decimal.mul = function (value, other) { + return D(value).mul(other); + }; + + Decimal.multiply = function (value, other) { + return D(value).mul(other); + }; + + Decimal.times = function (value, other) { + return D(value).mul(other); + }; + + Decimal.div = function (value, other) { + return D(value).div(other); + }; + + Decimal.divide = function (value, other) { + return D(value).div(other); + }; + + Decimal.recip = function (value) { + return D(value).recip(); + }; + + Decimal.reciprocal = function (value) { + return D(value).recip(); + }; + + Decimal.reciprocate = function (value) { + return D(value).reciprocate(); + }; + + Decimal.cmp = function (value, other) { + return D(value).cmp(other); + }; + + Decimal.cmpabs = function (value, other) { + return D(value).cmpabs(other); + }; + + Decimal.compare = function (value, other) { + return D(value).cmp(other); + }; + + Decimal.eq = function (value, other) { + return D(value).eq(other); + }; + + Decimal.equals = function (value, other) { + return D(value).eq(other); + }; + + Decimal.neq = function (value, other) { + return D(value).neq(other); + }; + + Decimal.notEquals = function (value, other) { + return D(value).notEquals(other); + }; + + Decimal.lt = function (value, other) { + return D(value).lt(other); + }; + + Decimal.lte = function (value, other) { + return D(value).lte(other); + }; + + Decimal.gt = function (value, other) { + return D(value).gt(other); + }; + + Decimal.gte = function (value, other) { + return D(value).gte(other); + }; + + Decimal.max = function (value, other) { + return D(value).max(other); + }; + + Decimal.min = function (value, other) { + return D(value).min(other); + }; + + Decimal.minabs = function (value, other) { + return D(value).minabs(other); + }; + + Decimal.maxabs = function (value, other) { + return D(value).maxabs(other); + }; + + Decimal.clamp = function(value, min, max) { + return D(value).clamp(min, max); + } + + Decimal.clampMin = function(value, min) { + return D(value).clampMin(min); + } + + Decimal.clampMax = function(value, max) { + return D(value).clampMax(max); + } + + Decimal.cmp_tolerance = function (value, other, tolerance) { + return D(value).cmp_tolerance(other, tolerance); + }; + + Decimal.compare_tolerance = function (value, other, tolerance) { + return D(value).cmp_tolerance(other, tolerance); + }; + + Decimal.eq_tolerance = function (value, other, tolerance) { + return D(value).eq_tolerance(other, tolerance); + }; + + Decimal.equals_tolerance = function (value, other, tolerance) { + return D(value).eq_tolerance(other, tolerance); + }; + + Decimal.neq_tolerance = function (value, other, tolerance) { + return D(value).neq_tolerance(other, tolerance); + }; + + Decimal.notEquals_tolerance = function (value, other, tolerance) { + return D(value).notEquals_tolerance(other, tolerance); + }; + + Decimal.lt_tolerance = function (value, other, tolerance) { + return D(value).lt_tolerance(other, tolerance); + }; + + Decimal.lte_tolerance = function (value, other, tolerance) { + return D(value).lte_tolerance(other, tolerance); + }; + + Decimal.gt_tolerance = function (value, other, tolerance) { + return D(value).gt_tolerance(other, tolerance); + }; + + Decimal.gte_tolerance = function (value, other, tolerance) { + return D(value).gte_tolerance(other, tolerance); + }; + + Decimal.pLog10 = function (value) { + return D(value).pLog10(); + }; + + Decimal.absLog10 = function (value) { + return D(value).absLog10(); + }; + + Decimal.log10 = function (value) { + return D(value).log10(); + }; + + Decimal.log = function (value, base) { + return D(value).log(base); + }; + + Decimal.log2 = function (value) { + return D(value).log2(); + }; + + Decimal.ln = function (value) { + return D(value).ln(); + }; + + Decimal.logarithm = function (value, base) { + return D(value).logarithm(base); + }; + + Decimal.pow = function (value, other) { + return D(value).pow(other); + }; + + Decimal.pow10 = function (value) { + return D(value).pow10(); + }; + + Decimal.root = function (value, other) { + return D(value).root(other); + }; + + Decimal.factorial = function (value, other) { + return D(value).factorial(); + }; + + Decimal.gamma = function (value, other) { + return D(value).gamma(); + }; + + Decimal.lngamma = function (value, other) { + return D(value).lngamma(); + }; + + Decimal.exp = function (value) { + return D(value).exp(); + }; + + Decimal.sqr = function (value) { + return D(value).sqr(); + }; + + Decimal.sqrt = function (value) { + return D(value).sqrt(); + }; + + Decimal.cube = function (value) { + return D(value).cube(); + }; + + Decimal.cbrt = function (value) { + return D(value).cbrt(); + }; + + Decimal.tetrate = function (value, height = 2, payload = FC_NN(1, 0, 1)) { + return D(value).tetrate(height, payload); + } + + Decimal.iteratedexp = function (value, height = 2, payload = FC_NN(1, 0, 1)) { + return D(value).iteratedexp(height, payload); + } + + Decimal.iteratedlog = function (value, base = 10, times = 1) { + return D(value).iteratedlog(base, times); + } + + Decimal.layeradd10 = function (value, diff) { + return D(value).layeradd10(diff); + } + + Decimal.layeradd = function (value, diff, base = 10) { + return D(value).layeradd(diff, base); + } + + Decimal.slog = function (value, base = 10) { + return D(value).slog(base); + } + + Decimal.lambertw = function(value) { + return D(value).lambertw(); + } + + Decimal.ssqrt = function(value) { + return D(value).ssqrt(); + } + + Decimal.pentate = function (value, height = 2, payload = FC_NN(1, 0, 1)) { + return D(value).pentate(height, payload); + } + + /** + * If you're willing to spend 'resourcesAvailable' and want to buy something + * with exponentially increasing cost each purchase (start at priceStart, + * multiply by priceRatio, already own currentOwned), how much of it can you buy? + * Adapted from Trimps source code. + */ + + + Decimal.affordGeometricSeries = function (resourcesAvailable, priceStart, priceRatio, currentOwned) { + return this.affordGeometricSeries_core(D(resourcesAvailable), D(priceStart), D(priceRatio), currentOwned); + }; + /** + * How much resource would it cost to buy (numItems) items if you already have currentOwned, + * the initial price is priceStart and it multiplies by priceRatio each purchase? + */ + + + Decimal.sumGeometricSeries = function (numItems, priceStart, priceRatio, currentOwned) { + return this.sumGeometricSeries_core(numItems, D(priceStart), D(priceRatio), currentOwned); + }; + /** + * If you're willing to spend 'resourcesAvailable' and want to buy something with additively + * increasing cost each purchase (start at priceStart, add by priceAdd, already own currentOwned), + * how much of it can you buy? + */ + + + Decimal.affordArithmeticSeries = function (resourcesAvailable, priceStart, priceAdd, currentOwned) { + return this.affordArithmeticSeries_core(D(resourcesAvailable), D(priceStart), D(priceAdd), D(currentOwned)); + }; + /** + * How much resource would it cost to buy (numItems) items if you already have currentOwned, + * the initial price is priceStart and it adds priceAdd each purchase? + * Adapted from http://www.mathwords.com/a/arithmetic_series.htm + */ + + + Decimal.sumArithmeticSeries = function (numItems, priceStart, priceAdd, currentOwned) { + return this.sumArithmeticSeries_core(D(numItems), D(priceStart), D(priceAdd), D(currentOwned)); + }; + /** + * When comparing two purchases that cost (resource) and increase your resource/sec by (deltaRpS), + * the lowest efficiency score is the better one to purchase. + * From Frozen Cookies: + * http://cookieclicker.wikia.com/wiki/Frozen_Cookies_(JavaScript_Add-on)#Efficiency.3F_What.27s_that.3F + */ + + + Decimal.efficiencyOfPurchase = function (cost, currentRpS, deltaRpS) { + return this.efficiencyOfPurchase_core(D(cost), D(currentRpS), D(deltaRpS)); + }; + + Decimal.randomDecimalForTesting = function (maxLayers) { + // NOTE: This doesn't follow any kind of sane random distribution, so use this for testing purposes only. + //5% of the time, return 0 + if (Math.random() * 20 < 1) { + return FC_NN(0, 0, 0); + } + + var randomsign = Math.random() > 0.5 ? 1 : -1; + + //5% of the time, return 1 or -1 + if (Math.random() * 20 < 1) { + return FC_NN(randomsign, 0, 1); + } + + //pick a random layer + var layer = Math.floor(Math.random()*(maxLayers+1)); + + var randomexp = layer === 0 ? Math.random()*616-308 : Math.random()*16; + //10% of the time, make it a simple power of 10 + if (Math.random() > 0.9) { randomexp = Math.trunc(randomexp); } + var randommag = Math.pow(10, randomexp); + //10% of the time, trunc mag + if (Math.random() > 0.9) { randommag = Math.trunc(randommag); } + return FC(randomsign, layer, randommag); + }; + + Decimal.affordGeometricSeries_core = function (resourcesAvailable, priceStart, priceRatio, currentOwned) { + var actualStart = priceStart.mul(priceRatio.pow(currentOwned)); + return Decimal.floor(resourcesAvailable.div(actualStart).mul(priceRatio.sub(1)).add(1).log10().div(priceRatio.log10())); + }; + + Decimal.sumGeometricSeries_core = function (numItems, priceStart, priceRatio, currentOwned) { + return priceStart.mul(priceRatio.pow(currentOwned)).mul(Decimal.sub(1, priceRatio.pow(numItems))).div(Decimal.sub(1, priceRatio)); + }; + + Decimal.affordArithmeticSeries_core = function (resourcesAvailable, priceStart, priceAdd, currentOwned) { + // n = (-(a-d/2) + sqrt((a-d/2)^2+2dS))/d + // where a is actualStart, d is priceAdd and S is resourcesAvailable + // then floor it and you're done! + 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(); + }; + + Decimal.sumArithmeticSeries_core = function (numItems, priceStart, priceAdd, currentOwned) { + var actualStart = priceStart.add(currentOwned.mul(priceAdd)); // (n/2)*(2*a+(n-1)*d) + + return numItems.div(2).mul(actualStart.mul(2).plus(numItems.sub(1).mul(priceAdd))); + }; + + Decimal.efficiencyOfPurchase_core = function (cost, currentRpS, deltaRpS) { + return cost.div(currentRpS).add(cost.div(deltaRpS)); + }; + + Decimal.prototype.normalize = function () { + /* + PSEUDOCODE: + Whenever we are partially 0 (sign is 0 or mag and layer is 0), make it fully 0. + Whenever we are at or hit layer 0, extract sign from negative mag. + If layer === 0 and mag < FIRST_NEG_LAYER (1/9e15), shift to 'first negative layer' (add layer, log10 mag). + While abs(mag) > EXP_LIMIT (9e15), layer += 1, mag = maglog10(mag). + While abs(mag) < LAYER_DOWN (15.954) and layer > 0, layer -= 1, mag = pow(10, mag). + + When we're done, all of the following should be true OR one of the numbers is not IsFinite OR layer is not IsInteger (error state): + Any 0 is totally zero (0, 0, 0). + Anything layer 0 has mag 0 OR mag > 1/9e15 and < 9e15. + Anything layer 1 or higher has abs(mag) >= 15.954 and < 9e15. + We will assume in calculations that all Decimals are either erroneous or satisfy these criteria. (Otherwise: Garbage in, garbage out.) + */ + if (this.sign === 0 || (this.mag === 0 && this.layer === 0)) + { + this.sign = 0; + this.mag = 0; + this.layer = 0; + return this; + } + + if (this.layer === 0 && this.mag < 0) + { + //extract sign from negative mag at layer 0 + this.mag = -this.mag; + this.sign = -this.sign; + } + + //Handle shifting from layer 0 to negative layers. + if (this.layer === 0 && this.mag < FIRST_NEG_LAYER) + { + this.layer += 1; + this.mag = Math.log10(this.mag); + return this; + } + + var absmag = Math.abs(this.mag); + var signmag = Math.sign(this.mag); + + if (absmag >= EXP_LIMIT) + { + this.layer += 1; + this.mag = signmag*Math.log10(absmag); + return this; + } + else + { + while (absmag < LAYER_DOWN && this.layer > 0) + { + this.layer -= 1; + if (this.layer === 0) + { + this.mag = Math.pow(10, this.mag); + } + else + { + this.mag = signmag*Math.pow(10, absmag); + absmag = Math.abs(this.mag); + signmag = Math.sign(this.mag); + } + } + if (this.layer === 0) + { + if (this.mag < 0) + { + //extract sign from negative mag at layer 0 + this.mag = -this.mag; + this.sign = -this.sign; + } + else if (this.mag === 0) + { + //excessive rounding can give us all zeroes + this.sign = 0; + } + } + } + + return this; + }; + + Decimal.prototype.fromComponents = function (sign, layer, mag) { + this.sign = sign; + this.layer = layer; + this.mag = mag; + + this.normalize(); + return this; + }; + + Decimal.prototype.fromComponents_noNormalize = function (sign, layer, mag) { + this.sign = sign; + this.layer = layer; + this.mag = mag; + return this; + }; + + Decimal.prototype.fromMantissaExponent = function (mantissa, exponent) { + this.layer = 1; + this.sign = Math.sign(mantissa); + mantissa = Math.abs(mantissa); + this.mag = exponent + Math.log10(mantissa); + + this.normalize(); + return this; + }; + + + Decimal.prototype.fromMantissaExponent_noNormalize = function (mantissa, exponent) { + //The idea of 'normalizing' a break_infinity.js style Decimal doesn't really apply. So just do the same thing. + this.fromMantissaExponent(mantissa, exponent); + return this; + }; + + Decimal.prototype.fromDecimal = function (value) { + this.sign = value.sign; + this.layer = value.layer; + this.mag = value.mag; + return this; + }; + + Decimal.prototype.fromNumber = function (value) { + this.mag = Math.abs(value); + this.sign = Math.sign(value); + this.layer = 0; + this.normalize(); + return this; + }; + + var IGNORE_COMMAS = true; + var COMMAS_ARE_DECIMAL_POINTS = false; + + Decimal.prototype.fromString = function (value) { + if (IGNORE_COMMAS) { value = value.replace(",", ""); } + else if (COMMAS_ARE_DECIMAL_POINTS) { value = value.replace(",", "."); } + + //Handle x^^^y format. + var pentationparts = value.split("^^^"); + if (pentationparts.length === 2) + { + var base = parseFloat(pentationparts[0]); + var height = parseFloat(pentationparts[1]); + var payload = 1; + var heightparts = pentationparts[1].split(";"); + if (heightparts.length === 2) + { + var payload = parseFloat(heightparts[1]); + if (!isFinite(payload)) { payload = 1; } + } + if (isFinite(base) && isFinite(height)) + { + var result = Decimal.pentate(base, height, payload); + this.sign = result.sign; + this.layer = result.layer; + this.mag = result.mag; + return this; + } + } + + //Handle x^^y format. + var tetrationparts = value.split("^^"); + if (tetrationparts.length === 2) + { + var base = parseFloat(tetrationparts[0]); + var height = parseFloat(tetrationparts[1]); + var heightparts = tetrationparts[1].split(";"); + if (heightparts.length === 2) + { + var payload = parseFloat(heightparts[1]); + if (!isFinite(payload)) { payload = 1; } + } + if (isFinite(base) && isFinite(height)) + { + var result = Decimal.tetrate(base, height, payload); + this.sign = result.sign; + this.layer = result.layer; + this.mag = result.mag; + return this; + } + } + + //Handle x^y format. + var powparts = value.split("^"); + if (powparts.length === 2) + { + var base = parseFloat(powparts[0]); + var exponent = parseFloat(powparts[1]); + if (isFinite(base) && isFinite(exponent)) + { + var result = Decimal.pow(base, exponent); + this.sign = result.sign; + this.layer = result.layer; + this.mag = result.mag; + return this; + } + } + + //Handle various cases involving it being a Big Number. + value = value.trim().toLowerCase(); + + //handle X PT Y format. + var ptparts = value.split("pt"); + if (ptparts.length === 2) + { + base = 10; + height = parseFloat(ptparts[0]); + ptparts[1] = ptparts[1].replace("(", ""); + ptparts[1] = ptparts[1].replace(")", ""); + var payload = parseFloat(ptparts[1]); + if (!isFinite(payload)) { payload = 1; } + if (isFinite(base) && isFinite(height)) + { + var result = Decimal.tetrate(base, height, payload); + this.sign = result.sign; + this.layer = result.layer; + this.mag = result.mag; + return this; + } + } + + //handle XpY format (it's the same thing just with p). + var ptparts = value.split("p"); + if (ptparts.length === 2) + { + base = 10; + height = parseFloat(ptparts[0]); + ptparts[1] = ptparts[1].replace("(", ""); + ptparts[1] = ptparts[1].replace(")", ""); + var payload = parseFloat(ptparts[1]); + if (!isFinite(payload)) { payload = 1; } + if (isFinite(base) && isFinite(height)) + { + var result = Decimal.tetrate(base, height, payload); + this.sign = result.sign; + this.layer = result.layer; + this.mag = result.mag; + return this; + } + } + + var parts = value.split("e"); + var ecount = parts.length-1; + + //Handle numbers that are exactly floats (0 or 1 es). + if (ecount === 0) + { + var numberAttempt = parseFloat(value); + if (isFinite(numberAttempt)) + { + return this.fromNumber(numberAttempt); + } + } + else if (ecount === 1) + { + //Very small numbers ("2e-3000" and so on) may look like valid floats but round to 0. + var numberAttempt = parseFloat(value); + if (isFinite(numberAttempt) && numberAttempt !== 0) + { + return this.fromNumber(numberAttempt); + } + } + + //Handle new (e^N)X format. + var newparts = value.split("e^"); + if (newparts.length === 2) + { + this.sign = 1; + if (newparts[0].charAt(0) == "-") + { + this.sign = -1; + } + var layerstring = ""; + for (var i = 0; i < newparts[1].length; ++i) + { + var chrcode = newparts[1].charCodeAt(i); + if ((chrcode >= 43 && chrcode <= 57) || chrcode === 101) //is "0" to "9" or "+" or "-" or "." or "e" (or "," or "/") + { + layerstring += newparts[1].charAt(i); + } + else //we found the end of the layer count + { + this.layer = parseFloat(layerstring); + this.mag = parseFloat(newparts[1].substr(i+1)); + this.normalize(); + return this; + } + } + } + + if (ecount < 1) { this.sign = 0; this.layer = 0; this.mag = 0; return this; } + var mantissa = parseFloat(parts[0]); + if (mantissa === 0) { this.sign = 0; this.layer = 0; this.mag = 0; return this; } + var exponent = parseFloat(parts[parts.length-1]); + //handle numbers like AeBeC and AeeeeBeC + if (ecount >= 2) + { + var me = parseFloat(parts[parts.length-2]); + if (isFinite(me)) + { + exponent *= Math.sign(me); + exponent += f_maglog10(me); + } + } + + //Handle numbers written like eee... (N es) X + if (!isFinite(mantissa)) + { + this.sign = (parts[0] === "-") ? -1 : 1; + this.layer = ecount; + this.mag = exponent; + } + //Handle numbers written like XeY + else if (ecount === 1) + { + this.sign = Math.sign(mantissa); + this.layer = 1; + //Example: 2e10 is equal to 10^log10(2e10) which is equal to 10^(10+log10(2)) + this.mag = exponent + Math.log10(Math.abs(mantissa)); + } + //Handle numbers written like Xeee... (N es) Y + else + { + this.sign = Math.sign(mantissa); + this.layer = ecount; + if (ecount === 2) + { + var result = Decimal.mul(FC(1, 2, exponent), D(mantissa)); + this.sign = result.sign; + this.layer = result.layer; + this.mag = result.mag; + return this; + } + else + { + //at eee and above, mantissa is too small to be recognizable! + this.mag = exponent; + } + } + + this.normalize(); + return this; + }; + + Decimal.prototype.fromValue = function (value) { + if (value instanceof Decimal) { + return this.fromDecimal(value); + } + + if (typeof value === "number") { + return this.fromNumber(value); + } + + if (typeof value === "string") { + return this.fromString(value); + } + + this.sign = 0; + this.layer = 0; + this.mag = 0; + return this; + }; + + Decimal.prototype.toNumber = function () { + if (!Number.isFinite(this.layer)) { return Number.NaN; } + if (this.layer === 0) + { + return this.sign*this.mag; + } + else if (this.layer === 1) + { + return this.sign*Math.pow(10, this.mag); + } + else //overflow for any normalized Decimal + { + return this.mag > 0 ? (this.sign > 0 ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY) : 0; + } + }; + + Decimal.prototype.mantissaWithDecimalPlaces = function (places) { + // https://stackoverflow.com/a/37425022 + if (isNaN(this.m)) { + return Number.NaN; + } + + if (this.m === 0) { + return 0; + } + + return decimalPlaces(this.m, places); + }; + + Decimal.prototype.magnitudeWithDecimalPlaces = function (places) { + // https://stackoverflow.com/a/37425022 + if (isNaN(this.mag)) { + return Number.NaN; + } + + if (this.mag === 0) { + return 0; + } + + return decimalPlaces(this.mag, places); + }; + + Decimal.prototype.toString = function () { + if (this.layer === 0) + { + if ((this.mag < 1e21 && this.mag > 1e-7) || this.mag === 0) + { + return (this.sign*this.mag).toString(); + } + return this.m + "e" + this.e; + } + else if (this.layer === 1) + { + return this.m + "e" + this.e; + } + else + { + //layer 2+ + if (this.layer <= MAX_ES_IN_A_ROW) + { + return (this.sign === -1 ? "-" : "") + "e".repeat(this.layer) + this.mag; + } + else + { + return (this.sign === -1 ? "-" : "") + "(e^" + this.layer + ")" + this.mag; + } + } + }; + + Decimal.prototype.toExponential = function (places) { + if (this.layer === 0) + { + return (this.sign*this.mag).toExponential(places); + } + return this.toStringWithDecimalPlaces(places); + }; + + Decimal.prototype.toFixed = function (places) { + if (this.layer === 0) + { + return (this.sign*this.mag).toFixed(places); + } + return this.toStringWithDecimalPlaces(places); + }; + + Decimal.prototype.toPrecision = function (places) { + if (this.e <= -7) { + return this.toExponential(places - 1); + } + + if (places > this.e) { + return this.toFixed(places - this.exponent - 1); + } + + return this.toExponential(places - 1); + }; + + Decimal.prototype.valueOf = function () { + return this.toString(); + }; + + Decimal.prototype.toJSON = function () { + return this.toString(); + }; + + Decimal.prototype.toStringWithDecimalPlaces = function (places) { + if (this.layer === 0) + { + if ((this.mag < 1e21 && this.mag > 1e-7) || this.mag === 0) + { + return (this.sign*this.mag).toFixed(places); + } + return decimalPlaces(this.m, places) + "e" + decimalPlaces(this.e, places); + } + else if (this.layer === 1) + { + return decimalPlaces(this.m, places) + "e" + decimalPlaces(this.e, places); + } + else + { + //layer 2+ + if (this.layer <= MAX_ES_IN_A_ROW) + { + return (this.sign === -1 ? "-" : "") + "e".repeat(this.layer) + decimalPlaces(this.mag, places); + } + else + { + return (this.sign === -1 ? "-" : "") + "(e^" + this.layer + ")" + decimalPlaces(this.mag, places); + } + } + }; + + Decimal.prototype.abs = function () { + return FC_NN(this.sign === 0 ? 0 : 1, this.layer, this.mag); + }; + + Decimal.prototype.neg = function () { + return FC_NN(-this.sign, this.layer, this.mag); + }; + + Decimal.prototype.negate = function () { + return this.neg(); + }; + + Decimal.prototype.negated = function () { + return this.neg(); + }; + + Decimal.prototype.sign = function () { + return this.sign; + }; + + Decimal.prototype.sgn = function () { + return this.sign; + }; + + Decimal.prototype.round = function () { + if (this.mag < 0) + { + return Decimal.dZero; + } + if (this.layer === 0) + { + return FC(this.sign, 0, Math.round(this.mag)); + } + return this; + }; + + Decimal.prototype.floor = function () { + if (this.mag < 0) + { + return Decimal.dZero; + } + if (this.layer === 0) + { + return FC(this.sign, 0, Math.floor(this.mag)); + } + return this; + }; + + Decimal.prototype.ceil = function () { + if (this.mag < 0) + { + return Decimal.dZero; + } + if (this.layer === 0) + { + return FC(this.sign, 0, Math.ceil(this.mag)); + } + return this; + }; + + Decimal.prototype.trunc = function () { + if (this.mag < 0) + { + return Decimal.dZero; + } + if (this.layer === 0) + { + return FC(this.sign, 0, Math.trunc(this.mag)); + } + return this; + }; + + Decimal.prototype.add = function (value) { + var decimal = D(value); + + //inf/nan check + if (!Number.isFinite(this.layer)) { return this; } + if (!Number.isFinite(decimal.layer)) { return decimal; } + + //Special case - if one of the numbers is 0, return the other number. + if (this.sign === 0) { return decimal; } + if (decimal.sign === 0) { return this; } + + //Special case - Adding a number to its negation produces 0, no matter how large. + if (this.sign === -(decimal.sign) && this.layer === decimal.layer && this.mag === decimal.mag) { return FC_NN(0, 0, 0); } + + var a; + var b; + + //Special case: If one of the numbers is layer 2 or higher, just take the bigger number. + if ((this.layer >= 2 || decimal.layer >= 2)) { return this.maxabs(decimal); } + + if (Decimal.cmpabs(this, decimal) > 0) + { + a = this; + b = decimal; + } + else + { + a = decimal; + b = this; + } + + if (a.layer === 0 && b.layer === 0) { return D(a.sign*a.mag + b.sign*b.mag); } + + var layera = a.layer*Math.sign(a.mag); + var layerb = b.layer*Math.sign(b.mag); + + //If one of the numbers is 2+ layers higher than the other, just take the bigger number. + if (layera - layerb >= 2) { return a; } + + if (layera === 0 && layerb === -1) + { + if (Math.abs(b.mag-Math.log10(a.mag)) > MAX_SIGNIFICANT_DIGITS) + { + return a; + } + else + { + var magdiff = Math.pow(10, Math.log10(a.mag)-b.mag); + var mantissa = (b.sign)+(a.sign*magdiff); + return FC(Math.sign(mantissa), 1, b.mag+Math.log10(Math.abs(mantissa))); + } + } + + if (layera === 1 && layerb === 0) + { + if (Math.abs(a.mag-Math.log10(b.mag)) > MAX_SIGNIFICANT_DIGITS) + { + return a; + } + else + { + var magdiff = Math.pow(10, a.mag-Math.log10(b.mag)); + var mantissa = (b.sign)+(a.sign*magdiff); + return FC(Math.sign(mantissa), 1, Math.log10(b.mag)+Math.log10(Math.abs(mantissa))); + } + } + + if (Math.abs(a.mag-b.mag) > MAX_SIGNIFICANT_DIGITS) + { + return a; + } + else + { + var magdiff = Math.pow(10, a.mag-b.mag); + var mantissa = (b.sign)+(a.sign*magdiff); + return FC(Math.sign(mantissa), 1, b.mag+Math.log10(Math.abs(mantissa))); + } + + throw Error("Bad arguments to add: " + this + ", " + value); + }; + + Decimal.prototype.plus = function (value) { + return this.add(value); + }; + + Decimal.prototype.sub = function (value) { + return this.add(D(value).neg()); + }; + + Decimal.prototype.subtract = function (value) { + return this.sub(value); + }; + + Decimal.prototype.minus = function (value) { + return this.sub(value); + }; + + Decimal.prototype.mul = function (value) { + var decimal = D(value); + + //inf/nan check + if (!Number.isFinite(this.layer)) { return this; } + if (!Number.isFinite(decimal.layer)) { return decimal; } + + //Special case - if one of the numbers is 0, return 0. + if (this.sign === 0 || decimal.sign === 0) { return FC_NN(0, 0, 0); } + + //Special case - Multiplying a number by its own reciprocal yields +/- 1, no matter how large. + if (this.layer === decimal.layer && this.mag === -decimal.mag) { return FC_NN(this.sign*decimal.sign, 0, 1); } + + var a; + var b; + + //Which number is bigger in terms of its multiplicative distance from 1? + if ((this.layer > decimal.layer) || (this.layer == decimal.layer && Math.abs(this.mag) > Math.abs(decimal.mag))) + { + a = this; + b = decimal; + } + else + { + a = decimal; + b = this; + } + + if (a.layer === 0 && b.layer === 0) { return D(a.sign*b.sign*a.mag*b.mag); } + + //Special case: If one of the numbers is layer 3 or higher or one of the numbers is 2+ layers bigger than the other, just take the bigger number. + if (a.layer >= 3 || (a.layer - b.layer >= 2)) { return FC(a.sign*b.sign, a.layer, a.mag); } + + if (a.layer === 1 && b.layer === 0) + { + return FC(a.sign*b.sign, 1, a.mag+Math.log10(b.mag)); + } + + if (a.layer === 1 && b.layer === 1) + { + return FC(a.sign*b.sign, 1, a.mag+b.mag); + } + + if (a.layer === 2 && b.layer === 1) + { + var newmag = FC(Math.sign(a.mag), a.layer-1, Math.abs(a.mag)).add(FC(Math.sign(b.mag), b.layer-1, Math.abs(b.mag))); + return FC(a.sign*b.sign, newmag.layer+1, newmag.sign*newmag.mag); + } + + if (a.layer === 2 && b.layer === 2) + { + var newmag = FC(Math.sign(a.mag), a.layer-1, Math.abs(a.mag)).add(FC(Math.sign(b.mag), b.layer-1, Math.abs(b.mag))); + return FC(a.sign*b.sign, newmag.layer+1, newmag.sign*newmag.mag); + } + + throw Error("Bad arguments to mul: " + this + ", " + value); + }; + + Decimal.prototype.multiply = function (value) { + return this.mul(value); + }; + + Decimal.prototype.times = function (value) { + return this.mul(value); + }; + + Decimal.prototype.div = function (value) { + var decimal = D(value); + return this.mul(decimal.recip()); + }; + + Decimal.prototype.divide = function (value) { + return this.div(value); + }; + + Decimal.prototype.divideBy = function (value) { + return this.div(value); + }; + + Decimal.prototype.dividedBy = function (value) { + return this.div(value); + }; + + Decimal.prototype.recip = function () { + if (this.mag === 0) + { + return Decimal.dNaN; + } + else if (this.layer === 0) + { + return FC(this.sign, 0, 1/this.mag); + } + else + { + return FC(this.sign, this.layer, -this.mag); + } + }; + + Decimal.prototype.reciprocal = function () { + return this.recip(); + }; + + Decimal.prototype.reciprocate = function () { + return this.recip(); + }; + + /** + * -1 for less than value, 0 for equals value, 1 for greater than value + */ + Decimal.prototype.cmp = function (value) { + var decimal = D(value); + if (this.sign > decimal.sign) { return 1; } + if (this.sign < decimal.sign) { return -1; } + return this.sign*this.cmpabs(value); + }; + + Decimal.prototype.cmpabs = function (value) { + var decimal = D(value); + var layera = this.mag > 0 ? this.layer : -this.layer; + var layerb = decimal.mag > 0 ? decimal.layer : -decimal.layer; + if (layera > layerb) { return 1; } + if (layera < layerb) { return -1; } + if (this.mag > decimal.mag) { return 1; } + if (this.mag < decimal.mag) { return -1; } + return 0; + }; + + Decimal.prototype.compare = function (value) { + return this.cmp(value); + }; + + Decimal.prototype.eq = function (value) { + var decimal = D(value); + return this.sign === decimal.sign && this.layer === decimal.layer && this.mag === decimal.mag; + }; + + Decimal.prototype.equals = function (value) { + return this.eq(value); + }; + + Decimal.prototype.neq = function (value) { + return !this.eq(value); + }; + + Decimal.prototype.notEquals = function (value) { + return this.neq(value); + }; + + Decimal.prototype.lt = function (value) { + var decimal = D(value); + return this.cmp(value) === -1; + }; + + Decimal.prototype.lte = function (value) { + return !this.gt(value); + }; + + Decimal.prototype.gt = function (value) { + var decimal = D(value); + return this.cmp(value) === 1; + }; + + Decimal.prototype.gte = function (value) { + return !this.lt(value); + }; + + Decimal.prototype.max = function (value) { + var decimal = D(value); + return this.lt(decimal) ? decimal : this; + }; + + Decimal.prototype.min = function (value) { + var decimal = D(value); + return this.gt(decimal) ? decimal : this; + }; + + Decimal.prototype.maxabs = function (value) { + var decimal = D(value); + return this.cmpabs(decimal) < 0 ? decimal : this; + }; + + Decimal.prototype.minabs = function (value) { + var decimal = D(value); + return this.cmpabs(decimal) > 0 ? decimal : this; + }; + + Decimal.prototype.clamp = function(min, max) { + return this.max(min).min(max); + } + + Decimal.prototype.clampMin = function(min) { + return this.max(min); + } + + Decimal.prototype.clampMax = function(max) { + return this.min(max); + } + + Decimal.prototype.cmp_tolerance = function (value, tolerance) { + var decimal = D(value); + return this.eq_tolerance(decimal, tolerance) ? 0 : this.cmp(decimal); + }; + + Decimal.prototype.compare_tolerance = function (value, tolerance) { + return this.cmp_tolerance(value, tolerance); + }; + + /** + * Tolerance is a relative tolerance, multiplied by the greater of the magnitudes of the two arguments. + * For example, if you put in 1e-9, then any number closer to the + * larger number than (larger number)*1e-9 will be considered equal. + */ + Decimal.prototype.eq_tolerance = function (value, tolerance) { + var decimal = D(value); // https://stackoverflow.com/a/33024979 + if (tolerance == null) { tolerance = 1e-7; } + //Numbers that are too far away are never close. + if (this.sign !== decimal.sign) { return false; } + if (Math.abs(this.layer - decimal.layer) > 1) { return false; } + // return abs(a-b) <= tolerance * max(abs(a), abs(b)) + var magA = this.mag; + var magB = decimal.mag; + if (this.layer > decimal.layer) { magB = f_maglog10(magB); } + if (this.layer < decimal.layer) { magA = f_maglog10(magA); } + return Math.abs(magA-magB) <= tolerance*Math.max(Math.abs(magA), Math.abs(magB)); + }; + + Decimal.prototype.equals_tolerance = function (value, tolerance) { + return this.eq_tolerance(value, tolerance); + }; + + Decimal.prototype.neq_tolerance = function (value, tolerance) { + return !this.eq_tolerance(value, tolerance); + }; + + Decimal.prototype.notEquals_tolerance = function (value, tolerance) { + return this.neq_tolerance(value, tolerance); + }; + + Decimal.prototype.lt_tolerance = function (value, tolerance) { + var decimal = D(value); + return !this.eq_tolerance(decimal, tolerance) && this.lt(decimal); + }; + + Decimal.prototype.lte_tolerance = function (value, tolerance) { + var decimal = D(value); + return this.eq_tolerance(decimal, tolerance) || this.lt(decimal); + }; + + Decimal.prototype.gt_tolerance = function (value, tolerance) { + var decimal = D(value); + return !this.eq_tolerance(decimal, tolerance) && this.gt(decimal); + }; + + Decimal.prototype.gte_tolerance = function (value, tolerance) { + var decimal = D(value); + return this.eq_tolerance(decimal, tolerance) || this.gt(decimal); + }; + + Decimal.prototype.pLog10 = function() { + if (this.lt(Decimal.dZero)) { return Decimal.dZero; } + return this.log10(); + } + + Decimal.prototype.absLog10 = function () { + if (this.sign === 0) + { + return Decimal.dNaN; + } + else if (this.layer > 0) + { + return FC(Math.sign(this.mag), this.layer-1, Math.abs(this.mag)); + } + else + { + return FC(1, 0, Math.log10(this.mag)); + } + }; + + Decimal.prototype.log10 = function () { + if (this.sign <= 0) + { + return Decimal.dNaN; + } + else if (this.layer > 0) + { + return FC(Math.sign(this.mag), this.layer-1, Math.abs(this.mag)); + } + else + { + return FC(this.sign, 0, Math.log10(this.mag)); + } + }; + + Decimal.prototype.log = function (base) { + base = D(base); + if (this.sign <= 0) + { + return Decimal.dNaN; + } + if (base.sign <= 0) + { + return Decimal.dNaN; + } + if (base.sign === 1 && base.layer === 0 && base.mag === 1) + { + return Decimal.dNaN; + } + else if (this.layer === 0 && base.layer === 0) + { + return FC(this.sign, 0, Math.log(this.mag)/Math.log(base.mag)); + } + + return Decimal.div(this.log10(), base.log10()); + }; + + Decimal.prototype.log2 = function () { + if (this.sign <= 0) + { + return Decimal.dNaN; + } + else if (this.layer === 0) + { + return FC(this.sign, 0, Math.log2(this.mag)); + } + else if (this.layer === 1) + { + return FC(Math.sign(this.mag), 0, Math.abs(this.mag)*3.321928094887362); //log2(10) + } + else if (this.layer === 2) + { + return FC(Math.sign(this.mag), 1, Math.abs(this.mag)+0.5213902276543247); //-log10(log10(2)) + } + else + { + return FC(Math.sign(this.mag), this.layer-1, Math.abs(this.mag)); + } + }; + + Decimal.prototype.ln = function () { + if (this.sign <= 0) + { + return Decimal.dNaN; + } + else if (this.layer === 0) + { + return FC(this.sign, 0, Math.log(this.mag)); + } + else if (this.layer === 1) + { + return FC(Math.sign(this.mag), 0, Math.abs(this.mag)*2.302585092994046); //ln(10) + } + else if (this.layer === 2) + { + return FC(Math.sign(this.mag), 1, Math.abs(this.mag)+0.36221568869946325); //log10(log10(e)) + } + else + { + return FC(Math.sign(this.mag), this.layer-1, Math.abs(this.mag)); + } + }; + + Decimal.prototype.logarithm = function (base) { + return this.log(base); + }; + + Decimal.prototype.pow = function (value) { + var decimal = D(value); + var a = this; + var b = decimal; + + //special case: if a is 0, then return 0 + if (a.sign === 0) { return a; } + //special case: if a is 1, then return 1 + if (a.sign === 1 && a.layer === 0 && a.mag === 1) { return a; } + //special case: if b is 0, then return 1 + if (b.sign === 0) { return FC_NN(1, 0, 1); } + //special case: if b is 1, then return a + if (b.sign === 1 && b.layer === 0 && b.mag === 1) { return a; } + + var result = (a.absLog10().mul(b)).pow10(); + + if (this.sign === -1 && b.toNumber() % 2 === 1) { + return result.neg(); + } + + return result; + }; + + Decimal.prototype.pow10 = function() { + /* + There are four cases we need to consider: + 1) positive sign, positive mag (e15, ee15): +1 layer (e.g. 10^15 becomes e15, 10^e15 becomes ee15) + 2) negative sign, positive mag (-e15, -ee15): +1 layer but sign and mag sign are flipped (e.g. 10^-15 becomes e-15, 10^-e15 becomes ee-15) + 3) positive sign, negative mag (e-15, ee-15): layer 0 case would have been handled in the Math.pow check, so just return 1 + 4) negative sign, negative mag (-e-15, -ee-15): layer 0 case would have been handled in the Math.pow check, so just return 1 + */ + + if (!Number.isFinite(this.layer) || !Number.isFinite(this.mag)) { return Decimal.dNaN; } + + var a = this; + + //handle layer 0 case - if no precision is lost just use Math.pow, else promote one layer + if (a.layer === 0) + { + var newmag = Math.pow(10, a.sign*a.mag); + if (Number.isFinite(newmag) && Math.abs(newmag) > 0.1) { return FC(1, 0, newmag); } + else + { + if (a.sign === 0) { return Decimal.dOne; } + else { a = FC_NN(a.sign, a.layer+1, Math.log10(a.mag)); } + } + } + + //handle all 4 layer 1+ cases individually + if (a.sign > 0 && a.mag > 0) + { + return FC(a.sign, a.layer+1, a.mag); + } + if (a.sign < 0 && a.mag > 0) + { + return FC(-a.sign, a.layer+1, -a.mag); + } + //both the negative mag cases are identical: one +/- rounding error + return Decimal.dOne; + } + + Decimal.prototype.pow_base = function (value) { + return D(value).pow(this); + }; + + Decimal.prototype.root = function (value) { + var decimal = D(value); + return this.pow(decimal.recip()); + } + + Decimal.prototype.factorial = function () { + if (this.mag < 0) + { + return this.toNumber().add(1).gamma(); + } + else if (this.layer === 0) + { + return this.add(1).gamma(); + } + else if (this.layer === 1) + { + return Decimal.exp(Decimal.mul(this, Decimal.ln(this).sub(1))); + } + else + { + return Decimal.exp(this); + } + }; + + //from HyperCalc source code + Decimal.prototype.gamma = function () { + if (this.mag < 0) + { + return this.recip(); + } + else if (this.layer === 0) + { + if (this.lt(FC_NN(1, 0, 24))) + { + return D(f_gamma(this.sign*this.mag)); + } + + var t = this.mag - 1; + var l = 0.9189385332046727; //0.5*Math.log(2*Math.PI) + l = (l+((t+0.5)*Math.log(t))); + l = 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 Decimal.exp(l); + } + + l = l2; + np = np*n2; + lm = 360*np; + adj = 1/lm; + l2 = l-adj; + if (l2 === l) + { + return Decimal.exp(l); + } + + l = l2; + np = np*n2; + lm = 1260*np; + var lt = 1/lm; + l = l+lt; + np = np*n2; + lm = 1680*np; + lt = 1/lm; + l = l-lt; + return Decimal.exp(l); + } + else if (this.layer === 1) + { + return Decimal.exp(Decimal.mul(this, Decimal.ln(this).sub(1))); + } + else + { + return Decimal.exp(this); + } + }; + + Decimal.prototype.lngamma = function () { + return this.gamma().ln(); + } + + Decimal.prototype.exp = function () { + if (this.mag < 0) { return Decimal.dOne; } + if (this.layer === 0 && this.mag <= 709.7) { return D(Math.exp(this.sign*this.mag)); } + else if (this.layer === 0) { return FC(1, 1, this.sign*Math.log10(Math.E)*this.mag); } + else if (this.layer === 1) { return FC(1, 2, this.sign*(Math.log10(0.4342944819032518)+this.mag)); } + else { return FC(1, this.layer+1, this.sign*this.mag); } + }; + + Decimal.prototype.sqr = function () { + return this.pow(2); + }; + + Decimal.prototype.sqrt = function () { + if (this.layer === 0) { return D(Math.sqrt(this.sign*this.mag)); } + else if (this.layer === 1) { return FC(1, 2, Math.log10(this.mag)-0.3010299956639812); } + else + { + var result = Decimal.div(FC_NN(this.sign, this.layer-1, this.mag), FC_NN(1, 0, 2)); + result.layer += 1; + result.normalize(); + return result; + } + }; + + Decimal.prototype.cube = function () { + return this.pow(3); + }; + + Decimal.prototype.cbrt = function () { + return this.pow(1/3); + }; + + //Tetration/tetrate: The result of exponentiating 'this' to 'this' 'height' times in a row. https://en.wikipedia.org/wiki/Tetration + //If payload != 1, then this is 'iterated exponentiation', the result of exping (payload) to base (this) (height) times. https://andydude.github.io/tetration/archives/tetration2/ident.html + //Works with negative and positive real heights. + Decimal.prototype.tetrate = function(height = 2, payload = FC_NN(1, 0, 1)) { + if (height === Number.POSITIVE_INFINITY) + { + //Formula for infinite height power tower. + var negln = Decimal.ln(this).neg(); + return negln.lambertw().div(negln); + } + + if (height < 0) + { + return Decimal.iteratedlog(payload, this, -height); + } + + payload = D(payload); + var oldheight = height; + height = Math.trunc(height); + var fracheight = oldheight-height; + + if (fracheight !== 0) + { + if (payload.eq(Decimal.dOne)) + { + ++height; + payload = new Decimal(fracheight); + } + else + { + if (this.eq(10)) + { + payload = payload.layeradd10(fracheight); + } + else + { + payload = payload.layeradd(fracheight, this); + } + } + } + + for (var i = 0; i < height; ++i) + { + payload = this.pow(payload); + //bail if we're NaN + if (!isFinite(payload.layer) || !isFinite(payload.mag)) { return payload; } + //shortcut + if (payload.layer - this.layer > 3) { return FC_NN(payload.sign, payload.layer + (height - i - 1), payload.mag); } + //give up after 100 iterations if nothing is happening + if (i > 100) { return payload; } + } + return payload; + } + + //iteratedexp/iterated exponentiation: - all cases handled in tetrate, so just call it + Decimal.prototype.iteratedexp = function(height = 2, payload = FC_NN(1, 0, 1)) { + return this.tetrate(height, payload); + } + + //iterated log/repeated log: The result of applying log(base) 'times' times in a row. Approximately equal to subtracting (times) from the number's slog representation. Equivalent to tetrating to a negative height. + //Works with negative and positive real heights. + Decimal.prototype.iteratedlog = function(base = 10, times = 1) { + if (times < 0) + { + return Decimal.tetrate(base, -times, this); + } + + base = D(base); + var result = D(this); + var fulltimes = times; + times = Math.trunc(times); + var fraction = fulltimes - times; + if (result.layer - base.layer > 3) + { + var layerloss = Math.min(times, (result.layer - base.layer - 3)); + times -= layerloss; + result.layer -= layerloss; + } + + for (var i = 0; i < times; ++i) + { + result = result.log(base); + //bail if we're NaN + if (!isFinite(result.layer) || !isFinite(result.mag)) { return result; } + //give up after 100 iterations if nothing is happening + if (i > 100) { return result; } + } + + //handle fractional part + if (fraction > 0 && fraction < 1) + { + if (base.eq(10)) + { + result = result.layeradd10(-fraction); + } + else + { + result = result.layeradd(-fraction, base); + } + } + + return result; + } + + //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. + // https://en.wikipedia.org/wiki/Super-logarithm + Decimal.prototype.slog = function(base = 10) { + if (this.mag < 0) { return Decimal.dNegOne; } + + base = D(base); + + var result = 0; + var copy = D(this); + if (copy.layer - base.layer > 3) + { + var layerloss = (copy.layer - base.layer - 3); + result += layerloss; + copy.layer -= layerloss; + } + + for (var i = 0; i < 100; ++i) + { + if (copy.lt(Decimal.dZero)) + { + copy = Decimal.pow(base, copy); + result -= 1; + } + else if (copy.lte(Decimal.dOne)) + { + return D(result + copy.toNumber() - 1); //<-- THIS IS THE CRITICAL FUNCTION + //^ Also have to change tetrate payload handling and layeradd10 if this is changed! + } + else + { + result += 1; + copy = Decimal.log(copy, base); + } + } + return D(result); + } + + //Approximations taken from the excellent paper https://web.archive.org/web/20090201164836/http://tetration.itgo.com/paper.html ! + //Not using for now unless I can figure out how to use it in all the related functions. + /*var slog_criticalfunction_1 = function(x, z) { + z = z.toNumber(); + return -1 + z; + } + + var slog_criticalfunction_2 = function(x, z) { + z = z.toNumber(); + var lnx = x.ln(); + if (lnx.layer === 0) + { + lnx = lnx.toNumber(); + return -1 + z*2*lnx/(1+lnx) - z*z*(1-lnx)/(1+lnx); + } + else + { + var term1 = lnx.mul(z*2).div(lnx.add(1)); + var term2 = Decimal.sub(1, lnx).mul(z*z).div(lnx.add(1)); + Decimal.dNegOne.add(Decimal.sub(term1, term2)); + } + } + + var slog_criticalfunction_3 = function(x, z) { + z = z.toNumber(); + var lnx = x.ln(); + var lnx2 = lnx.sqr(); + var lnx3 = lnx.cube(); + if (lnx.layer === 0 && lnx2.layer === 0 && lnx3.layer === 0) + { + lnx = lnx.toNumber(); + lnx2 = lnx2.toNumber(); + lnx3 = lnx3.toNumber(); + + var term1 = 6*z*(lnx+lnx3); + var term2 = 3*z*z*(3*lnx2-2*lnx3); + var term3 = 2*z*z*z*(1-lnx-2*lnx2+lnx3); + var top = term1+term2+term3; + var bottom = 2+4*lnx+5*lnx2+2*lnx3; + + return -1 + top/bottom; + } + else + { + var term1 = (lnx.add(lnx3)).mul(6*z); + var term2 = (lnx2.mul(3).sub(lnx3.mul(2))).mul(3*z*z); + var term3 = (Decimal.dOne.sub(lnx).sub(lnx2.mul(2)).add(lnx3)).mul(2*z*z*z); + var top = term1.add(term2).add(term3); + var bottom = new Decimal(2).add(lnx.mul(4)).add(lnx2.mul(5)).add(lnx3.mul(2)); + + return Decimal.dNegOne.add(top.div(bottom)); + } + }*/ + + //Function for adding/removing layers from a Decimal, even fractional layers (e.g. its slog10 representation). + //Everything continues to use the linear approximation ATM. + Decimal.prototype.layeradd10 = function(diff) { + diff = Decimal.fromValue_noAlloc(diff).toNumber(); + var result = D(this); + if (diff >= 1) + { + var layeradd = Math.trunc(diff); + diff -= layeradd; + result.layer += layeradd; + } + if (diff <= -1) + { + var layeradd = Math.trunc(diff); + diff -= layeradd; + result.layer += layeradd; + if (result.layer < 0) + { + for (var i = 0; i < 100; ++i) + { + result.layer++; + result.mag = Math.log10(result.mag); + if (!isFinite(result.mag)) { return result; } + if (result.layer >= 0) { break; } + } + } + } + + //layeradd10: like adding 'diff' to the number's slog(base) representation. Very similar to tetrate base 10 and iterated log base 10. Also equivalent to adding a fractional amount to the number's layer in its break_eternity.js representation. + if (diff > 0) + { + var subtractlayerslater = 0; + //Ironically, this edge case would be unnecessary if we had 'negative layers'. + while (Number.isFinite(result.mag) && result.mag < 10) + { + result.mag = Math.pow(10, result.mag); + ++subtractlayerslater; + } + + //A^(10^B) === C, solve for B + //B === log10(logA(C)) + + if (result.mag > 1e10) + { + result.mag = Math.log10(result.mag); + result.layer++; + } + + //Note that every integer slog10 value, the formula changes, so if we're near such a number, we have to spend exactly enough layerdiff to hit it, and then use the new formula. + var diffToNextSlog = Math.log10(Math.log(1e10)/Math.log(result.mag), 10); + if (diffToNextSlog < diff) + { + result.mag = Math.log10(1e10); + result.layer++; + diff -= diffToNextSlog; + } + + result.mag = Math.pow(result.mag, Math.pow(10, diff)); + + while (subtractlayerslater > 0) + { + result.mag = Math.log10(result.mag); + --subtractlayerslater; + } + } + else if (diff < 0) + { + var subtractlayerslater = 0; + + while (Number.isFinite(result.mag) && result.mag < 10) + { + result.mag = Math.pow(10, result.mag); + ++subtractlayerslater; + } + + if (result.mag > 1e10) + { + result.mag = Math.log10(result.mag); + result.layer++; + } + + var diffToNextSlog = Math.log10(1/Math.log10(result.mag)); + if (diffToNextSlog > diff) + { + result.mag = 1e10; + result.layer--; + diff -= diffToNextSlog; + } + + result.mag = Math.pow(result.mag, Math.pow(10, diff)); + + while (subtractlayerslater > 0) + { + result.mag = Math.log10(result.mag); + --subtractlayerslater; + } + } + + while (result.layer < 0) + { + result.layer++; + result.mag = Math.log10(result.mag); + } + result.normalize(); + return result; + } + + //layeradd: like adding 'diff' to the number's slog(base) representation. Very similar to tetrate base 'base' and iterated log base 'base'. + Decimal.prototype.layeradd = function(diff, base) { + var slogthis = this.slog(base).toNumber(); + var slogdest = slogthis+diff; + if (slogdest >= 0) + { + return Decimal.tetrate(base, slogdest); + } + else if (!Number.isFinite(slogdest)) + { + return Decimal.dNaN; + } + else if (slogdest >= -1) + { + return Decimal.log(Decimal.tetrate(base, slogdest+1), base); + } + else + { + Decimal.log(Decimal.log(Decimal.tetrate(base, slogdest+2), base), base); + } + } + + //The Lambert W function, also called the omega function or product logarithm, is the solution W(x) === x*e^x. + // https://en.wikipedia.org/wiki/Lambert_W_function + //Some special values, for testing: https://en.wikipedia.org/wiki/Lambert_W_function#Special_values + Decimal.prototype.lambertw = function() { + if (this.lt(-0.3678794411710499)) + { + throw Error("lambertw is unimplemented for results less than -1, sorry!"); + } + else if (this.mag < 0) + { + return D(f_lambertw(this.toNumber())); + } + else if (this.layer === 0) + { + return D(f_lambertw(this.sign*this.mag)); + } + else if (this.layer === 1) + { + return d_lambertw(this); + } + else if (this.layer === 2) + { + return d_lambertw(this); + } + if (this.layer >= 3) + { + return FC_NN(this.sign, this.layer-1, this.mag); + } + } + + //from https://github.com/scipy/scipy/blob/8dba340293fe20e62e173bdf2c10ae208286692f/scipy/special/lambertw.pxd + // The evaluation can become inaccurate very close to the branch point + // at ``-1/e``. In some corner cases, `lambertw` might currently + // fail to converge, or can end up on the wrong branch. + var d_lambertw = function(z, tol = 1e-10) { + var w; + var ew, wew, wewz, wn; + + if (!Number.isFinite(z.mag)) { return z; } + if (z === 0) + { + return z; + } + if (z === 1) + { + //Split out this case because the asymptotic series blows up + return OMEGA; + } + + var absz = Decimal.abs(z); + //Get an initial guess for Halley's method + w = Decimal.ln(z); + + //Halley's method; see 5.9 in [1] + + for (var i = 0; i < 100; ++i) + { + ew = Decimal.exp(-w); + wewz = w.sub(z.mul(ew)); + wn = w.sub(wewz.div(w.add(1).sub((w.add(2)).mul(wewz).div((Decimal.mul(2, w).add(2)))))); + if (Decimal.abs(wn.sub(w)).lt(Decimal.abs(wn).mul(tol))) + { + return wn; + } + else + { + w = wn; + } + } + + throw Error("Iteration failed to converge: " + z); + //return Decimal.dNaN; + } + + //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 + Decimal.prototype.ssqrt = function() { + if (this.sign == 1 && this.layer >= 3) + { + return FC_NN(this.sign, this.layer-1, this.mag) + } + var lnx = this.ln(); + return lnx.div(lnx.lambertw()); + } +/* + +Unit tests for tetrate/iteratedexp/iteratedlog/layeradd10/layeradd/slog: + +for (var i = 0; i < 1000; ++i) +{ + var first = Math.random()*100; + var both = Math.random()*100; + var expected = first+both+1; + var result = new Decimal(10).layeradd10(first).layeradd10(both).slog(); + if (Number.isFinite(result.mag) && !Decimal.eq_tolerance(expected, result)) + { + console.log(first + ", " + both); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var first = Math.random()*100; + var both = Math.random()*100; + first += both; + var expected = first-both+1; + var result = new Decimal(10).layeradd10(first).layeradd10(-both).slog(); + if (Number.isFinite(result.mag) && !Decimal.eq_tolerance(expected, result)) + { + console.log(first + ", " + both); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var first = Math.random()*100; + var both = Math.random()*100; + var base = Math.random()*8+2; + var expected = first+both+1; + var result = new Decimal(base).layeradd(first, base).layeradd(both, base).slog(base); + if (Number.isFinite(result.mag) && !Decimal.eq_tolerance(expected, result)) + { + console.log(first + ", " + both); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var first = Math.random()*100; + var both = Math.random()*100; + var base = Math.random()*8+2; + first += both; + var expected = first-both+1; + var result = new Decimal(base).layeradd(first, base).layeradd(-both, base).slog(base); + if (Number.isFinite(result.mag) && !Decimal.eq_tolerance(expected, result)) + { + console.log(first + ", " + both); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var first = Math.round((Math.random()*30))/10; + var both = Math.round((Math.random()*30))/10; + var tetrateonly = Decimal.tetrate(10, first); + var tetrateandlog = Decimal.tetrate(10, first+both).iteratedlog(10, both); + if (!Decimal.eq_tolerance(tetrateonly, tetrateandlog)) + { + console.log(first + ", " + both); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var first = Math.round((Math.random()*30))/10; + var both = Math.round((Math.random()*30))/10; + var base = Math.random()*8+2; + var tetrateonly = Decimal.tetrate(base, first); + var tetrateandlog = Decimal.tetrate(base, first+both).iteratedlog(base, both); + if (!Decimal.eq_tolerance(tetrateonly, tetrateandlog)) + { + console.log(first + ", " + both); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var first = Math.round((Math.random()*30))/10; + var both = Math.round((Math.random()*30))/10; + var base = Math.random()*8+2; + var tetrateonly = Decimal.tetrate(base, first, base); + var tetrateandlog = Decimal.tetrate(base, first+both, base).iteratedlog(base, both); + if (!Decimal.eq_tolerance(tetrateonly, tetrateandlog)) + { + console.log(first + ", " + both); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var xex = new Decimal(-0.3678794411710499+Math.random()*100); + var x = Decimal.lambertw(xex); + if (!Decimal.eq_tolerance(xex, x.mul(Decimal.exp(x)))) + { + console.log(xex); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var xex = new Decimal(-0.3678794411710499+Math.exp(Math.random()*100)); + var x = Decimal.lambertw(xex); + if (!Decimal.eq_tolerance(xex, x.mul(Decimal.exp(x)))) + { + console.log(xex); + } +} + +for (var i = 0; i < 1000; ++i) +{ + var a = Decimal.randomDecimalForTesting(Math.random() > 0.5 ? 0 : 1); + var b = Decimal.randomDecimalForTesting(Math.random() > 0.5 ? 0 : 1); + if (Math.random() > 0.5) { a = a.recip(); } + if (Math.random() > 0.5) { b = b.recip(); } + var c = a.add(b).toNumber(); + if (Number.isFinite(c) && !Decimal.eq_tolerance(c, a.toNumber()+b.toNumber())) + { + console.log(a + ", " + b); + } +} + +for (var i = 0; i < 100; ++i) +{ + var a = Decimal.randomDecimalForTesting(Math.round(Math.random()*4)); + var b = Decimal.randomDecimalForTesting(Math.round(Math.random()*4)); + if (Math.random() > 0.5) { a = a.recip(); } + if (Math.random() > 0.5) { b = b.recip(); } + var c = a.mul(b).toNumber(); + if (Number.isFinite(c) && Number.isFinite(a.toNumber()) && Number.isFinite(b.toNumber()) && a.toNumber() != 0 && b.toNumber() != 0 && c != 0 && !Decimal.eq_tolerance(c, a.toNumber()*b.toNumber())) + { + console.log("Test 1: " + a + ", " + b); + } + else if (!Decimal.mul(a.recip(), b.recip()).eq_tolerance(Decimal.mul(a, b).recip())) + { + console.log("Test 3: " + a + ", " + b); + } +} + +for (var i = 0; i < 10; ++i) +{ + var a = Decimal.randomDecimalForTesting(Math.round(Math.random()*4)); + var b = Decimal.randomDecimalForTesting(Math.round(Math.random()*4)); + if (Math.random() > 0.5 && a.sign !== 0) { a = a.recip(); } + if (Math.random() > 0.5 && b.sign !== 0) { b = b.recip(); } + var c = a.pow(b); + var d = a.root(b.recip()); + var e = a.pow(b.recip()); + var f = a.root(b); + + if (!c.eq_tolerance(d) && a.sign !== 0 && b.sign !== 0) + { + console.log("Test 1: " + a + ", " + b); + } + if (!e.eq_tolerance(f) && a.sign !== 0 && b.sign !== 0) + { + console.log("Test 2: " + a + ", " + b); + } +} + +for (var i = 0; i < 10; ++i) +{ + var a = Math.round(Math.random()*18-9); + var b = Math.round(Math.random()*100-50); + var c = Math.round(Math.random()*18-9); + var d = Math.round(Math.random()*100-50); + console.log("Decimal.pow(Decimal.fromMantissaExponent(" + a + ", " + b + "), Decimal.fromMantissaExponent(" + c + ", " + d + ")).toString()"); +} + +*/ + + //Pentation/pentate: The result of tetrating 'height' times in a row. An absurdly strong operator - Decimal.pentate(2, 4.28) and Decimal.pentate(10, 2.37) are already too huge for break_eternity.js! + // https://en.wikipedia.org/wiki/Pentation + Decimal.prototype.pentate = function(height = 2, payload = FC_NN(1, 0, 1)) { + payload = D(payload); + var oldheight = height; + height = Math.trunc(height); + var fracheight = oldheight-height; + + //I have no idea if this is a meaningful approximation for pentation to continuous heights, but it is monotonic and continuous. + if (fracheight !== 0) + { + if (payload.eq(Decimal.dOne)) + { + ++height; + payload = new Decimal(fracheight); + } + else + { + if (this.eq(10)) + { + payload = payload.layeradd10(fracheight); + } + else + { + payload = payload.layeradd(fracheight, this); + } + } + } + + for (var i = 0; i < height; ++i) + { + payload = this.tetrate(payload); + //bail if we're NaN + if (!isFinite(payload.layer) || !isFinite(payload.mag)) { return payload; } + //give up after 10 iterations if nothing is happening + if (i > 10) { return payload; } + } + + return payload; + } + + // trig functions! + Decimal.prototype.sin = function () { + if (this.mag < 0) { return this; } + if (this.layer === 0) { return D(Math.sin(this.sign*this.mag)); } + return FC_NN(0, 0, 0); + }; + + Decimal.prototype.cos = function () { + if (this.mag < 0) { return Decimal.dOne; } + if (this.layer === 0) { return D(Math.cos(this.sign*this.mag)); } + return FC_NN(0, 0, 0); + }; + + Decimal.prototype.tan = function () { + if (this.mag < 0) { return this; } + if (this.layer === 0) { return D(Math.tan(this.sign*this.mag)); } + return FC_NN(0, 0, 0); + }; + + Decimal.prototype.asin = function () { + if (this.mag < 0) { return this; } + if (this.layer === 0) { return D(Math.asin(this.sign*this.mag)); } + return FC_NN(Number.NaN, Number.NaN, Number.NaN); + }; + + Decimal.prototype.acos = function () { + if (this.mag < 0) { return D(Math.acos(this.toNumber())); } + if (this.layer === 0) { return D(Math.acos(this.sign*this.mag)); } + return FC_NN(Number.NaN, Number.NaN, Number.NaN); + }; + + Decimal.prototype.atan = function () { + if (this.mag < 0) { return this; } + if (this.layer === 0) { return D(Math.atan(this.sign*this.mag)); } + return D(Math.atan(this.sign*1.8e308)); + }; + + Decimal.prototype.sinh = function () { + return this.exp().sub(this.negate().exp()).div(2); + }; + + Decimal.prototype.cosh = function () { + return this.exp().add(this.negate().exp()).div(2); + }; + + Decimal.prototype.tanh = function () { + return this.sinh().div(this.cosh()); + }; + + Decimal.prototype.asinh = function () { + return Decimal.ln(this.add(this.sqr().add(1).sqrt())); + }; + + Decimal.prototype.acosh = function () { + return Decimal.ln(this.add(this.sqr().sub(1).sqrt())); + }; + + Decimal.prototype.atanh = function () { + if (this.abs().gte(1)) { + return FC_NN(Number.NaN, Number.NaN, Number.NaN); + } + + return Decimal.ln(this.add(1).div(D(1).sub(this))).div(2); + }; + + /** + * Joke function from Realm Grinder + */ + Decimal.prototype.ascensionPenalty = function (ascensions) { + if (ascensions === 0) { + return this; + } + + return this.root(Decimal.pow(10, ascensions)); + }; + + /** + * Joke function from Cookie Clicker. It's 'egg' + */ + Decimal.prototype.egg = function () { + return this.add(9); + }; + + Decimal.prototype.lessThanOrEqualTo = function (other) { + return this.cmp(other) < 1; + }; + + Decimal.prototype.lessThan = function (other) { + return this.cmp(other) < 0; + }; + + Decimal.prototype.greaterThanOrEqualTo = function (other) { + return this.cmp(other) > -1; + }; + + Decimal.prototype.greaterThan = function (other) { + return this.cmp(other) > 0; + }; + + return Decimal; + }(); + + Decimal.dZero = FC_NN(0, 0, 0); + Decimal.dOne = FC_NN(1, 0, 1); + Decimal.dNegOne = FC_NN(-1, 0, 1); + Decimal.dTwo = FC_NN(1, 0, 2); + Decimal.dTen = FC_NN(1, 0, 10); + Decimal.dNaN = FC_NN(Number.NaN, Number.NaN, Number.NaN); + Decimal.dInf = FC_NN(1, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY); + Decimal.dNegInf = FC_NN(-1, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY); + Decimal.dNumberMax = FC(1, 0, Number.MAX_VALUE); + Decimal.dNumberMin = FC(1, 0, Number.MIN_VALUE); + + return Decimal; + +})); diff --git a/js/break_eternity.min.js b/js/break_eternity.min.js deleted file mode 100644 index 748a0bf..0000000 --- a/js/break_eternity.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";function _instanceof(t,r){return null!=r&&"undefined"!=typeof Symbol&&r[Symbol.hasInstance]?!!r[Symbol.hasInstance](t):t instanceof r}function _typeof(t){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}!function(t,r){"object"===("undefined"==typeof exports?"undefined":_typeof(exports))&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(t=t||self).Decimal=r()}(void 0,function(){var t=Math.log10(9e15),r=function(){for(var t=[],r=-323;r<=308;r++)t.push(Number("1e"+r));return function(r){return t[r+323]}}(),i=function(t){return h.fromValue_noAlloc(t)},e=function(t,r,i){return h.fromComponents(t,r,i)},n=function(t,r,i){return h.fromComponents_noNormalize(t,r,i)},a=function(t,r){var i=r+1,e=Math.ceil(Math.log10(Math.abs(t))),n=Math.round(t*Math.pow(10,i-e))*Math.pow(10,e-i);return parseFloat(n.toFixed(Math.max(i-e,0)))},s=function(t){return Math.sign(t)*Math.log10(Math.abs(t))},o=function(t){var r,i,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1e-10;if(!Number.isFinite(t))return t;if(0===t)return t;if(1===t)return.5671432904097838;r=t<10?0:Math.log(t)-Math.log(Math.log(t));for(var n=0;n<100;++n){if(i=(t*Math.exp(-r)+r*r)/(r+1),Math.abs(i-r)1&&void 0!==arguments[1]?arguments[1]:2,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:n(1,0,1);return i(t).tetrate(r,e)},h.iteratedexp=function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:2,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:n(1,0,1);return i(t).iteratedexp(r,e)},h.iteratedlog=function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:10,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1;return i(t).iteratedlog(r,e)},h.layeradd10=function(t,r){return i(t).layeradd10(r)},h.layeradd=function(t,r){var e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:10;return i(t).layeradd(r,e)},h.slog=function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:10;return i(t).slog(r)},h.lambertw=function(t){return i(t).lambertw()},h.ssqrt=function(t){return i(t).ssqrt()},h.pentate=function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:2,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:n(1,0,1);return i(t).pentate(r,e)},h.affordGeometricSeries=function(t,r,e,n){return this.affordGeometricSeries_core(i(t),i(r),i(e),n)},h.sumGeometricSeries=function(t,r,e,n){return this.sumGeometricSeries_core(t,i(r),i(e),n)},h.affordArithmeticSeries=function(t,r,e,n){return this.affordArithmeticSeries_core(i(t),i(r),i(e),i(n))},h.sumArithmeticSeries=function(t,r,e,n){return this.sumArithmeticSeries_core(i(t),i(r),i(e),i(n))},h.efficiencyOfPurchase=function(t,r,e){return this.efficiencyOfPurchase_core(i(t),i(r),i(e))},h.randomDecimalForTesting=function(t){if(20*Math.random()<1)return n(0,0,0);var r=Math.random()>.5?1:-1;if(20*Math.random()<1)return n(r,0,1);var i=Math.floor(Math.random()*(t+1)),a=0===i?616*Math.random()-308:16*Math.random();Math.random()>.9&&(a=Math.trunc(a));var s=Math.pow(10,a);return Math.random()>.9&&(s=Math.trunc(s)),e(r,i,s)},h.affordGeometricSeries_core=function(t,r,i,e){var n=r.mul(i.pow(e));return h.floor(t.div(n).mul(i.sub(1)).add(1).log10().div(i.log10()))},h.sumGeometricSeries_core=function(t,r,i,e){return r.mul(i.pow(e)).mul(h.sub(1,i.pow(t))).div(h.sub(1,i))},h.affordArithmeticSeries_core=function(t,r,i,e){var n=r.add(e.mul(i)).sub(i.div(2)),a=n.pow(2);return n.neg().add(a.add(i.mul(t).mul(2)).sqrt()).div(i).floor()},h.sumArithmeticSeries_core=function(t,r,i,e){var n=r.add(e.mul(i));return t.div(2).mul(n.mul(2).plus(t.sub(1).mul(i)))},h.efficiencyOfPurchase_core=function(t,r,i){return t.div(r).add(t.div(i))},h.prototype.normalize=function(){if(0===this.sign||0===this.mag&&0===this.layer)return this.sign=0,this.mag=0,this.layer=0,this;if(0===this.layer&&this.mag<0&&(this.mag=-this.mag,this.sign=-this.sign),0===this.layer&&this.mag<1/9e15)return this.layer+=1,this.mag=Math.log10(this.mag),this;var r=Math.abs(this.mag),i=Math.sign(this.mag);if(r>=9e15)return this.layer+=1,this.mag=i*Math.log10(r),this;for(;r0;)this.layer-=1,0===this.layer?this.mag=Math.pow(10,this.mag):(this.mag=i*Math.pow(10,r),r=Math.abs(this.mag),i=Math.sign(this.mag));return 0===this.layer&&(this.mag<0?(this.mag=-this.mag,this.sign=-this.sign):0===this.mag&&(this.sign=0)),this},h.prototype.fromComponents=function(t,r,i){return this.sign=t,this.layer=r,this.mag=i,this.normalize(),this},h.prototype.fromComponents_noNormalize=function(t,r,i){return this.sign=t,this.layer=r,this.mag=i,this},h.prototype.fromMantissaExponent=function(t,r){return this.layer=1,this.sign=Math.sign(t),t=Math.abs(t),this.mag=r+Math.log10(t),this.normalize(),this},h.prototype.fromMantissaExponent_noNormalize=function(t,r){return this.fromMantissaExponent(t,r),this},h.prototype.fromDecimal=function(t){return this.sign=t.sign,this.layer=t.layer,this.mag=t.mag,this},h.prototype.fromNumber=function(t){return this.mag=Math.abs(t),this.sign=Math.sign(t),this.layer=0,this.normalize(),this};h.prototype.fromString=function(t){var r=(t=t.replace(",","")).split("^^^");if(2===r.length){var n=parseFloat(r[0]),a=parseFloat(r[1]),o=1;if(2===(l=r[1].split(";")).length){o=parseFloat(l[1]);isFinite(o)||(o=1)}if(isFinite(n)&&isFinite(a)){var u=h.pentate(n,a,o);return this.sign=u.sign,this.layer=u.layer,this.mag=u.mag,this}}var g=t.split("^^");if(2===g.length){var l;n=parseFloat(g[0]),a=parseFloat(g[1]);if(2===(l=g[1].split(";")).length){o=parseFloat(l[1]);isFinite(o)||(o=1)}if(isFinite(n)&&isFinite(a)){u=h.tetrate(n,a,o);return this.sign=u.sign,this.layer=u.layer,this.mag=u.mag,this}}var m,f=t.split("^");if(2===f.length){n=parseFloat(f[0]);var c=parseFloat(f[1]);if(isFinite(n)&&isFinite(c)){u=h.pow(n,c);return this.sign=u.sign,this.layer=u.layer,this.mag=u.mag,this}}if(2===(m=(t=t.trim().toLowerCase()).split("pt")).length){n=10,a=parseFloat(m[0]),m[1]=m[1].replace("(",""),m[1]=m[1].replace(")","");o=parseFloat(m[1]);if(isFinite(o)||(o=1),isFinite(n)&&isFinite(a)){u=h.tetrate(n,a,o);return this.sign=u.sign,this.layer=u.layer,this.mag=u.mag,this}}if(2===(m=t.split("p")).length){n=10,a=parseFloat(m[0]),m[1]=m[1].replace("(",""),m[1]=m[1].replace(")","");o=parseFloat(m[1]);if(isFinite(o)||(o=1),isFinite(n)&&isFinite(a)){u=h.tetrate(n,a,o);return this.sign=u.sign,this.layer=u.layer,this.mag=u.mag,this}}var p=t.split("e"),y=p.length-1;if(0===y){var d=parseFloat(t);if(isFinite(d))return this.fromNumber(d)}else if(1===y){d=parseFloat(t);if(isFinite(d)&&0!==d)return this.fromNumber(d)}var M=t.split("e^");if(2===M.length){this.sign=1,"-"==M[0].charAt(0)&&(this.sign=-1);for(var b="",N=0;N=43&&v<=57||101===v))return this.layer=parseFloat(b),this.mag=parseFloat(M[1].substr(N+1)),this.normalize(),this;b+=M[1].charAt(N)}}if(y<1)return this.sign=0,this.layer=0,this.mag=0,this;var _=parseFloat(p[0]);if(0===_)return this.sign=0,this.layer=0,this.mag=0,this;c=parseFloat(p[p.length-1]);if(y>=2){var F=parseFloat(p[p.length-2]);isFinite(F)&&(c*=Math.sign(F),c+=s(F))}if(isFinite(_))if(1===y)this.sign=Math.sign(_),this.layer=1,this.mag=c+Math.log10(Math.abs(_));else{if(this.sign=Math.sign(_),this.layer=y,2===y){u=h.mul(e(1,2,c),i(_));return this.sign=u.sign,this.layer=u.layer,this.mag=u.mag,this}this.mag=c}else this.sign="-"===p[0]?-1:1,this.layer=y,this.mag=c;return this.normalize(),this},h.prototype.fromValue=function(t){return _instanceof(t,h)?this.fromDecimal(t):"number"==typeof t?this.fromNumber(t):"string"==typeof t?this.fromString(t):(this.sign=0,this.layer=0,this.mag=0,this)},h.prototype.toNumber=function(){return Number.isFinite(this.layer)?0===this.layer?this.sign*this.mag:1===this.layer?this.sign*Math.pow(10,this.mag):this.mag>0?this.sign>0?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:0:Number.NaN},h.prototype.mantissaWithDecimalPlaces=function(t){return isNaN(this.m)?Number.NaN:0===this.m?0:a(this.m,t)},h.prototype.magnitudeWithDecimalPlaces=function(t){return isNaN(this.mag)?Number.NaN:0===this.mag?0:a(this.mag,t)},h.prototype.toString=function(){return 0===this.layer?this.mag<1e21&&this.mag>1e-7||0===this.mag?(this.sign*this.mag).toString():this.m+"e"+this.e:1===this.layer?this.m+"e"+this.e:this.layer<=5?(-1===this.sign?"-":"")+"e".repeat(this.layer)+this.mag:(-1===this.sign?"-":"")+"(e^"+this.layer+")"+this.mag},h.prototype.toExponential=function(t){return 0===this.layer?(this.sign*this.mag).toExponential(t):this.toStringWithDecimalPlaces(t)},h.prototype.toFixed=function(t){return 0===this.layer?(this.sign*this.mag).toFixed(t):this.toStringWithDecimalPlaces(t)},h.prototype.toPrecision=function(t){return this.e<=-7?this.toExponential(t-1):t>this.e?this.toFixed(t-this.exponent-1):this.toExponential(t-1)},h.prototype.valueOf=function(){return this.toString()},h.prototype.toJSON=function(){return this.toString()},h.prototype.toStringWithDecimalPlaces=function(t){return 0===this.layer?this.mag<1e21&&this.mag>1e-7||0===this.mag?(this.sign*this.mag).toFixed(t):a(this.m,t)+"e"+a(this.e,t):1===this.layer?a(this.m,t)+"e"+a(this.e,t):this.layer<=5?(-1===this.sign?"-":"")+"e".repeat(this.layer)+a(this.mag,t):(-1===this.sign?"-":"")+"(e^"+this.layer+")"+a(this.mag,t)},h.prototype.abs=function(){return n(0===this.sign?0:1,this.layer,this.mag)},h.prototype.neg=function(){return n(-this.sign,this.layer,this.mag)},h.prototype.negate=function(){return this.neg()},h.prototype.negated=function(){return this.neg()},h.prototype.sign=function(){return this.sign},h.prototype.sgn=function(){return this.sign},h.prototype.round=function(){return this.mag<0?h.dZero:0===this.layer?e(this.sign,0,Math.round(this.mag)):this},h.prototype.floor=function(){return this.mag<0?h.dZero:0===this.layer?e(this.sign,0,Math.floor(this.mag)):this},h.prototype.ceil=function(){return this.mag<0?h.dZero:0===this.layer?e(this.sign,0,Math.ceil(this.mag)):this},h.prototype.trunc=function(){return this.mag<0?h.dZero:0===this.layer?e(this.sign,0,Math.trunc(this.mag)):this},h.prototype.add=function(t){var r,a,s=i(t);if(!Number.isFinite(this.layer))return this;if(!Number.isFinite(s.layer))return s;if(0===this.sign)return s;if(0===s.sign)return this;if(this.sign===-s.sign&&this.layer===s.layer&&this.mag===s.mag)return n(0,0,0);if(this.layer>=2||s.layer>=2)return this.maxabs(s);if(h.cmpabs(this,s)>0?(r=this,a=s):(r=s,a=this),0===r.layer&&0===a.layer)return i(r.sign*r.mag+a.sign*a.mag);var o=r.layer*Math.sign(r.mag),u=a.layer*Math.sign(a.mag);if(o-u>=2)return r;if(0===o&&-1===u){if(Math.abs(a.mag-Math.log10(r.mag))>17)return r;var g=Math.pow(10,Math.log10(r.mag)-a.mag),l=a.sign+r.sign*g;return e(Math.sign(l),1,a.mag+Math.log10(Math.abs(l)))}if(1===o&&0===u){if(Math.abs(r.mag-Math.log10(a.mag))>17)return r;g=Math.pow(10,r.mag-Math.log10(a.mag)),l=a.sign+r.sign*g;return e(Math.sign(l),1,Math.log10(a.mag)+Math.log10(Math.abs(l)))}if(Math.abs(r.mag-a.mag)>17)return r;g=Math.pow(10,r.mag-a.mag),l=a.sign+r.sign*g;return e(Math.sign(l),1,a.mag+Math.log10(Math.abs(l)))},h.prototype.plus=function(t){return this.add(t)},h.prototype.sub=function(t){return this.add(i(t).neg())},h.prototype.subtract=function(t){return this.sub(t)},h.prototype.minus=function(t){return this.sub(t)},h.prototype.mul=function(t){var r,a,s=i(t);if(!Number.isFinite(this.layer))return this;if(!Number.isFinite(s.layer))return s;if(0===this.sign||0===s.sign)return n(0,0,0);if(this.layer===s.layer&&this.mag===-s.mag)return n(this.sign*s.sign,0,1);if(this.layer>s.layer||this.layer==s.layer&&Math.abs(this.mag)>Math.abs(s.mag)?(r=this,a=s):(r=s,a=this),0===r.layer&&0===a.layer)return i(r.sign*a.sign*r.mag*a.mag);if(r.layer>=3||r.layer-a.layer>=2)return e(r.sign*a.sign,r.layer,r.mag);if(1===r.layer&&0===a.layer)return e(r.sign*a.sign,1,r.mag+Math.log10(a.mag));if(1===r.layer&&1===a.layer)return e(r.sign*a.sign,1,r.mag+a.mag);if(2===r.layer&&1===a.layer){var o=e(Math.sign(r.mag),r.layer-1,Math.abs(r.mag)).add(e(Math.sign(a.mag),a.layer-1,Math.abs(a.mag)));return e(r.sign*a.sign,o.layer+1,o.sign*o.mag)}if(2===r.layer&&2===a.layer){o=e(Math.sign(r.mag),r.layer-1,Math.abs(r.mag)).add(e(Math.sign(a.mag),a.layer-1,Math.abs(a.mag)));return e(r.sign*a.sign,o.layer+1,o.sign*o.mag)}throw Error("Bad arguments to mul: "+this+", "+t)},h.prototype.multiply=function(t){return this.mul(t)},h.prototype.times=function(t){return this.mul(t)},h.prototype.div=function(t){var r=i(t);return this.mul(r.recip())},h.prototype.divide=function(t){return this.div(t)},h.prototype.divideBy=function(t){return this.div(t)},h.prototype.dividedBy=function(t){return this.div(t)},h.prototype.recip=function(){return 0===this.mag?h.dNaN:0===this.layer?e(this.sign,0,1/this.mag):e(this.sign,this.layer,-this.mag)},h.prototype.reciprocal=function(){return this.recip()},h.prototype.reciprocate=function(){return this.recip()},h.prototype.cmp=function(t){var r=i(t);return this.sign>r.sign?1:this.sign0?this.layer:-this.layer,n=r.mag>0?r.layer:-r.layer;return e>n?1:er.mag?1:this.mag0?r:this},h.prototype.clamp=function(t,r){return this.max(t).min(r)},h.prototype.clampMin=function(t){return this.max(t)},h.prototype.clampMax=function(t){return this.min(t)},h.prototype.cmp_tolerance=function(t,r){var e=i(t);return this.eq_tolerance(e,r)?0:this.cmp(e)},h.prototype.compare_tolerance=function(t,r){return this.cmp_tolerance(t,r)},h.prototype.eq_tolerance=function(t,r){var e=i(t);if(null==r&&(r=1e-7),this.sign!==e.sign)return!1;if(Math.abs(this.layer-e.layer)>1)return!1;var n=this.mag,a=e.mag;return this.layer>e.layer&&(a=s(a)),this.layer0?e(Math.sign(this.mag),this.layer-1,Math.abs(this.mag)):e(1,0,Math.log10(this.mag))},h.prototype.log10=function(){return this.sign<=0?h.dNaN:this.layer>0?e(Math.sign(this.mag),this.layer-1,Math.abs(this.mag)):e(this.sign,0,Math.log10(this.mag))},h.prototype.log=function(t){return t=i(t),this.sign<=0?h.dNaN:t.sign<=0?h.dNaN:1===t.sign&&0===t.layer&&1===t.mag?h.dNaN:0===this.layer&&0===t.layer?e(this.sign,0,Math.log(this.mag)/Math.log(t.mag)):h.div(this.log10(),t.log10())},h.prototype.log2=function(){return this.sign<=0?h.dNaN:0===this.layer?e(this.sign,0,Math.log2(this.mag)):1===this.layer?e(Math.sign(this.mag),0,3.321928094887362*Math.abs(this.mag)):2===this.layer?e(Math.sign(this.mag),1,Math.abs(this.mag)+.5213902276543247):e(Math.sign(this.mag),this.layer-1,Math.abs(this.mag))},h.prototype.ln=function(){return this.sign<=0?h.dNaN:0===this.layer?e(this.sign,0,Math.log(this.mag)):1===this.layer?e(Math.sign(this.mag),0,2.302585092994046*Math.abs(this.mag)):2===this.layer?e(Math.sign(this.mag),1,Math.abs(this.mag)+.36221568869946325):e(Math.sign(this.mag),this.layer-1,Math.abs(this.mag))},h.prototype.logarithm=function(t){return this.log(t)},h.prototype.pow=function(t){var r=this,e=i(t);if(0===r.sign)return r;if(1===r.sign&&0===r.layer&&1===r.mag)return r;if(0===e.sign)return n(1,0,1);if(1===e.sign&&0===e.layer&&1===e.mag)return r;var a=r.absLog10().mul(e).pow10();return-1===this.sign&&e.toNumber()%2==1?a.neg():a},h.prototype.pow10=function(){if(!Number.isFinite(this.layer)||!Number.isFinite(this.mag))return h.dNaN;var t=this;if(0===t.layer){var r=Math.pow(10,t.sign*t.mag);if(Number.isFinite(r)&&Math.abs(r)>.1)return e(1,0,r);if(0===t.sign)return h.dOne;t=n(t.sign,t.layer+1,Math.log10(t.mag))}return t.sign>0&&t.mag>0?e(t.sign,t.layer+1,t.mag):t.sign<0&&t.mag>0?e(-t.sign,t.layer+1,-t.mag):h.dOne},h.prototype.pow_base=function(t){return i(t).pow(this)},h.prototype.root=function(t){var r=i(t);return this.pow(r.recip())},h.prototype.factorial=function(){return this.mag<0?this.toNumber().add(1).gamma():0===this.layer?this.add(1).gamma():1===this.layer?h.exp(h.mul(this,h.ln(this).sub(1))):h.exp(this)},h.prototype.gamma=function(){if(this.mag<0)return this.recip();if(0===this.layer){if(this.lt(n(1,0,24)))return i(function(t){if(!isFinite(t))return t;if(t<-50)return t===Math.trunc(t)?Number.NEGATIVE_INFINITY:0;for(var r=1;t<10;)r*=t,++t;var i=.9189385332046727;i+=(.5+(t-=1))*Math.log(t),i-=t;var e=t*t,n=t;return i+=1/(12*n),i+=1/(360*(n*=e)),i+=1/(1260*(n*=e)),i+=1/(1680*(n*=e)),i+=1/(1188*(n*=e)),i+=691/(360360*(n*=e)),i+=7/(1092*(n*=e)),i+=3617/(122400*(n*=e)),Math.exp(i)/r}(this.sign*this.mag));var t=this.mag-1,r=.9189385332046727;r+=(t+.5)*Math.log(t);var e=t*t,a=t,s=12*a,o=1/s,u=(r-=t)+o;if(u===r)return h.exp(r);if((u=(r=u)-(o=1/(s=360*(a*=e))))===r)return h.exp(r);r=u;var g=1/(s=1260*(a*=e));return r+=g,r-=g=1/(s=1680*(a*=e)),h.exp(r)}return 1===this.layer?h.exp(h.mul(this,h.ln(this).sub(1))):h.exp(this)},h.prototype.lngamma=function(){return this.gamma().ln()},h.prototype.exp=function(){return this.mag<0?h.dOne:0===this.layer&&this.mag<=709.7?i(Math.exp(this.sign*this.mag)):0===this.layer?e(1,1,this.sign*Math.log10(Math.E)*this.mag):1===this.layer?e(1,2,this.sign*(Math.log10(.4342944819032518)+this.mag)):e(1,this.layer+1,this.sign*this.mag)},h.prototype.sqr=function(){return this.pow(2)},h.prototype.sqrt=function(){if(0===this.layer)return i(Math.sqrt(this.sign*this.mag));if(1===this.layer)return e(1,2,Math.log10(this.mag)-.3010299956639812);var t=h.div(n(this.sign,this.layer-1,this.mag),n(1,0,2));return t.layer+=1,t.normalize(),t},h.prototype.cube=function(){return this.pow(3)},h.prototype.cbrt=function(){return this.pow(1/3)},h.prototype.tetrate=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:2,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:n(1,0,1);if(t===Number.POSITIVE_INFINITY){var e=h.ln(this).neg();return e.lambertw().div(e)}if(t<0)return h.iteratedlog(r,this,-t);r=i(r);var a=t-(t=Math.trunc(t));0!==a&&(r.eq(h.dOne)?(++t,r=new h(a)):r=this.eq(10)?r.layeradd10(a):r.layeradd(a,this));for(var s=0;s3)return n(r.sign,r.layer+(t-s-1),r.mag);if(s>100)return r}return r},h.prototype.iteratedexp=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:2,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:n(1,0,1);return this.tetrate(t,r)},h.prototype.iteratedlog=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:10,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;if(r<0)return h.tetrate(t,-r,this);t=i(t);var e=i(this),n=r-(r=Math.trunc(r));if(e.layer-t.layer>3){var a=Math.min(r,e.layer-t.layer-3);r-=a,e.layer-=a}for(var s=0;s100)return e}return n>0&&n<1&&(e=t.eq(10)?e.layeradd10(-n):e.layeradd(-n,t)),e},h.prototype.slog=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:10;if(this.mag<0)return h.dNegOne;t=i(t);var r=0,e=i(this);if(e.layer-t.layer>3){var n=e.layer-t.layer-3;r+=n,e.layer-=n}for(var a=0;a<100;++a)if(e.lt(h.dZero))e=h.pow(t,e),r-=1;else{if(e.lte(h.dOne))return i(r+e.toNumber()-1);r+=1,e=h.log(e,t)}return i(r)},h.prototype.layeradd10=function(t){t=h.fromValue_noAlloc(t).toNumber();var r,e=i(this);t>=1&&(t-=r=Math.trunc(t),e.layer+=r);if(t<=-1&&(t-=r=Math.trunc(t),e.layer+=r,e.layer<0))for(var n=0;n<100;++n){if(e.layer++,e.mag=Math.log10(e.mag),!isFinite(e.mag))return e;if(e.layer>=0)break}if(t>0){for(var a=0;Number.isFinite(e.mag)&&e.mag<10;)e.mag=Math.pow(10,e.mag),++a;for(e.mag>1e10&&(e.mag=Math.log10(e.mag),e.layer++),(s=Math.log10(Math.log(1e10)/Math.log(e.mag),10))0;)e.mag=Math.log10(e.mag),--a}else if(t<0){for(a=0;Number.isFinite(e.mag)&&e.mag<10;)e.mag=Math.pow(10,e.mag),++a;var s;for(e.mag>1e10&&(e.mag=Math.log10(e.mag),e.layer++),(s=Math.log10(1/Math.log10(e.mag)))>t&&(e.mag=1e10,e.layer--,t-=s),e.mag=Math.pow(e.mag,Math.pow(10,t));a>0;)e.mag=Math.log10(e.mag),--a}for(;e.layer<0;)e.layer++,e.mag=Math.log10(e.mag);return e.normalize(),e},h.prototype.layeradd=function(t,r){var i=this.slog(r).toNumber()+t;return i>=0?h.tetrate(r,i):Number.isFinite(i)?i>=-1?h.log(h.tetrate(r,i+1),r):void h.log(h.log(h.tetrate(r,i+2),r),r):h.dNaN},h.prototype.lambertw=function(){if(this.lt(-.3678794411710499))throw Error("lambertw is unimplemented for results less than -1, sorry!");return this.mag<0?i(o(this.toNumber())):0===this.layer?i(o(this.sign*this.mag)):1===this.layer?u(this):2===this.layer?u(this):this.layer>=3?n(this.sign,this.layer-1,this.mag):void 0};var u=function(t){var r,i,e,n,a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1e-10;if(!Number.isFinite(t.mag))return t;if(0===t)return t;if(1===t)return.5671432904097838;h.abs(t);r=h.ln(t);for(var s=0;s<100;++s){if(i=h.exp(-r),e=r.sub(t.mul(i)),n=r.sub(e.div(r.add(1).sub(r.add(2).mul(e).div(h.mul(2,r).add(2))))),h.abs(n.sub(r)).lt(h.abs(n).mul(a)))return n;r=n}throw Error("Iteration failed to converge: "+t)};return h.prototype.ssqrt=function(){if(1==this.sign&&this.layer>=3)return n(this.sign,this.layer-1,this.mag);var t=this.ln();return t.div(t.lambertw())},h.prototype.pentate=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:2,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:n(1,0,1);r=i(r);var e=t-(t=Math.trunc(t));0!==e&&(r.eq(h.dOne)?(++t,r=new h(e)):r=this.eq(10)?r.layeradd10(e):r.layeradd(e,this));for(var a=0;a10)return r}return r},h.prototype.sin=function(){return this.mag<0?this:0===this.layer?i(Math.sin(this.sign*this.mag)):n(0,0,0)},h.prototype.cos=function(){return this.mag<0?h.dOne:0===this.layer?i(Math.cos(this.sign*this.mag)):n(0,0,0)},h.prototype.tan=function(){return this.mag<0?this:0===this.layer?i(Math.tan(this.sign*this.mag)):n(0,0,0)},h.prototype.asin=function(){return this.mag<0?this:0===this.layer?i(Math.asin(this.sign*this.mag)):n(Number.NaN,Number.NaN,Number.NaN)},h.prototype.acos=function(){return this.mag<0?i(Math.acos(this.toNumber())):0===this.layer?i(Math.acos(this.sign*this.mag)):n(Number.NaN,Number.NaN,Number.NaN)},h.prototype.atan=function(){return this.mag<0?this:0===this.layer?i(Math.atan(this.sign*this.mag)):i(Math.atan(Infinity*this.sign))},h.prototype.sinh=function(){return this.exp().sub(this.negate().exp()).div(2)},h.prototype.cosh=function(){return this.exp().add(this.negate().exp()).div(2)},h.prototype.tanh=function(){return this.sinh().div(this.cosh())},h.prototype.asinh=function(){return h.ln(this.add(this.sqr().add(1).sqrt()))},h.prototype.acosh=function(){return h.ln(this.add(this.sqr().sub(1).sqrt()))},h.prototype.atanh=function(){return this.abs().gte(1)?n(Number.NaN,Number.NaN,Number.NaN):h.ln(this.add(1).div(i(1).sub(this))).div(2)},h.prototype.ascensionPenalty=function(t){return 0===t?this:this.root(h.pow(10,t))},h.prototype.egg=function(){return this.add(9)},h.prototype.lessThanOrEqualTo=function(t){return this.cmp(t)<1},h.prototype.lessThan=function(t){return this.cmp(t)<0},h.prototype.greaterThanOrEqualTo=function(t){return this.cmp(t)>-1},h.prototype.greaterThan=function(t){return this.cmp(t)>0},h}();return h.dZero=n(0,0,0),h.dOne=n(1,0,1),h.dNegOne=n(-1,0,1),h.dTwo=n(1,0,2),h.dTen=n(1,0,10),h.dNaN=n(Number.NaN,Number.NaN,Number.NaN),h.dInf=n(1,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY),h.dNegInf=n(-1,Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY),h.dNumberMax=e(1,0,Number.MAX_VALUE),h.dNumberMin=e(1,0,Number.MIN_VALUE),h}); diff --git a/js/game.js b/js/game.js index 577c299..8306518 100644 --- a/js/game.js +++ b/js/game.js @@ -73,6 +73,7 @@ function getStartPlayer() { sb: { unl: false, order: 0, + auto: false, points: new Decimal(0), best: new Decimal(0), upgrades: [], @@ -819,6 +820,7 @@ function checkForVars() { if (player.s.buildings[5] === undefined) player.s.buildings[5] = new Decimal(0); if (player.s.auto === undefined) player.s.auto = false if (player.sb === undefined) player.sb = getStartPlayer().sb + if (player.sb.auto === undefined) player.sb.auto = false if (player.timePlayed === undefined) player.timePlayed = 0 if (player.hasNaN === undefined) player.hasNaN = false if (player.h === undefined) player.h = getStartPlayer().h @@ -1046,7 +1048,8 @@ function rowReset(row, layer) { case 1: player.points = new Decimal(10); player.p.points = new Decimal(0); - if ((player.h.best.lt(1)&&player.q.best.lt(1))||LAYER_ROW[layer]>=3) { + if (LAYER_ROW[layer]>=3 && player.h.best.gte(10)) player.p.upgrades = prev.p.upgrades; + else if ((player.h.best.lt(1)&&player.q.best.lt(1))||LAYER_ROW[layer]>=3) { if (layer=="b"||layer=="g") { if (player[layer].best.lt(8)) player.p.upgrades = []; } else if (layer=="t"||layer=="s"||layer=="sb") { @@ -1100,14 +1103,16 @@ function rowReset(row, layer) { 4: new Decimal(0), 5: new Decimal(0) }), - upgrades: player.h.best.gte(2) ? player.s.upgrades : [], + upgrades: player.h.best.gte(4) ? player.s.upgrades : [], + auto: player.s.auto, } player.sb = { unl: player.sb.unl, + auto: player.sb.auto, order: 0, points: new Decimal(0), best: player.h.best.gte(2) ? player.sb.best : new Decimal(0), - upgrades: [], + upgrades: player.h.best.gte(10) ? player.sb.upgrades : [], } player.q.time = new Decimal(0); player.q.energy = new Decimal(0); @@ -1505,11 +1510,15 @@ function gameLoop(diff) { let exp = getQuirkEnergyGainExp() if (exp.gte(0)) player.q.energy = player.q.energy.plus(player.q.time.pow(exp).times(diff)) } + if (player.q.best.gte(15)) player.e.points = player.e.points.plus(tmp.resetGain.e.times(diff)) if (player.b.auto&&player.t.best.gte(5)) doReset("b") if (player.g.auto&&player.s.best.gte(5)) doReset("g") if (player.e.auto&&player.q.best.gte(5)) maxEnhancers() if (player.t.autoCap&&player.h.best.gte(5)) maxExtTimeCapsules() + if (player.t.auto&&player.q.best.gte(10)) doReset("t") + if (player.s.auto&&player.q.best.gte(10)) doReset("s") + if (player.sb.auto&&player.h.best.gte(15)) doReset("sb") if (player.hasNaN&&!NaNalert) { alert("We have detected a corruption in your save. Please visit https://discord.gg/wwQfgPa for help.")