diff --git a/css/styles.css b/css/styles.css index b0a4ac6789..a1b46268c3 100644 --- a/css/styles.css +++ b/css/styles.css @@ -168,6 +168,27 @@ a:link, a:visited { pointer-events: none; } +/* Make anchor tags ("a" elements) for activated actions */ +.a-link-button-bought { + text-decoration: none; + background-color: #00AA00; + color: #FFFFFF; + padding: 5px; + margin: 5px; + border: 1px solid #00AA00; + cursor: default; +} + +.a-link-button-bought:hover .tooltiptext, +.a-link-button-bought:hover .tooltiptexthigh, +.a-link-button-bought:hover .tooltiptextleft { + visibility: visible; +} + +.a-link-button-bought:active { + pointer-events: none; +} + /* Notification icon (for create program right now only) */ #create-program-tab { position:relative; diff --git a/dist/engine.bundle.js b/dist/engine.bundle.js index f9978a60b9..4af78711ee 100644 --- a/dist/engine.bundle.js +++ b/dist/engine.bundle.js @@ -95,8 +95,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./Server.js */ 10); /* harmony import */ var _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./SpecialServerIps.js */ 17); /* harmony import */ var _SourceFile_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./SourceFile.js */ 44); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../utils/decimal.js */ 24); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(_utils_decimal_js__WEBPACK_IMPORTED_MODULE_15__); +/* harmony import */ var decimal_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! decimal.js */ 24); /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../utils/DialogBox.js */ 7); /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1); /* harmony import */ var _utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../utils/IPAddress.js */ 16); @@ -179,9 +178,9 @@ function PlayerObject() { this.faction_rep_mult = 1; //Money - this.money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(1000); - this.total_money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(0); //Total money ever earned in this "simulation" - this.lifetime_money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(0); //Total money ever earned + this.money = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](1000); + this.total_money = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](0); //Total money ever earned in this "simulation" + this.lifetime_money = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](0); //Total money ever earned //IP Address of Starting (home) computer this.homeComputer = ""; @@ -198,6 +197,7 @@ function PlayerObject() { this.currentServer = ""; //IP address of Server currently being accessed through terminal this.purchasedServers = []; //IP Addresses of purchased servers this.hacknetNodes = []; + this.hacknetNodeWrappers = []; this.totalHacknetNodeProduction = 0; //Factions @@ -345,7 +345,7 @@ PlayerObject.prototype.prestigeAugmentation = function() { this.agility_exp = 0; this.charisma_exp = 0; - this.money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(1000); + this.money = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](1000); this.city = _Location_js__WEBPACK_IMPORTED_MODULE_10__["Locations"].Sector12; this.location = ""; @@ -426,7 +426,7 @@ PlayerObject.prototype.prestigeSourceFile = function() { this.agility_exp = 0; this.charisma_exp = 0; - this.money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(1000); + this.money = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](1000); this.city = _Location_js__WEBPACK_IMPORTED_MODULE_10__["Locations"].Sector12; this.location = ""; @@ -486,19 +486,11 @@ PlayerObject.prototype.prestigeSourceFile = function() { this.hasTixApiAccess = false; //BitNode 3: Corporatocracy - if (this.bitNodeN === 3) {this.money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(150e9);} + if (this.bitNodeN === 3) {this.money = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](150e9);} this.corporation = 0; - //Reset Bladeburner this.bladeburner = 0; - //BitNode 8: Ghost of Wall Street - if (this.bitNodeN === 8) {this.money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(100000000);} - if (this.bitNodeN === 8 || _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_11__["hasWallStreetSF"]) { - this.hasWseAccount = true; - this.hasTixApiAccess = true; - } - this.playtimeSinceLastAug = 0; this.scriptProdSinceLastAug = 0; } @@ -2453,21 +2445,21 @@ function loadPlayer(saveString) { Player = JSON.parse(saveString, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_19__["Reviver"]); //Parse Decimal.js objects - Player.money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(Player.money); - Player.total_money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(Player.total_money); - Player.lifetime_money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(Player.lifetime_money); + Player.money = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](Player.money); + Player.total_money = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](Player.total_money); + Player.lifetime_money = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](Player.lifetime_money); if (Player.corporation instanceof _CompanyManagement_js__WEBPACK_IMPORTED_MODULE_4__["Corporation"]) { - Player.corporation.funds = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(Player.corporation.funds); - Player.corporation.revenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(Player.corporation.revenue); - Player.corporation.expenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(Player.corporation.expenses); + Player.corporation.funds = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](Player.corporation.funds); + Player.corporation.revenue = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](Player.corporation.revenue); + Player.corporation.expenses = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](Player.corporation.expenses); for (var i = 0; i < Player.corporation.divisions.length; ++i) { var ind = Player.corporation.divisions[i]; - ind.lastCycleRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(ind.lastCycleRevenue); - ind.lastCycleExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(ind.lastCycleExpenses); - ind.thisCycleRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(ind.thisCycleRevenue); - ind.thisCycleExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(ind.thisCycleExpenses); + ind.lastCycleRevenue = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](ind.lastCycleRevenue); + ind.lastCycleExpenses = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](ind.lastCycleExpenses); + ind.thisCycleRevenue = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](ind.thisCycleRevenue); + ind.thisCycleExpenses = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](ind.thisCycleExpenses); } } } @@ -2957,7 +2949,7 @@ function generateRandomString(n) { __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CONSTANTS", function() { return CONSTANTS; }); let CONSTANTS = { - Version: "0.37.1", + Version: "0.37.2", //Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience //and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then @@ -3442,16 +3434,13 @@ let CONSTANTS = { "World Stock Exchange account and TIX API Access
", LatestUpdate: - "v0.37.1
" + - "* You now earn money from successfully completing Bladeburner contracts. The amount you earn is based " + - "on the difficulty of the contract.
" + - "* Completing Field Analysis in Bladeburner now grants 0.1 rank
" + - "* The maximum RAM you can get on a purchased server is now 1,048,576GB (2^20)
" + - "* Bug Fix: Fixed Netscript syntax highlighting issues with the new NetscriptJS
" + - "* Bug Fix: Netscript Functions now properly incur RAM costs in NetscriptJS
" + - "* Bug Fix: deleteServer() now fails if its called on the server you are currently connected to
" + - "* Removed in-game Netscript documentation, since it was outdated and difficult to maintain.
" + - "* Bug Fix: Updated the gymWorkout() Singularity function with the new exp/cost values for gyms
" + "v0.37.2
" + + "* After joining the Bladeburners division, there is now a button to go to the Bladeburner content " + + "in the 'City' page
" + + "* You now start with $250m in BitNode-8 (increased from $100m)
" + + "* Bug Fix: You can now no longer directly edit Hacknet Node values through NetscriptJS (hopefully)
" + + "* Bug Fix: Bladeburners is no longer accessible in BN-8
" + + "* Bug Fix: getBitNodeMultipliers() Netscript function now returns a copy rather than the original object
" } @@ -4199,6 +4188,7 @@ function displayLocationContent() { securityJob.style.display = "block"; agentJob.style.display = "block"; if (_Player_js__WEBPACK_IMPORTED_MODULE_8__["Player"].bitNodeN === 6 || _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_7__["hasBladeburnerSF"] === true) { + if (_Player_js__WEBPACK_IMPORTED_MODULE_8__["Player"].bitNodeN === 8) {break;} if (_Player_js__WEBPACK_IMPORTED_MODULE_8__["Player"].bladeburner instanceof _Bladeburner_js__WEBPACK_IMPORTED_MODULE_0__["Bladeburner"]) { //Note: Can't infiltrate NSA when part of bladeburner nsaBladeburner.innerText = "Enter Bladeburner Headquarters"; @@ -6349,6 +6339,7 @@ let Engine = { //Generic Locations (common to every city): // World Stock Exchange // Corporation (if applicable) + // Bladeburner HQ (if applicable); var genericLocationsList = document.getElementById("generic-locations-list"); genericLocationsList.style.display = "inline"; Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["removeChildrenFromElement"])(genericLocationsList); @@ -6375,6 +6366,18 @@ let Engine = { })); genericLocationsList.appendChild(li); } + + if (_Player_js__WEBPACK_IMPORTED_MODULE_26__["Player"].bladeburner instanceof _Bladeburner_js__WEBPACK_IMPORTED_MODULE_9__["Bladeburner"]) { + var li = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("li"); + li.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", { + innerText:"Bladeburner Headquarters", class:"a-link-button", + clickListener:()=>{ + Engine.loadBladeburnerContent(); + return false; + } + })); + genericLocationsList.appendChild(li); + } }, displayFactionsInfo: function() { @@ -6437,9 +6440,9 @@ let Engine = { clickListener:()=>{ Object(_Faction_js__WEBPACK_IMPORTED_MODULE_15__["joinFaction"])(_Faction_js__WEBPACK_IMPORTED_MODULE_15__["Factions"][factionName]); for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_26__["Player"].factionInvitations.length; ++i) { - if (_Player_js__WEBPACK_IMPORTED_MODULE_26__["Player"].factionInvitations[i] == factionName) { + if (_Player_js__WEBPACK_IMPORTED_MODULE_26__["Player"].factionInvitations[i] == factionName || _Faction_js__WEBPACK_IMPORTED_MODULE_15__["Factions"][_Player_js__WEBPACK_IMPORTED_MODULE_26__["Player"].factionInvitations[i]].isBanned) { _Player_js__WEBPACK_IMPORTED_MODULE_26__["Player"].factionInvitations.splice(i, 1); - break; + i--; } } Engine.displayFactionsInfo(); @@ -18856,6 +18859,9 @@ function displayStockMarketContent() { wseAccountButton.innerText = "Buy WSE Account - $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_10__["formatNumber"])(_Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].WSEAccountCost, 2).toString(); if (!_Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].hasWseAccount && _Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].money.gte(_Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].WSEAccountCost)) { wseAccountButton.setAttribute("class", "a-link-button"); + } else if (_Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].hasWseAccount){ + wseAccountButton.innerText = "WSE Account - Purchased"; + wseAccountButton.setAttribute("class", "a-link-button-bought"); } else { wseAccountButton.setAttribute("class", "a-link-button-inactive"); } @@ -18874,6 +18880,9 @@ function displayStockMarketContent() { Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_10__["formatNumber"])(_Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].TIXAPICost, 2).toString(); if (!_Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].hasTixApiAccess && _Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].money.gte(_Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].TIXAPICost)) { tixApiAccessButton.setAttribute("class", "a-link-button"); + } else if(_Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].hasTixApiAccess) { + tixApiAccessButton.innerText = "Trade Information eXchange (TIX) API Access - Purchased" + tixApiAccessButton.setAttribute("class", "a-link-button-bought"); } else { tixApiAccessButton.setAttribute("class", "a-link-button-inactive"); } @@ -19625,4807 +19634,4795 @@ function setSettingsLabels() { /***/ }), /* 24 */ -/*!**************************!*\ - !*** ./utils/decimal.js ***! - \**************************/ -/***/ (function(module, exports, __webpack_require__) { +/*!************************************************!*\ + !*** ./node_modules/decimal.js/decimal.es6.js ***! + \************************************************/ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -var __WEBPACK_AMD_DEFINE_RESULT__;/*! decimal.js v7.2.3 https://github.com/MikeMcl/decimal.js/LICENCE */ -;(function (globalScope) { - 'use strict'; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* + * + * decimal.js v7.2.3 + * An arbitrary-precision Decimal type for JavaScript. + * https://github.com/MikeMcl/decimal.js + * Copyright (c) 2017 Michael Mclaughlin + * MIT Licence + * https://github.com/MikeMcl/decimal.js/LICENCE + * + */ - /* - * decimal.js v7.2.3 - * An arbitrary-precision Decimal type for JavaScript. - * https://github.com/MikeMcl/decimal.js - * Copyright (c) 2017 Michael Mclaughlin - * MIT Licence - */ +// ----------------------------------- EDITABLE DEFAULTS ------------------------------------ // - // ----------------------------------- EDITABLE DEFAULTS ------------------------------------ // - - - // The maximum exponent magnitude. - // The limit on the value of `toExpNeg`, `toExpPos`, `minE` and `maxE`. - var EXP_LIMIT = 9e15, // 0 to 9e15 - - // The limit on the value of `precision`, and on the value of the first argument to - // `toDecimalPlaces`, `toExponential`, `toFixed`, `toPrecision` and `toSignificantDigits`. - MAX_DIGITS = 1e9, // 0 to 1e9 - - // Base conversion alphabet. - NUMERALS = '0123456789abcdef', - // The natural logarithm of 10 (1025 digits). - LN10 = '2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840422862486334095254650828067566662873690987816894829072083255546808437998948262331985283935053089653777326288461633662222876982198867465436674744042432743651550489343149393914796194044002221051017141748003688084012647080685567743216228355220114804663715659121373450747856947683463616792101806445070648000277502684916746550586856935673420670581136429224554405758925724208241314695689016758940256776311356919292033376587141660230105703089634572075440370847469940168269282808481184289314848524948644871927809676271275775397027668605952496716674183485704422507197965004714951050492214776567636938662976979522110718264549734772662425709429322582798502585509785265383207606726317164309505995087807523710333101197857547331541421808427543863591778117054309827482385045648019095610299291824318237525357709750539565187697510374970888692180205189339507238539205144634197265287286965110862571492198849978748873771345686209167058', - - // Pi (1025 digits). - PI = '3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632789', - - - // The initial configuration properties of the Decimal constructor. - Decimal = { - - // These values must be integers within the stated ranges (inclusive). - // Most of these values can be changed at run-time using the `Decimal.config` method. - - // The maximum number of significant digits of the result of a calculation or base conversion. - // E.g. `Decimal.config({ precision: 20 });` - precision: 20, // 1 to MAX_DIGITS - - // The rounding mode used when rounding to `precision`. - // - // ROUND_UP 0 Away from zero. - // ROUND_DOWN 1 Towards zero. - // ROUND_CEIL 2 Towards +Infinity. - // ROUND_FLOOR 3 Towards -Infinity. - // ROUND_HALF_UP 4 Towards nearest neighbour. If equidistant, up. - // ROUND_HALF_DOWN 5 Towards nearest neighbour. If equidistant, down. - // ROUND_HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour. - // ROUND_HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity. - // ROUND_HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity. - // - // E.g. - // `Decimal.rounding = 4;` - // `Decimal.rounding = Decimal.ROUND_HALF_UP;` - rounding: 4, // 0 to 8 - - // The modulo mode used when calculating the modulus: a mod n. - // The quotient (q = a / n) is calculated according to the corresponding rounding mode. - // The remainder (r) is calculated as: r = a - n * q. - // - // UP 0 The remainder is positive if the dividend is negative, else is negative. - // DOWN 1 The remainder has the same sign as the dividend (JavaScript %). - // FLOOR 3 The remainder has the same sign as the divisor (Python %). - // HALF_EVEN 6 The IEEE 754 remainder function. - // EUCLID 9 Euclidian division. q = sign(n) * floor(a / abs(n)). Always positive. - // - // Truncated division (1), floored division (3), the IEEE 754 remainder (6), and Euclidian - // division (9) are commonly used for the modulus operation. The other rounding modes can also - // be used, but they may not give useful results. - modulo: 1, // 0 to 9 - - // The exponent value at and beneath which `toString` returns exponential notation. - // JavaScript numbers: -7 - toExpNeg: -7, // 0 to -EXP_LIMIT - - // The exponent value at and above which `toString` returns exponential notation. - // JavaScript numbers: 21 - toExpPos: 21, // 0 to EXP_LIMIT - - // The minimum exponent value, beneath which underflow to zero occurs. - // JavaScript numbers: -324 (5e-324) - minE: -EXP_LIMIT, // -1 to -EXP_LIMIT - - // The maximum exponent value, above which overflow to Infinity occurs. - // JavaScript numbers: 308 (1.7976931348623157e+308) - maxE: EXP_LIMIT, // 1 to EXP_LIMIT - - // Whether to use cryptographically-secure random number generation, if available. - crypto: false // true/false - }, + // The maximum exponent magnitude. + // The limit on the value of `toExpNeg`, `toExpPos`, `minE` and `maxE`. +var EXP_LIMIT = 9e15, // 0 to 9e15 + + // The limit on the value of `precision`, and on the value of the first argument to + // `toDecimalPlaces`, `toExponential`, `toFixed`, `toPrecision` and `toSignificantDigits`. + MAX_DIGITS = 1e9, // 0 to 1e9 + // Base conversion alphabet. + NUMERALS = '0123456789abcdef', - // ----------------------------------- END OF EDITABLE DEFAULTS ------------------------------- // + // The natural logarithm of 10 (1025 digits). + ln10 = '2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840422862486334095254650828067566662873690987816894829072083255546808437998948262331985283935053089653777326288461633662222876982198867465436674744042432743651550489343149393914796194044002221051017141748003688084012647080685567743216228355220114804663715659121373450747856947683463616792101806445070648000277502684916746550586856935673420670581136429224554405758925724208241314695689016758940256776311356919292033376587141660230105703089634572075440370847469940168269282808481184289314848524948644871927809676271275775397027668605952496716674183485704422507197965004714951050492214776567636938662976979522110718264549734772662425709429322582798502585509785265383207606726317164309505995087807523710333101197857547331541421808427543863591778117054309827482385045648019095610299291824318237525357709750539565187697510374970888692180205189339507238539205144634197265287286965110862571492198849978748873771345686209167058', + // Pi (1025 digits). + pi = '3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632789', - inexact, noConflict, quadrant, - external = true, - decimalError = '[DecimalError] ', - invalidArgument = decimalError + 'Invalid argument: ', - precisionLimitExceeded = decimalError + 'Precision limit exceeded', - cryptoUnavailable = decimalError + 'crypto unavailable', + // The initial configuration properties of the Decimal constructor. + defaults = { - mathfloor = Math.floor, - mathpow = Math.pow, + // These values must be integers within the stated ranges (inclusive). + // Most of these values can be changed at run-time using the `Decimal.config` method. - isBinary = /^0b([01]+(\.[01]*)?|\.[01]+)(p[+-]?\d+)?$/i, - isHex = /^0x([0-9a-f]+(\.[0-9a-f]*)?|\.[0-9a-f]+)(p[+-]?\d+)?$/i, - isOctal = /^0o([0-7]+(\.[0-7]*)?|\.[0-7]+)(p[+-]?\d+)?$/i, - isDecimal = /^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i, + // The maximum number of significant digits of the result of a calculation or base conversion. + // E.g. `Decimal.config({ precision: 20 });` + precision: 20, // 1 to MAX_DIGITS - BASE = 1e7, - LOG_BASE = 7, - MAX_SAFE_INTEGER = 9007199254740991, + // The rounding mode used when rounding to `precision`. + // + // ROUND_UP 0 Away from zero. + // ROUND_DOWN 1 Towards zero. + // ROUND_CEIL 2 Towards +Infinity. + // ROUND_FLOOR 3 Towards -Infinity. + // ROUND_HALF_UP 4 Towards nearest neighbour. If equidistant, up. + // ROUND_HALF_DOWN 5 Towards nearest neighbour. If equidistant, down. + // ROUND_HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour. + // ROUND_HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity. + // ROUND_HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity. + // + // E.g. + // `Decimal.rounding = 4;` + // `Decimal.rounding = Decimal.ROUND_HALF_UP;` + rounding: 4, // 0 to 8 + + // The modulo mode used when calculating the modulus: a mod n. + // The quotient (q = a / n) is calculated according to the corresponding rounding mode. + // The remainder (r) is calculated as: r = a - n * q. + // + // UP 0 The remainder is positive if the dividend is negative, else is negative. + // DOWN 1 The remainder has the same sign as the dividend (JavaScript %). + // FLOOR 3 The remainder has the same sign as the divisor (Python %). + // HALF_EVEN 6 The IEEE 754 remainder function. + // EUCLID 9 Euclidian division. q = sign(n) * floor(a / abs(n)). Always positive. + // + // Truncated division (1), floored division (3), the IEEE 754 remainder (6), and Euclidian + // division (9) are commonly used for the modulus operation. The other rounding modes can also + // be used, but they may not give useful results. + modulo: 1, // 0 to 9 - LN10_PRECISION = LN10.length - 1, - PI_PRECISION = PI.length - 1, + // The exponent value at and beneath which `toString` returns exponential notation. + // JavaScript numbers: -7 + toExpNeg: -7, // 0 to -EXP_LIMIT - // Decimal.prototype object - P = {}; + // The exponent value at and above which `toString` returns exponential notation. + // JavaScript numbers: 21 + toExpPos: 21, // 0 to EXP_LIMIT + // The minimum exponent value, beneath which underflow to zero occurs. + // JavaScript numbers: -324 (5e-324) + minE: -EXP_LIMIT, // -1 to -EXP_LIMIT - // Decimal prototype methods + // The maximum exponent value, above which overflow to Infinity occurs. + // JavaScript numbers: 308 (1.7976931348623157e+308) + maxE: EXP_LIMIT, // 1 to EXP_LIMIT + // Whether to use cryptographically-secure random number generation, if available. + crypto: false // true/false + }, - /* - * absoluteValue abs - * ceil - * comparedTo cmp - * cosine cos - * cubeRoot cbrt - * decimalPlaces dp - * dividedBy div - * dividedToIntegerBy divToInt - * equals eq - * floor - * greaterThan gt - * greaterThanOrEqualTo gte - * hyperbolicCosine cosh - * hyperbolicSine sinh - * hyperbolicTangent tanh - * inverseCosine acos - * inverseHyperbolicCosine acosh - * inverseHyperbolicSine asinh - * inverseHyperbolicTangent atanh - * inverseSine asin - * inverseTangent atan - * isFinite - * isInteger isInt - * isNaN - * isNegative isNeg - * isPositive isPos - * isZero - * lessThan lt - * lessThanOrEqualTo lte - * logarithm log - * [maximum] [max] - * [minimum] [min] - * minus sub - * modulo mod - * naturalExponential exp - * naturalLogarithm ln - * negated neg - * plus add - * precision sd - * round - * sine sin - * squareRoot sqrt - * tangent tan - * times mul - * toBinary - * toDecimalPlaces toDP - * toExponential - * toFixed - * toFraction - * toHexadecimal toHex - * toNearest - * toNumber - * toOctal - * toPower pow - * toPrecision - * toSignificantDigits toSD - * toString - * truncated trunc - * valueOf toJSON - */ +// ----------------------------------- END OF EDITABLE DEFAULTS ------------------------------- // - /* - * Return a new Decimal whose value is the absolute value of this Decimal. - * - */ - P.absoluteValue = P.abs = function () { - var x = new this.constructor(this); - if (x.s < 0) x.s = 1; - return finalise(x); - }; + Decimal, LN10, PI, inexact, quadrant, + external = true, - /* - * Return a new Decimal whose value is the value of this Decimal rounded to a whole number in the - * direction of positive Infinity. - * - */ - P.ceil = function () { - return finalise(new this.constructor(this), this.e + 1, 2); - }; + decimalError = '[DecimalError] ', + invalidArgument = decimalError + 'Invalid argument: ', + precisionLimitExceeded = decimalError + 'Precision limit exceeded', + cryptoUnavailable = decimalError + 'crypto unavailable', + mathfloor = Math.floor, + mathpow = Math.pow, - /* - * Return - * 1 if the value of this Decimal is greater than the value of `y`, - * -1 if the value of this Decimal is less than the value of `y`, - * 0 if they have the same value, - * NaN if the value of either Decimal is NaN. - * - */ - P.comparedTo = P.cmp = function (y) { - var i, j, xdL, ydL, - x = this, - xd = x.d, - yd = (y = new x.constructor(y)).d, - xs = x.s, - ys = y.s; + isBinary = /^0b([01]+(\.[01]*)?|\.[01]+)(p[+-]?\d+)?$/i, + isHex = /^0x([0-9a-f]+(\.[0-9a-f]*)?|\.[0-9a-f]+)(p[+-]?\d+)?$/i, + isOctal = /^0o([0-7]+(\.[0-7]*)?|\.[0-7]+)(p[+-]?\d+)?$/i, + isDecimal = /^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i, - // Either NaN or ±Infinity? - if (!xd || !yd) { - return !xs || !ys ? NaN : xs !== ys ? xs : xd === yd ? 0 : !xd ^ xs < 0 ? 1 : -1; - } + BASE = 1e7, + LOG_BASE = 7, + MAX_SAFE_INTEGER = 9007199254740991, - // Either zero? - if (!xd[0] || !yd[0]) return xd[0] ? xs : yd[0] ? -ys : 0; + LN10_PRECISION = ln10.length - 1, + PI_PRECISION = pi.length - 1, - // Signs differ? - if (xs !== ys) return xs; + // Decimal.prototype object + P = {}; - // Compare exponents. - if (x.e !== y.e) return x.e > y.e ^ xs < 0 ? 1 : -1; - xdL = xd.length; - ydL = yd.length; +// Decimal prototype methods - // Compare digit by digit. - for (i = 0, j = xdL < ydL ? xdL : ydL; i < j; ++i) { - if (xd[i] !== yd[i]) return xd[i] > yd[i] ^ xs < 0 ? 1 : -1; - } - // Compare lengths. - return xdL === ydL ? 0 : xdL > ydL ^ xs < 0 ? 1 : -1; - }; +/* + * absoluteValue abs + * ceil + * comparedTo cmp + * cosine cos + * cubeRoot cbrt + * decimalPlaces dp + * dividedBy div + * dividedToIntegerBy divToInt + * equals eq + * floor + * greaterThan gt + * greaterThanOrEqualTo gte + * hyperbolicCosine cosh + * hyperbolicSine sinh + * hyperbolicTangent tanh + * inverseCosine acos + * inverseHyperbolicCosine acosh + * inverseHyperbolicSine asinh + * inverseHyperbolicTangent atanh + * inverseSine asin + * inverseTangent atan + * isFinite + * isInteger isInt + * isNaN + * isNegative isNeg + * isPositive isPos + * isZero + * lessThan lt + * lessThanOrEqualTo lte + * logarithm log + * [maximum] [max] + * [minimum] [min] + * minus sub + * modulo mod + * naturalExponential exp + * naturalLogarithm ln + * negated neg + * plus add + * precision sd + * round + * sine sin + * squareRoot sqrt + * tangent tan + * times mul + * toBinary + * toDecimalPlaces toDP + * toExponential + * toFixed + * toFraction + * toHexadecimal toHex + * toNearest + * toNumber + * toOctal + * toPower pow + * toPrecision + * toSignificantDigits toSD + * toString + * truncated trunc + * valueOf toJSON + */ - /* - * Return a new Decimal whose value is the cosine of the value in radians of this Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-1, 1] - * - * cos(0) = 1 - * cos(-0) = 1 - * cos(Infinity) = NaN - * cos(-Infinity) = NaN - * cos(NaN) = NaN - * - */ - P.cosine = P.cos = function () { - var pr, rm, - x = this, - Ctor = x.constructor; +/* + * Return a new Decimal whose value is the absolute value of this Decimal. + * + */ +P.absoluteValue = P.abs = function () { + var x = new this.constructor(this); + if (x.s < 0) x.s = 1; + return finalise(x); +}; - if (!x.d) return new Ctor(NaN); - // cos(0) = cos(-0) = 1 - if (!x.d[0]) return new Ctor(1); +/* + * Return a new Decimal whose value is the value of this Decimal rounded to a whole number in the + * direction of positive Infinity. + * + */ +P.ceil = function () { + return finalise(new this.constructor(this), this.e + 1, 2); +}; - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + Math.max(x.e, x.sd()) + LOG_BASE; - Ctor.rounding = 1; - x = cosine(Ctor, toLessThanHalfPi(Ctor, x)); +/* + * Return + * 1 if the value of this Decimal is greater than the value of `y`, + * -1 if the value of this Decimal is less than the value of `y`, + * 0 if they have the same value, + * NaN if the value of either Decimal is NaN. + * + */ +P.comparedTo = P.cmp = function (y) { + var i, j, xdL, ydL, + x = this, + xd = x.d, + yd = (y = new x.constructor(y)).d, + xs = x.s, + ys = y.s; - Ctor.precision = pr; - Ctor.rounding = rm; + // Either NaN or ±Infinity? + if (!xd || !yd) { + return !xs || !ys ? NaN : xs !== ys ? xs : xd === yd ? 0 : !xd ^ xs < 0 ? 1 : -1; + } - return finalise(quadrant == 2 || quadrant == 3 ? x.neg() : x, pr, rm, true); - }; + // Either zero? + if (!xd[0] || !yd[0]) return xd[0] ? xs : yd[0] ? -ys : 0; + // Signs differ? + if (xs !== ys) return xs; - /* - * - * Return a new Decimal whose value is the cube root of the value of this Decimal, rounded to - * `precision` significant digits using rounding mode `rounding`. - * - * cbrt(0) = 0 - * cbrt(-0) = -0 - * cbrt(1) = 1 - * cbrt(-1) = -1 - * cbrt(N) = N - * cbrt(-I) = -I - * cbrt(I) = I - * - * Math.cbrt(x) = (x < 0 ? -Math.pow(-x, 1/3) : Math.pow(x, 1/3)) - * - */ - P.cubeRoot = P.cbrt = function () { - var e, m, n, r, rep, s, sd, t, t3, t3plusx, - x = this, - Ctor = x.constructor; + // Compare exponents. + if (x.e !== y.e) return x.e > y.e ^ xs < 0 ? 1 : -1; - if (!x.isFinite() || x.isZero()) return new Ctor(x); - external = false; + xdL = xd.length; + ydL = yd.length; - // Initial estimate. - s = x.s * Math.pow(x.s * x, 1 / 3); + // Compare digit by digit. + for (i = 0, j = xdL < ydL ? xdL : ydL; i < j; ++i) { + if (xd[i] !== yd[i]) return xd[i] > yd[i] ^ xs < 0 ? 1 : -1; + } - // Math.cbrt underflow/overflow? - // Pass x to Math.pow as integer, then adjust the exponent of the result. - if (!s || Math.abs(s) == 1 / 0) { - n = digitsToString(x.d); - e = x.e; + // Compare lengths. + return xdL === ydL ? 0 : xdL > ydL ^ xs < 0 ? 1 : -1; +}; - // Adjust n exponent so it is a multiple of 3 away from x exponent. - if (s = (e - n.length + 1) % 3) n += (s == 1 || s == -2 ? '0' : '00'); - s = Math.pow(n, 1 / 3); - // Rarely, e may be one less than the result exponent value. - e = mathfloor((e + 1) / 3) - (e % 3 == (e < 0 ? -1 : 2)); +/* + * Return a new Decimal whose value is the cosine of the value in radians of this Decimal. + * + * Domain: [-Infinity, Infinity] + * Range: [-1, 1] + * + * cos(0) = 1 + * cos(-0) = 1 + * cos(Infinity) = NaN + * cos(-Infinity) = NaN + * cos(NaN) = NaN + * + */ +P.cosine = P.cos = function () { + var pr, rm, + x = this, + Ctor = x.constructor; - if (s == 1 / 0) { - n = '5e' + e; - } else { - n = s.toExponential(); - n = n.slice(0, n.indexOf('e') + 1) + e; - } + if (!x.d) return new Ctor(NaN); - r = new Ctor(n); - r.s = x.s; - } else { - r = new Ctor(s.toString()); - } + // cos(0) = cos(-0) = 1 + if (!x.d[0]) return new Ctor(1); - sd = (e = Ctor.precision) + 3; + pr = Ctor.precision; + rm = Ctor.rounding; + Ctor.precision = pr + Math.max(x.e, x.sd()) + LOG_BASE; + Ctor.rounding = 1; - // Halley's method. - // TODO? Compare Newton's method. - for (;;) { - t = r; - t3 = t.times(t).times(t); - t3plusx = t3.plus(x); - r = divide(t3plusx.plus(x).times(t), t3plusx.plus(t3), sd + 2, 1); + x = cosine(Ctor, toLessThanHalfPi(Ctor, x)); - // TODO? Replace with for-loop and checkRoundingDigits. - if (digitsToString(t.d).slice(0, sd) === (n = digitsToString(r.d)).slice(0, sd)) { - n = n.slice(sd - 3, sd + 1); + Ctor.precision = pr; + Ctor.rounding = rm; - // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or 4999 - // , i.e. approaching a rounding boundary, continue the iteration. - if (n == '9999' || !rep && n == '4999') { + return finalise(quadrant == 2 || quadrant == 3 ? x.neg() : x, pr, rm, true); +}; - // On the first iteration only, check to see if rounding up gives the exact result as the - // nines may infinitely repeat. - if (!rep) { - finalise(t, e + 1, 0); - if (t.times(t).times(t).eq(x)) { - r = t; - break; - } - } +/* + * + * Return a new Decimal whose value is the cube root of the value of this Decimal, rounded to + * `precision` significant digits using rounding mode `rounding`. + * + * cbrt(0) = 0 + * cbrt(-0) = -0 + * cbrt(1) = 1 + * cbrt(-1) = -1 + * cbrt(N) = N + * cbrt(-I) = -I + * cbrt(I) = I + * + * Math.cbrt(x) = (x < 0 ? -Math.pow(-x, 1/3) : Math.pow(x, 1/3)) + * + */ +P.cubeRoot = P.cbrt = function () { + var e, m, n, r, rep, s, sd, t, t3, t3plusx, + x = this, + Ctor = x.constructor; - sd += 4; - rep = 1; - } else { + if (!x.isFinite() || x.isZero()) return new Ctor(x); + external = false; - // If the rounding digits are null, 0{0,4} or 50{0,3}, check for an exact result. - // If not, then there are further digits and m will be truthy. - if (!+n || !+n.slice(1) && n.charAt(0) == '5') { + // Initial estimate. + s = x.s * Math.pow(x.s * x, 1 / 3); - // Truncate to the first rounding digit. - finalise(r, e + 1, 1); - m = !r.times(r).times(r).eq(x); - } + // Math.cbrt underflow/overflow? + // Pass x to Math.pow as integer, then adjust the exponent of the result. + if (!s || Math.abs(s) == 1 / 0) { + n = digitsToString(x.d); + e = x.e; - break; - } - } + // Adjust n exponent so it is a multiple of 3 away from x exponent. + if (s = (e - n.length + 1) % 3) n += (s == 1 || s == -2 ? '0' : '00'); + s = Math.pow(n, 1 / 3); + + // Rarely, e may be one less than the result exponent value. + e = mathfloor((e + 1) / 3) - (e % 3 == (e < 0 ? -1 : 2)); + + if (s == 1 / 0) { + n = '5e' + e; + } else { + n = s.toExponential(); + n = n.slice(0, n.indexOf('e') + 1) + e; } - external = true; + r = new Ctor(n); + r.s = x.s; + } else { + r = new Ctor(s.toString()); + } - return finalise(r, e, Ctor.rounding, m); - }; + sd = (e = Ctor.precision) + 3; + // Halley's method. + // TODO? Compare Newton's method. + for (;;) { + t = r; + t3 = t.times(t).times(t); + t3plusx = t3.plus(x); + r = divide(t3plusx.plus(x).times(t), t3plusx.plus(t3), sd + 2, 1); + + // TODO? Replace with for-loop and checkRoundingDigits. + if (digitsToString(t.d).slice(0, sd) === (n = digitsToString(r.d)).slice(0, sd)) { + n = n.slice(sd - 3, sd + 1); + + // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or 4999 + // , i.e. approaching a rounding boundary, continue the iteration. + if (n == '9999' || !rep && n == '4999') { + + // On the first iteration only, check to see if rounding up gives the exact result as the + // nines may infinitely repeat. + if (!rep) { + finalise(t, e + 1, 0); + + if (t.times(t).times(t).eq(x)) { + r = t; + break; + } + } - /* - * Return the number of decimal places of the value of this Decimal. - * - */ - P.decimalPlaces = P.dp = function () { - var w, - d = this.d, - n = NaN; + sd += 4; + rep = 1; + } else { - if (d) { - w = d.length - 1; - n = (w - mathfloor(this.e / LOG_BASE)) * LOG_BASE; + // If the rounding digits are null, 0{0,4} or 50{0,3}, check for an exact result. + // If not, then there are further digits and m will be truthy. + if (!+n || !+n.slice(1) && n.charAt(0) == '5') { - // Subtract the number of trailing zeros of the last word. - w = d[w]; - if (w) for (; w % 10 == 0; w /= 10) n--; - if (n < 0) n = 0; + // Truncate to the first rounding digit. + finalise(r, e + 1, 1); + m = !r.times(r).times(r).eq(x); + } + + break; + } } + } - return n; - }; + external = true; + return finalise(r, e, Ctor.rounding, m); +}; - /* - * n / 0 = I - * n / N = N - * n / I = 0 - * 0 / n = 0 - * 0 / 0 = N - * 0 / N = N - * 0 / I = 0 - * N / n = N - * N / 0 = N - * N / N = N - * N / I = N - * I / n = I - * I / 0 = I - * I / N = N - * I / I = N - * - * Return a new Decimal whose value is the value of this Decimal divided by `y`, rounded to - * `precision` significant digits using rounding mode `rounding`. - * - */ - P.dividedBy = P.div = function (y) { - return divide(this, new this.constructor(y)); - }; +/* + * Return the number of decimal places of the value of this Decimal. + * + */ +P.decimalPlaces = P.dp = function () { + var w, + d = this.d, + n = NaN; - /* - * Return a new Decimal whose value is the integer part of dividing the value of this Decimal - * by the value of `y`, rounded to `precision` significant digits using rounding mode `rounding`. - * - */ - P.dividedToIntegerBy = P.divToInt = function (y) { - var x = this, - Ctor = x.constructor; - return finalise(divide(x, new Ctor(y), 0, 1, 1), Ctor.precision, Ctor.rounding); - }; + if (d) { + w = d.length - 1; + n = (w - mathfloor(this.e / LOG_BASE)) * LOG_BASE; + // Subtract the number of trailing zeros of the last word. + w = d[w]; + if (w) for (; w % 10 == 0; w /= 10) n--; + if (n < 0) n = 0; + } - /* - * Return true if the value of this Decimal is equal to the value of `y`, otherwise return false. - * - */ - P.equals = P.eq = function (y) { - return this.cmp(y) === 0; - }; + return n; +}; - /* - * Return a new Decimal whose value is the value of this Decimal rounded to a whole number in the - * direction of negative Infinity. - * - */ - P.floor = function () { - return finalise(new this.constructor(this), this.e + 1, 3); - }; +/* + * n / 0 = I + * n / N = N + * n / I = 0 + * 0 / n = 0 + * 0 / 0 = N + * 0 / N = N + * 0 / I = 0 + * N / n = N + * N / 0 = N + * N / N = N + * N / I = N + * I / n = I + * I / 0 = I + * I / N = N + * I / I = N + * + * Return a new Decimal whose value is the value of this Decimal divided by `y`, rounded to + * `precision` significant digits using rounding mode `rounding`. + * + */ +P.dividedBy = P.div = function (y) { + return divide(this, new this.constructor(y)); +}; - /* - * Return true if the value of this Decimal is greater than the value of `y`, otherwise return - * false. - * - */ - P.greaterThan = P.gt = function (y) { - return this.cmp(y) > 0; - }; +/* + * Return a new Decimal whose value is the integer part of dividing the value of this Decimal + * by the value of `y`, rounded to `precision` significant digits using rounding mode `rounding`. + * + */ +P.dividedToIntegerBy = P.divToInt = function (y) { + var x = this, + Ctor = x.constructor; + return finalise(divide(x, new Ctor(y), 0, 1, 1), Ctor.precision, Ctor.rounding); +}; - /* - * Return true if the value of this Decimal is greater than or equal to the value of `y`, - * otherwise return false. - * - */ - P.greaterThanOrEqualTo = P.gte = function (y) { - var k = this.cmp(y); - return k == 1 || k === 0; - }; +/* + * Return true if the value of this Decimal is equal to the value of `y`, otherwise return false. + * + */ +P.equals = P.eq = function (y) { + return this.cmp(y) === 0; +}; - /* - * Return a new Decimal whose value is the hyperbolic cosine of the value in radians of this - * Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [1, Infinity] - * - * cosh(x) = 1 + x^2/2! + x^4/4! + x^6/6! + ... - * - * cosh(0) = 1 - * cosh(-0) = 1 - * cosh(Infinity) = Infinity - * cosh(-Infinity) = Infinity - * cosh(NaN) = NaN - * - * x time taken (ms) result - * 1000 9 9.8503555700852349694e+433 - * 10000 25 4.4034091128314607936e+4342 - * 100000 171 1.4033316802130615897e+43429 - * 1000000 3817 1.5166076984010437725e+434294 - * 10000000 abandoned after 2 minute wait - * - * TODO? Compare performance of cosh(x) = 0.5 * (exp(x) + exp(-x)) - * - */ - P.hyperbolicCosine = P.cosh = function () { - var k, n, pr, rm, len, - x = this, - Ctor = x.constructor, - one = new Ctor(1); +/* + * Return a new Decimal whose value is the value of this Decimal rounded to a whole number in the + * direction of negative Infinity. + * + */ +P.floor = function () { + return finalise(new this.constructor(this), this.e + 1, 3); +}; - if (!x.isFinite()) return new Ctor(x.s ? 1 / 0 : NaN); - if (x.isZero()) return one; - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + Math.max(x.e, x.sd()) + 4; - Ctor.rounding = 1; - len = x.d.length; +/* + * Return true if the value of this Decimal is greater than the value of `y`, otherwise return + * false. + * + */ +P.greaterThan = P.gt = function (y) { + return this.cmp(y) > 0; +}; - // Argument reduction: cos(4x) = 1 - 8cos^2(x) + 8cos^4(x) + 1 - // i.e. cos(x) = 1 - cos^2(x/4)(8 - 8cos^2(x/4)) - // Estimate the optimum number of times to use the argument reduction. - // TODO? Estimation reused from cosine() and may not be optimal here. - if (len < 32) { - k = Math.ceil(len / 3); - n = Math.pow(4, -k).toString(); - } else { - k = 16; - n = '2.3283064365386962890625e-10'; - } +/* + * Return true if the value of this Decimal is greater than or equal to the value of `y`, + * otherwise return false. + * + */ +P.greaterThanOrEqualTo = P.gte = function (y) { + var k = this.cmp(y); + return k == 1 || k === 0; +}; - x = taylorSeries(Ctor, 1, x.times(n), new Ctor(1), true); - // Reverse argument reduction - var cosh2_x, - i = k, - d8 = new Ctor(8); - for (; i--;) { - cosh2_x = x.times(x); - x = one.minus(cosh2_x.times(d8.minus(cosh2_x.times(d8)))); - } +/* + * Return a new Decimal whose value is the hyperbolic cosine of the value in radians of this + * Decimal. + * + * Domain: [-Infinity, Infinity] + * Range: [1, Infinity] + * + * cosh(x) = 1 + x^2/2! + x^4/4! + x^6/6! + ... + * + * cosh(0) = 1 + * cosh(-0) = 1 + * cosh(Infinity) = Infinity + * cosh(-Infinity) = Infinity + * cosh(NaN) = NaN + * + * x time taken (ms) result + * 1000 9 9.8503555700852349694e+433 + * 10000 25 4.4034091128314607936e+4342 + * 100000 171 1.4033316802130615897e+43429 + * 1000000 3817 1.5166076984010437725e+434294 + * 10000000 abandoned after 2 minute wait + * + * TODO? Compare performance of cosh(x) = 0.5 * (exp(x) + exp(-x)) + * + */ +P.hyperbolicCosine = P.cosh = function () { + var k, n, pr, rm, len, + x = this, + Ctor = x.constructor, + one = new Ctor(1); + + if (!x.isFinite()) return new Ctor(x.s ? 1 / 0 : NaN); + if (x.isZero()) return one; + + pr = Ctor.precision; + rm = Ctor.rounding; + Ctor.precision = pr + Math.max(x.e, x.sd()) + 4; + Ctor.rounding = 1; + len = x.d.length; + + // Argument reduction: cos(4x) = 1 - 8cos^2(x) + 8cos^4(x) + 1 + // i.e. cos(x) = 1 - cos^2(x/4)(8 - 8cos^2(x/4)) + + // Estimate the optimum number of times to use the argument reduction. + // TODO? Estimation reused from cosine() and may not be optimal here. + if (len < 32) { + k = Math.ceil(len / 3); + n = Math.pow(4, -k).toString(); + } else { + k = 16; + n = '2.3283064365386962890625e-10'; + } - return finalise(x, Ctor.precision = pr, Ctor.rounding = rm, true); - }; + x = taylorSeries(Ctor, 1, x.times(n), new Ctor(1), true); + // Reverse argument reduction + var cosh2_x, + i = k, + d8 = new Ctor(8); + for (; i--;) { + cosh2_x = x.times(x); + x = one.minus(cosh2_x.times(d8.minus(cosh2_x.times(d8)))); + } - /* - * Return a new Decimal whose value is the hyperbolic sine of the value in radians of this - * Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-Infinity, Infinity] - * - * sinh(x) = x + x^3/3! + x^5/5! + x^7/7! + ... - * - * sinh(0) = 0 - * sinh(-0) = -0 - * sinh(Infinity) = Infinity - * sinh(-Infinity) = -Infinity - * sinh(NaN) = NaN - * - * x time taken (ms) - * 10 2 ms - * 100 5 ms - * 1000 14 ms - * 10000 82 ms - * 100000 886 ms 1.4033316802130615897e+43429 - * 200000 2613 ms - * 300000 5407 ms - * 400000 8824 ms - * 500000 13026 ms 8.7080643612718084129e+217146 - * 1000000 48543 ms - * - * TODO? Compare performance of sinh(x) = 0.5 * (exp(x) - exp(-x)) - * - */ - P.hyperbolicSine = P.sinh = function () { - var k, pr, rm, len, - x = this, - Ctor = x.constructor; + return finalise(x, Ctor.precision = pr, Ctor.rounding = rm, true); +}; - if (!x.isFinite() || x.isZero()) return new Ctor(x); - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + Math.max(x.e, x.sd()) + 4; - Ctor.rounding = 1; - len = x.d.length; +/* + * Return a new Decimal whose value is the hyperbolic sine of the value in radians of this + * Decimal. + * + * Domain: [-Infinity, Infinity] + * Range: [-Infinity, Infinity] + * + * sinh(x) = x + x^3/3! + x^5/5! + x^7/7! + ... + * + * sinh(0) = 0 + * sinh(-0) = -0 + * sinh(Infinity) = Infinity + * sinh(-Infinity) = -Infinity + * sinh(NaN) = NaN + * + * x time taken (ms) + * 10 2 ms + * 100 5 ms + * 1000 14 ms + * 10000 82 ms + * 100000 886 ms 1.4033316802130615897e+43429 + * 200000 2613 ms + * 300000 5407 ms + * 400000 8824 ms + * 500000 13026 ms 8.7080643612718084129e+217146 + * 1000000 48543 ms + * + * TODO? Compare performance of sinh(x) = 0.5 * (exp(x) - exp(-x)) + * + */ +P.hyperbolicSine = P.sinh = function () { + var k, pr, rm, len, + x = this, + Ctor = x.constructor; - if (len < 3) { - x = taylorSeries(Ctor, 2, x, x, true); - } else { + if (!x.isFinite() || x.isZero()) return new Ctor(x); - // Alternative argument reduction: sinh(3x) = sinh(x)(3 + 4sinh^2(x)) - // i.e. sinh(x) = sinh(x/3)(3 + 4sinh^2(x/3)) - // 3 multiplications and 1 addition + pr = Ctor.precision; + rm = Ctor.rounding; + Ctor.precision = pr + Math.max(x.e, x.sd()) + 4; + Ctor.rounding = 1; + len = x.d.length; - // Argument reduction: sinh(5x) = sinh(x)(5 + sinh^2(x)(20 + 16sinh^2(x))) - // i.e. sinh(x) = sinh(x/5)(5 + sinh^2(x/5)(20 + 16sinh^2(x/5))) - // 4 multiplications and 2 additions + if (len < 3) { + x = taylorSeries(Ctor, 2, x, x, true); + } else { - // Estimate the optimum number of times to use the argument reduction. - k = 1.4 * Math.sqrt(len); - k = k > 16 ? 16 : k | 0; + // Alternative argument reduction: sinh(3x) = sinh(x)(3 + 4sinh^2(x)) + // i.e. sinh(x) = sinh(x/3)(3 + 4sinh^2(x/3)) + // 3 multiplications and 1 addition - x = x.times(Math.pow(5, -k)); + // Argument reduction: sinh(5x) = sinh(x)(5 + sinh^2(x)(20 + 16sinh^2(x))) + // i.e. sinh(x) = sinh(x/5)(5 + sinh^2(x/5)(20 + 16sinh^2(x/5))) + // 4 multiplications and 2 additions - x = taylorSeries(Ctor, 2, x, x, true); + // Estimate the optimum number of times to use the argument reduction. + k = 1.4 * Math.sqrt(len); + k = k > 16 ? 16 : k | 0; - // Reverse argument reduction - var sinh2_x, - d5 = new Ctor(5), - d16 = new Ctor(16), - d20 = new Ctor(20); - for (; k--;) { - sinh2_x = x.times(x); - x = x.times(d5.plus(sinh2_x.times(d16.times(sinh2_x).plus(d20)))); - } - } + x = x.times(Math.pow(5, -k)); - Ctor.precision = pr; - Ctor.rounding = rm; + x = taylorSeries(Ctor, 2, x, x, true); - return finalise(x, pr, rm, true); - }; + // Reverse argument reduction + var sinh2_x, + d5 = new Ctor(5), + d16 = new Ctor(16), + d20 = new Ctor(20); + for (; k--;) { + sinh2_x = x.times(x); + x = x.times(d5.plus(sinh2_x.times(d16.times(sinh2_x).plus(d20)))); + } + } + Ctor.precision = pr; + Ctor.rounding = rm; - /* - * Return a new Decimal whose value is the hyperbolic tangent of the value in radians of this - * Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-1, 1] - * - * tanh(x) = sinh(x) / cosh(x) - * - * tanh(0) = 0 - * tanh(-0) = -0 - * tanh(Infinity) = 1 - * tanh(-Infinity) = -1 - * tanh(NaN) = NaN - * - */ - P.hyperbolicTangent = P.tanh = function () { - var pr, rm, - x = this, - Ctor = x.constructor; + return finalise(x, pr, rm, true); +}; - if (!x.isFinite()) return new Ctor(x.s); - if (x.isZero()) return new Ctor(x); - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + 7; - Ctor.rounding = 1; +/* + * Return a new Decimal whose value is the hyperbolic tangent of the value in radians of this + * Decimal. + * + * Domain: [-Infinity, Infinity] + * Range: [-1, 1] + * + * tanh(x) = sinh(x) / cosh(x) + * + * tanh(0) = 0 + * tanh(-0) = -0 + * tanh(Infinity) = 1 + * tanh(-Infinity) = -1 + * tanh(NaN) = NaN + * + */ +P.hyperbolicTangent = P.tanh = function () { + var pr, rm, + x = this, + Ctor = x.constructor; - return divide(x.sinh(), x.cosh(), Ctor.precision = pr, Ctor.rounding = rm); - }; + if (!x.isFinite()) return new Ctor(x.s); + if (x.isZero()) return new Ctor(x); + pr = Ctor.precision; + rm = Ctor.rounding; + Ctor.precision = pr + 7; + Ctor.rounding = 1; - /* - * Return a new Decimal whose value is the arccosine (inverse cosine) in radians of the value of - * this Decimal. - * - * Domain: [-1, 1] - * Range: [0, pi] - * - * acos(x) = pi/2 - asin(x) - * - * acos(0) = pi/2 - * acos(-0) = pi/2 - * acos(1) = 0 - * acos(-1) = pi - * acos(1/2) = pi/3 - * acos(-1/2) = 2*pi/3 - * acos(|x| > 1) = NaN - * acos(NaN) = NaN - * - */ - P.inverseCosine = P.acos = function () { - var halfPi, - x = this, - Ctor = x.constructor, - k = x.abs().cmp(1), - pr = Ctor.precision, - rm = Ctor.rounding; + return divide(x.sinh(), x.cosh(), Ctor.precision = pr, Ctor.rounding = rm); +}; - if (k !== -1) { - return k === 0 - // |x| is 1 - ? x.isNeg() ? getPi(Ctor, pr, rm) : new Ctor(0) - // |x| > 1 or x is NaN - : new Ctor(NaN); - } - if (x.isZero()) return getPi(Ctor, pr + 4, rm).times(0.5); +/* + * Return a new Decimal whose value is the arccosine (inverse cosine) in radians of the value of + * this Decimal. + * + * Domain: [-1, 1] + * Range: [0, pi] + * + * acos(x) = pi/2 - asin(x) + * + * acos(0) = pi/2 + * acos(-0) = pi/2 + * acos(1) = 0 + * acos(-1) = pi + * acos(1/2) = pi/3 + * acos(-1/2) = 2*pi/3 + * acos(|x| > 1) = NaN + * acos(NaN) = NaN + * + */ +P.inverseCosine = P.acos = function () { + var halfPi, + x = this, + Ctor = x.constructor, + k = x.abs().cmp(1), + pr = Ctor.precision, + rm = Ctor.rounding; - // TODO? Special case acos(0.5) = pi/3 and acos(-0.5) = 2*pi/3 + if (k !== -1) { + return k === 0 + // |x| is 1 + ? x.isNeg() ? getPi(Ctor, pr, rm) : new Ctor(0) + // |x| > 1 or x is NaN + : new Ctor(NaN); + } - Ctor.precision = pr + 6; - Ctor.rounding = 1; + if (x.isZero()) return getPi(Ctor, pr + 4, rm).times(0.5); - x = x.asin(); - halfPi = getPi(Ctor, pr + 4, rm).times(0.5); + // TODO? Special case acos(0.5) = pi/3 and acos(-0.5) = 2*pi/3 - Ctor.precision = pr; - Ctor.rounding = rm; + Ctor.precision = pr + 6; + Ctor.rounding = 1; - return halfPi.minus(x); - }; + x = x.asin(); + halfPi = getPi(Ctor, pr + 4, rm).times(0.5); + Ctor.precision = pr; + Ctor.rounding = rm; - /* - * Return a new Decimal whose value is the inverse of the hyperbolic cosine in radians of the - * value of this Decimal. - * - * Domain: [1, Infinity] - * Range: [0, Infinity] - * - * acosh(x) = ln(x + sqrt(x^2 - 1)) - * - * acosh(x < 1) = NaN - * acosh(NaN) = NaN - * acosh(Infinity) = Infinity - * acosh(-Infinity) = NaN - * acosh(0) = NaN - * acosh(-0) = NaN - * acosh(1) = 0 - * acosh(-1) = NaN - * - */ - P.inverseHyperbolicCosine = P.acosh = function () { - var pr, rm, - x = this, - Ctor = x.constructor; + return halfPi.minus(x); +}; - if (x.lte(1)) return new Ctor(x.eq(1) ? 0 : NaN); - if (!x.isFinite()) return new Ctor(x); - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + Math.max(Math.abs(x.e), x.sd()) + 4; - Ctor.rounding = 1; - external = false; +/* + * Return a new Decimal whose value is the inverse of the hyperbolic cosine in radians of the + * value of this Decimal. + * + * Domain: [1, Infinity] + * Range: [0, Infinity] + * + * acosh(x) = ln(x + sqrt(x^2 - 1)) + * + * acosh(x < 1) = NaN + * acosh(NaN) = NaN + * acosh(Infinity) = Infinity + * acosh(-Infinity) = NaN + * acosh(0) = NaN + * acosh(-0) = NaN + * acosh(1) = 0 + * acosh(-1) = NaN + * + */ +P.inverseHyperbolicCosine = P.acosh = function () { + var pr, rm, + x = this, + Ctor = x.constructor; - x = x.times(x).minus(1).sqrt().plus(x); + if (x.lte(1)) return new Ctor(x.eq(1) ? 0 : NaN); + if (!x.isFinite()) return new Ctor(x); - external = true; - Ctor.precision = pr; - Ctor.rounding = rm; + pr = Ctor.precision; + rm = Ctor.rounding; + Ctor.precision = pr + Math.max(Math.abs(x.e), x.sd()) + 4; + Ctor.rounding = 1; + external = false; - return x.ln(); - }; + x = x.times(x).minus(1).sqrt().plus(x); + external = true; + Ctor.precision = pr; + Ctor.rounding = rm; - /* - * Return a new Decimal whose value is the inverse of the hyperbolic sine in radians of the value - * of this Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-Infinity, Infinity] - * - * asinh(x) = ln(x + sqrt(x^2 + 1)) - * - * asinh(NaN) = NaN - * asinh(Infinity) = Infinity - * asinh(-Infinity) = -Infinity - * asinh(0) = 0 - * asinh(-0) = -0 - * - */ - P.inverseHyperbolicSine = P.asinh = function () { - var pr, rm, - x = this, - Ctor = x.constructor; + return x.ln(); +}; - if (!x.isFinite() || x.isZero()) return new Ctor(x); - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + 2 * Math.max(Math.abs(x.e), x.sd()) + 6; - Ctor.rounding = 1; - external = false; +/* + * Return a new Decimal whose value is the inverse of the hyperbolic sine in radians of the value + * of this Decimal. + * + * Domain: [-Infinity, Infinity] + * Range: [-Infinity, Infinity] + * + * asinh(x) = ln(x + sqrt(x^2 + 1)) + * + * asinh(NaN) = NaN + * asinh(Infinity) = Infinity + * asinh(-Infinity) = -Infinity + * asinh(0) = 0 + * asinh(-0) = -0 + * + */ +P.inverseHyperbolicSine = P.asinh = function () { + var pr, rm, + x = this, + Ctor = x.constructor; - x = x.times(x).plus(1).sqrt().plus(x); + if (!x.isFinite() || x.isZero()) return new Ctor(x); - external = true; - Ctor.precision = pr; - Ctor.rounding = rm; + pr = Ctor.precision; + rm = Ctor.rounding; + Ctor.precision = pr + 2 * Math.max(Math.abs(x.e), x.sd()) + 6; + Ctor.rounding = 1; + external = false; - return x.ln(); - }; + x = x.times(x).plus(1).sqrt().plus(x); + external = true; + Ctor.precision = pr; + Ctor.rounding = rm; - /* - * Return a new Decimal whose value is the inverse of the hyperbolic tangent in radians of the - * value of this Decimal. - * - * Domain: [-1, 1] - * Range: [-Infinity, Infinity] - * - * atanh(x) = 0.5 * ln((1 + x) / (1 - x)) - * - * atanh(|x| > 1) = NaN - * atanh(NaN) = NaN - * atanh(Infinity) = NaN - * atanh(-Infinity) = NaN - * atanh(0) = 0 - * atanh(-0) = -0 - * atanh(1) = Infinity - * atanh(-1) = -Infinity - * - */ - P.inverseHyperbolicTangent = P.atanh = function () { - var pr, rm, wpr, xsd, - x = this, - Ctor = x.constructor; + return x.ln(); +}; - if (!x.isFinite()) return new Ctor(NaN); - if (x.e >= 0) return new Ctor(x.abs().eq(1) ? x.s / 0 : x.isZero() ? x : NaN); - pr = Ctor.precision; - rm = Ctor.rounding; - xsd = x.sd(); +/* + * Return a new Decimal whose value is the inverse of the hyperbolic tangent in radians of the + * value of this Decimal. + * + * Domain: [-1, 1] + * Range: [-Infinity, Infinity] + * + * atanh(x) = 0.5 * ln((1 + x) / (1 - x)) + * + * atanh(|x| > 1) = NaN + * atanh(NaN) = NaN + * atanh(Infinity) = NaN + * atanh(-Infinity) = NaN + * atanh(0) = 0 + * atanh(-0) = -0 + * atanh(1) = Infinity + * atanh(-1) = -Infinity + * + */ +P.inverseHyperbolicTangent = P.atanh = function () { + var pr, rm, wpr, xsd, + x = this, + Ctor = x.constructor; - if (Math.max(xsd, pr) < 2 * -x.e - 1) return finalise(new Ctor(x), pr, rm, true); + if (!x.isFinite()) return new Ctor(NaN); + if (x.e >= 0) return new Ctor(x.abs().eq(1) ? x.s / 0 : x.isZero() ? x : NaN); - Ctor.precision = wpr = xsd - x.e; + pr = Ctor.precision; + rm = Ctor.rounding; + xsd = x.sd(); - x = divide(x.plus(1), new Ctor(1).minus(x), wpr + pr, 1); + if (Math.max(xsd, pr) < 2 * -x.e - 1) return finalise(new Ctor(x), pr, rm, true); - Ctor.precision = pr + 4; - Ctor.rounding = 1; + Ctor.precision = wpr = xsd - x.e; - x = x.ln(); + x = divide(x.plus(1), new Ctor(1).minus(x), wpr + pr, 1); - Ctor.precision = pr; - Ctor.rounding = rm; + Ctor.precision = pr + 4; + Ctor.rounding = 1; - return x.times(0.5); - }; + x = x.ln(); + Ctor.precision = pr; + Ctor.rounding = rm; - /* - * Return a new Decimal whose value is the arcsine (inverse sine) in radians of the value of this - * Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-pi/2, pi/2] - * - * asin(x) = 2*atan(x/(1 + sqrt(1 - x^2))) - * - * asin(0) = 0 - * asin(-0) = -0 - * asin(1/2) = pi/6 - * asin(-1/2) = -pi/6 - * asin(1) = pi/2 - * asin(-1) = -pi/2 - * asin(|x| > 1) = NaN - * asin(NaN) = NaN - * - * TODO? Compare performance of Taylor series. - * - */ - P.inverseSine = P.asin = function () { - var halfPi, k, - pr, rm, - x = this, - Ctor = x.constructor; + return x.times(0.5); +}; - if (x.isZero()) return new Ctor(x); - k = x.abs().cmp(1); - pr = Ctor.precision; - rm = Ctor.rounding; +/* + * Return a new Decimal whose value is the arcsine (inverse sine) in radians of the value of this + * Decimal. + * + * Domain: [-Infinity, Infinity] + * Range: [-pi/2, pi/2] + * + * asin(x) = 2*atan(x/(1 + sqrt(1 - x^2))) + * + * asin(0) = 0 + * asin(-0) = -0 + * asin(1/2) = pi/6 + * asin(-1/2) = -pi/6 + * asin(1) = pi/2 + * asin(-1) = -pi/2 + * asin(|x| > 1) = NaN + * asin(NaN) = NaN + * + * TODO? Compare performance of Taylor series. + * + */ +P.inverseSine = P.asin = function () { + var halfPi, k, + pr, rm, + x = this, + Ctor = x.constructor; - if (k !== -1) { + if (x.isZero()) return new Ctor(x); - // |x| is 1 - if (k === 0) { - halfPi = getPi(Ctor, pr + 4, rm).times(0.5); - halfPi.s = x.s; - return halfPi; - } + k = x.abs().cmp(1); + pr = Ctor.precision; + rm = Ctor.rounding; - // |x| > 1 or x is NaN - return new Ctor(NaN); + if (k !== -1) { + + // |x| is 1 + if (k === 0) { + halfPi = getPi(Ctor, pr + 4, rm).times(0.5); + halfPi.s = x.s; + return halfPi; } - // TODO? Special case asin(1/2) = pi/6 and asin(-1/2) = -pi/6 + // |x| > 1 or x is NaN + return new Ctor(NaN); + } - Ctor.precision = pr + 6; - Ctor.rounding = 1; + // TODO? Special case asin(1/2) = pi/6 and asin(-1/2) = -pi/6 - x = x.div(new Ctor(1).minus(x.times(x)).sqrt().plus(1)).atan(); + Ctor.precision = pr + 6; + Ctor.rounding = 1; - Ctor.precision = pr; - Ctor.rounding = rm; + x = x.div(new Ctor(1).minus(x.times(x)).sqrt().plus(1)).atan(); - return x.times(2); - }; + Ctor.precision = pr; + Ctor.rounding = rm; + return x.times(2); +}; - /* - * Return a new Decimal whose value is the arctangent (inverse tangent) in radians of the value - * of this Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-pi/2, pi/2] - * - * atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... - * - * atan(0) = 0 - * atan(-0) = -0 - * atan(1) = pi/4 - * atan(-1) = -pi/4 - * atan(Infinity) = pi/2 - * atan(-Infinity) = -pi/2 - * atan(NaN) = NaN - * - */ - P.inverseTangent = P.atan = function () { - var i, j, k, n, px, t, r, wpr, x2, - x = this, - Ctor = x.constructor, - pr = Ctor.precision, - rm = Ctor.rounding; - if (!x.isFinite()) { - if (!x.s) return new Ctor(NaN); - if (pr + 4 <= PI_PRECISION) { - r = getPi(Ctor, pr + 4, rm).times(0.5); - r.s = x.s; - return r; - } - } else if (x.isZero()) { - return new Ctor(x); - } else if (x.abs().eq(1) && pr + 4 <= PI_PRECISION) { - r = getPi(Ctor, pr + 4, rm).times(0.25); +/* + * Return a new Decimal whose value is the arctangent (inverse tangent) in radians of the value + * of this Decimal. + * + * Domain: [-Infinity, Infinity] + * Range: [-pi/2, pi/2] + * + * atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... + * + * atan(0) = 0 + * atan(-0) = -0 + * atan(1) = pi/4 + * atan(-1) = -pi/4 + * atan(Infinity) = pi/2 + * atan(-Infinity) = -pi/2 + * atan(NaN) = NaN + * + */ +P.inverseTangent = P.atan = function () { + var i, j, k, n, px, t, r, wpr, x2, + x = this, + Ctor = x.constructor, + pr = Ctor.precision, + rm = Ctor.rounding; + + if (!x.isFinite()) { + if (!x.s) return new Ctor(NaN); + if (pr + 4 <= PI_PRECISION) { + r = getPi(Ctor, pr + 4, rm).times(0.5); r.s = x.s; return r; } + } else if (x.isZero()) { + return new Ctor(x); + } else if (x.abs().eq(1) && pr + 4 <= PI_PRECISION) { + r = getPi(Ctor, pr + 4, rm).times(0.25); + r.s = x.s; + return r; + } - Ctor.precision = wpr = pr + 10; - Ctor.rounding = 1; + Ctor.precision = wpr = pr + 10; + Ctor.rounding = 1; - // TODO? if (x >= 1 && pr <= PI_PRECISION) atan(x) = halfPi * x.s - atan(1 / x); + // TODO? if (x >= 1 && pr <= PI_PRECISION) atan(x) = halfPi * x.s - atan(1 / x); - // Argument reduction - // Ensure |x| < 0.42 - // atan(x) = 2 * atan(x / (1 + sqrt(1 + x^2))) + // Argument reduction + // Ensure |x| < 0.42 + // atan(x) = 2 * atan(x / (1 + sqrt(1 + x^2))) - k = Math.min(28, wpr / LOG_BASE + 2 | 0); + k = Math.min(28, wpr / LOG_BASE + 2 | 0); - for (i = k; i; --i) x = x.div(x.times(x).plus(1).sqrt().plus(1)); + for (i = k; i; --i) x = x.div(x.times(x).plus(1).sqrt().plus(1)); - external = false; + external = false; - j = Math.ceil(wpr / LOG_BASE); - n = 1; - x2 = x.times(x); - r = new Ctor(x); - px = x; + j = Math.ceil(wpr / LOG_BASE); + n = 1; + x2 = x.times(x); + r = new Ctor(x); + px = x; - // atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... - for (; i !== -1;) { - px = px.times(x2); - t = r.minus(px.div(n += 2)); + // atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... + for (; i !== -1;) { + px = px.times(x2); + t = r.minus(px.div(n += 2)); - px = px.times(x2); - r = t.plus(px.div(n += 2)); + px = px.times(x2); + r = t.plus(px.div(n += 2)); - if (r.d[j] !== void 0) for (i = j; r.d[i] === t.d[i] && i--;); - } + if (r.d[j] !== void 0) for (i = j; r.d[i] === t.d[i] && i--;); + } - if (k) r = r.times(2 << (k - 1)); + if (k) r = r.times(2 << (k - 1)); - external = true; + external = true; - return finalise(r, Ctor.precision = pr, Ctor.rounding = rm, true); - }; + return finalise(r, Ctor.precision = pr, Ctor.rounding = rm, true); +}; - /* - * Return true if the value of this Decimal is a finite number, otherwise return false. - * - */ - P.isFinite = function () { - return !!this.d; - }; +/* + * Return true if the value of this Decimal is a finite number, otherwise return false. + * + */ +P.isFinite = function () { + return !!this.d; +}; - /* - * Return true if the value of this Decimal is an integer, otherwise return false. - * - */ - P.isInteger = P.isInt = function () { - return !!this.d && mathfloor(this.e / LOG_BASE) > this.d.length - 2; - }; +/* + * Return true if the value of this Decimal is an integer, otherwise return false. + * + */ +P.isInteger = P.isInt = function () { + return !!this.d && mathfloor(this.e / LOG_BASE) > this.d.length - 2; +}; - /* - * Return true if the value of this Decimal is NaN, otherwise return false. - * - */ - P.isNaN = function () { - return !this.s; - }; +/* + * Return true if the value of this Decimal is NaN, otherwise return false. + * + */ +P.isNaN = function () { + return !this.s; +}; - /* - * Return true if the value of this Decimal is negative, otherwise return false. - * - */ - P.isNegative = P.isNeg = function () { - return this.s < 0; - }; +/* + * Return true if the value of this Decimal is negative, otherwise return false. + * + */ +P.isNegative = P.isNeg = function () { + return this.s < 0; +}; - /* - * Return true if the value of this Decimal is positive, otherwise return false. - * - */ - P.isPositive = P.isPos = function () { - return this.s > 0; - }; +/* + * Return true if the value of this Decimal is positive, otherwise return false. + * + */ +P.isPositive = P.isPos = function () { + return this.s > 0; +}; - /* - * Return true if the value of this Decimal is 0 or -0, otherwise return false. - * - */ - P.isZero = function () { - return !!this.d && this.d[0] === 0; - }; +/* + * Return true if the value of this Decimal is 0 or -0, otherwise return false. + * + */ +P.isZero = function () { + return !!this.d && this.d[0] === 0; +}; - /* - * Return true if the value of this Decimal is less than `y`, otherwise return false. - * - */ - P.lessThan = P.lt = function (y) { - return this.cmp(y) < 0; - }; +/* + * Return true if the value of this Decimal is less than `y`, otherwise return false. + * + */ +P.lessThan = P.lt = function (y) { + return this.cmp(y) < 0; +}; - /* - * Return true if the value of this Decimal is less than or equal to `y`, otherwise return false. - * - */ - P.lessThanOrEqualTo = P.lte = function (y) { - return this.cmp(y) < 1; - }; +/* + * Return true if the value of this Decimal is less than or equal to `y`, otherwise return false. + * + */ +P.lessThanOrEqualTo = P.lte = function (y) { + return this.cmp(y) < 1; +}; - /* - * Return the logarithm of the value of this Decimal to the specified base, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * If no base is specified, return log[10](arg). - * - * log[base](arg) = ln(arg) / ln(base) - * - * The result will always be correctly rounded if the base of the log is 10, and 'almost always' - * otherwise: - * - * Depending on the rounding mode, the result may be incorrectly rounded if the first fifteen - * rounding digits are [49]99999999999999 or [50]00000000000000. In that case, the maximum error - * between the result and the correctly rounded result will be one ulp (unit in the last place). - * - * log[-b](a) = NaN - * log[0](a) = NaN - * log[1](a) = NaN - * log[NaN](a) = NaN - * log[Infinity](a) = NaN - * log[b](0) = -Infinity - * log[b](-0) = -Infinity - * log[b](-a) = NaN - * log[b](1) = 0 - * log[b](Infinity) = Infinity - * log[b](NaN) = NaN - * - * [base] {number|string|Decimal} The base of the logarithm. - * - */ - P.logarithm = P.log = function (base) { - var isBase10, d, denominator, k, inf, num, sd, r, - arg = this, - Ctor = arg.constructor, - pr = Ctor.precision, - rm = Ctor.rounding, - guard = 5; - - // Default base is 10. - if (base == null) { - base = new Ctor(10); - isBase10 = true; - } else { - base = new Ctor(base); - d = base.d; +/* + * Return the logarithm of the value of this Decimal to the specified base, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * If no base is specified, return log[10](arg). + * + * log[base](arg) = ln(arg) / ln(base) + * + * The result will always be correctly rounded if the base of the log is 10, and 'almost always' + * otherwise: + * + * Depending on the rounding mode, the result may be incorrectly rounded if the first fifteen + * rounding digits are [49]99999999999999 or [50]00000000000000. In that case, the maximum error + * between the result and the correctly rounded result will be one ulp (unit in the last place). + * + * log[-b](a) = NaN + * log[0](a) = NaN + * log[1](a) = NaN + * log[NaN](a) = NaN + * log[Infinity](a) = NaN + * log[b](0) = -Infinity + * log[b](-0) = -Infinity + * log[b](-a) = NaN + * log[b](1) = 0 + * log[b](Infinity) = Infinity + * log[b](NaN) = NaN + * + * [base] {number|string|Decimal} The base of the logarithm. + * + */ +P.logarithm = P.log = function (base) { + var isBase10, d, denominator, k, inf, num, sd, r, + arg = this, + Ctor = arg.constructor, + pr = Ctor.precision, + rm = Ctor.rounding, + guard = 5; + + // Default base is 10. + if (base == null) { + base = new Ctor(10); + isBase10 = true; + } else { + base = new Ctor(base); + d = base.d; - // Return NaN if base is negative, or non-finite, or is 0 or 1. - if (base.s < 0 || !d || !d[0] || base.eq(1)) return new Ctor(NaN); + // Return NaN if base is negative, or non-finite, or is 0 or 1. + if (base.s < 0 || !d || !d[0] || base.eq(1)) return new Ctor(NaN); - isBase10 = base.eq(10); - } + isBase10 = base.eq(10); + } - d = arg.d; + d = arg.d; - // Is arg negative, non-finite, 0 or 1? - if (arg.s < 0 || !d || !d[0] || arg.eq(1)) { - return new Ctor(d && !d[0] ? -1 / 0 : arg.s != 1 ? NaN : d ? 0 : 1 / 0); - } + // Is arg negative, non-finite, 0 or 1? + if (arg.s < 0 || !d || !d[0] || arg.eq(1)) { + return new Ctor(d && !d[0] ? -1 / 0 : arg.s != 1 ? NaN : d ? 0 : 1 / 0); + } - // The result will have a non-terminating decimal expansion if base is 10 and arg is not an - // integer power of 10. - if (isBase10) { - if (d.length > 1) { - inf = true; - } else { - for (k = d[0]; k % 10 === 0;) k /= 10; - inf = k !== 1; - } + // The result will have a non-terminating decimal expansion if base is 10 and arg is not an + // integer power of 10. + if (isBase10) { + if (d.length > 1) { + inf = true; + } else { + for (k = d[0]; k % 10 === 0;) k /= 10; + inf = k !== 1; } + } - external = false; - sd = pr + guard; - num = naturalLogarithm(arg, sd); - denominator = isBase10 ? getLn10(Ctor, sd + 10) : naturalLogarithm(base, sd); - - // The result will have 5 rounding digits. - r = divide(num, denominator, sd, 1); + external = false; + sd = pr + guard; + num = naturalLogarithm(arg, sd); + denominator = isBase10 ? getLn10(Ctor, sd + 10) : naturalLogarithm(base, sd); - // If at a rounding boundary, i.e. the result's rounding digits are [49]9999 or [50]0000, - // calculate 10 further digits. - // - // If the result is known to have an infinite decimal expansion, repeat this until it is clear - // that the result is above or below the boundary. Otherwise, if after calculating the 10 - // further digits, the last 14 are nines, round up and assume the result is exact. - // Also assume the result is exact if the last 14 are zero. - // - // Example of a result that will be incorrectly rounded: - // log[1048576](4503599627370502) = 2.60000000000000009610279511444746... - // The above result correctly rounded using ROUND_CEIL to 1 decimal place should be 2.7, but it - // will be given as 2.6 as there are 15 zeros immediately after the requested decimal place, so - // the exact result would be assumed to be 2.6, which rounded using ROUND_CEIL to 1 decimal - // place is still 2.6. - if (checkRoundingDigits(r.d, k = pr, rm)) { + // The result will have 5 rounding digits. + r = divide(num, denominator, sd, 1); - do { - sd += 10; - num = naturalLogarithm(arg, sd); - denominator = isBase10 ? getLn10(Ctor, sd + 10) : naturalLogarithm(base, sd); - r = divide(num, denominator, sd, 1); + // If at a rounding boundary, i.e. the result's rounding digits are [49]9999 or [50]0000, + // calculate 10 further digits. + // + // If the result is known to have an infinite decimal expansion, repeat this until it is clear + // that the result is above or below the boundary. Otherwise, if after calculating the 10 + // further digits, the last 14 are nines, round up and assume the result is exact. + // Also assume the result is exact if the last 14 are zero. + // + // Example of a result that will be incorrectly rounded: + // log[1048576](4503599627370502) = 2.60000000000000009610279511444746... + // The above result correctly rounded using ROUND_CEIL to 1 decimal place should be 2.7, but it + // will be given as 2.6 as there are 15 zeros immediately after the requested decimal place, so + // the exact result would be assumed to be 2.6, which rounded using ROUND_CEIL to 1 decimal + // place is still 2.6. + if (checkRoundingDigits(r.d, k = pr, rm)) { - if (!inf) { + do { + sd += 10; + num = naturalLogarithm(arg, sd); + denominator = isBase10 ? getLn10(Ctor, sd + 10) : naturalLogarithm(base, sd); + r = divide(num, denominator, sd, 1); - // Check for 14 nines from the 2nd rounding digit, as the first may be 4. - if (+digitsToString(r.d).slice(k + 1, k + 15) + 1 == 1e14) { - r = finalise(r, pr + 1, 0); - } + if (!inf) { - break; + // Check for 14 nines from the 2nd rounding digit, as the first may be 4. + if (+digitsToString(r.d).slice(k + 1, k + 15) + 1 == 1e14) { + r = finalise(r, pr + 1, 0); } - } while (checkRoundingDigits(r.d, k += 10, rm)); - } - external = true; + break; + } + } while (checkRoundingDigits(r.d, k += 10, rm)); + } - return finalise(r, pr, rm); - }; + external = true; + return finalise(r, pr, rm); +}; - /* - * Return a new Decimal whose value is the maximum of the arguments and the value of this Decimal. - * - * arguments {number|string|Decimal} - * - P.max = function () { - Array.prototype.push.call(arguments, this); - return maxOrMin(this.constructor, arguments, 'lt'); - }; - */ +/* + * Return a new Decimal whose value is the maximum of the arguments and the value of this Decimal. + * + * arguments {number|string|Decimal} + * +P.max = function () { + Array.prototype.push.call(arguments, this); + return maxOrMin(this.constructor, arguments, 'lt'); +}; + */ - /* - * Return a new Decimal whose value is the minimum of the arguments and the value of this Decimal. - * - * arguments {number|string|Decimal} - * - P.min = function () { - Array.prototype.push.call(arguments, this); - return maxOrMin(this.constructor, arguments, 'gt'); - }; - */ +/* + * Return a new Decimal whose value is the minimum of the arguments and the value of this Decimal. + * + * arguments {number|string|Decimal} + * +P.min = function () { + Array.prototype.push.call(arguments, this); + return maxOrMin(this.constructor, arguments, 'gt'); +}; + */ - /* - * n - 0 = n - * n - N = N - * n - I = -I - * 0 - n = -n - * 0 - 0 = 0 - * 0 - N = N - * 0 - I = -I - * N - n = N - * N - 0 = N - * N - N = N - * N - I = N - * I - n = I - * I - 0 = I - * I - N = N - * I - I = N - * - * Return a new Decimal whose value is the value of this Decimal minus `y`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - */ - P.minus = P.sub = function (y) { - var d, e, i, j, k, len, pr, rm, xd, xe, xLTy, yd, - x = this, - Ctor = x.constructor; - y = new Ctor(y); +/* + * n - 0 = n + * n - N = N + * n - I = -I + * 0 - n = -n + * 0 - 0 = 0 + * 0 - N = N + * 0 - I = -I + * N - n = N + * N - 0 = N + * N - N = N + * N - I = N + * I - n = I + * I - 0 = I + * I - N = N + * I - I = N + * + * Return a new Decimal whose value is the value of this Decimal minus `y`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + */ +P.minus = P.sub = function (y) { + var d, e, i, j, k, len, pr, rm, xd, xe, xLTy, yd, + x = this, + Ctor = x.constructor; - // If either is not finite... - if (!x.d || !y.d) { + y = new Ctor(y); - // Return NaN if either is NaN. - if (!x.s || !y.s) y = new Ctor(NaN); + // If either is not finite... + if (!x.d || !y.d) { - // Return y negated if x is finite and y is ±Infinity. - else if (x.d) y.s = -y.s; + // Return NaN if either is NaN. + if (!x.s || !y.s) y = new Ctor(NaN); - // Return x if y is finite and x is ±Infinity. - // Return x if both are ±Infinity with different signs. - // Return NaN if both are ±Infinity with the same sign. - else y = new Ctor(y.d || x.s !== y.s ? x : NaN); + // Return y negated if x is finite and y is ±Infinity. + else if (x.d) y.s = -y.s; - return y; - } + // Return x if y is finite and x is ±Infinity. + // Return x if both are ±Infinity with different signs. + // Return NaN if both are ±Infinity with the same sign. + else y = new Ctor(y.d || x.s !== y.s ? x : NaN); - // If signs differ... - if (x.s != y.s) { - y.s = -y.s; - return x.plus(y); - } + return y; + } - xd = x.d; - yd = y.d; - pr = Ctor.precision; - rm = Ctor.rounding; + // If signs differ... + if (x.s != y.s) { + y.s = -y.s; + return x.plus(y); + } - // If either is zero... - if (!xd[0] || !yd[0]) { + xd = x.d; + yd = y.d; + pr = Ctor.precision; + rm = Ctor.rounding; - // Return y negated if x is zero and y is non-zero. - if (yd[0]) y.s = -y.s; + // If either is zero... + if (!xd[0] || !yd[0]) { - // Return x if y is zero and x is non-zero. - else if (xd[0]) y = new Ctor(x); + // Return y negated if x is zero and y is non-zero. + if (yd[0]) y.s = -y.s; - // Return zero if both are zero. - // From IEEE 754 (2008) 6.3: 0 - 0 = -0 - -0 = -0 when rounding to -Infinity. - else return new Ctor(rm === 3 ? -0 : 0); + // Return x if y is zero and x is non-zero. + else if (xd[0]) y = new Ctor(x); - return external ? finalise(y, pr, rm) : y; - } + // Return zero if both are zero. + // From IEEE 754 (2008) 6.3: 0 - 0 = -0 - -0 = -0 when rounding to -Infinity. + else return new Ctor(rm === 3 ? -0 : 0); - // x and y are finite, non-zero numbers with the same sign. + return external ? finalise(y, pr, rm) : y; + } - // Calculate base 1e7 exponents. - e = mathfloor(y.e / LOG_BASE); - xe = mathfloor(x.e / LOG_BASE); + // x and y are finite, non-zero numbers with the same sign. - xd = xd.slice(); - k = xe - e; + // Calculate base 1e7 exponents. + e = mathfloor(y.e / LOG_BASE); + xe = mathfloor(x.e / LOG_BASE); - // If base 1e7 exponents differ... - if (k) { - xLTy = k < 0; + xd = xd.slice(); + k = xe - e; - if (xLTy) { - d = xd; - k = -k; - len = yd.length; - } else { - d = yd; - e = xe; - len = xd.length; - } + // If base 1e7 exponents differ... + if (k) { + xLTy = k < 0; - // Numbers with massively different exponents would result in a very high number of - // zeros needing to be prepended, but this can be avoided while still ensuring correct - // rounding by limiting the number of zeros to `Math.ceil(pr / LOG_BASE) + 2`. - i = Math.max(Math.ceil(pr / LOG_BASE), len) + 2; + if (xLTy) { + d = xd; + k = -k; + len = yd.length; + } else { + d = yd; + e = xe; + len = xd.length; + } - if (k > i) { - k = i; - d.length = 1; - } + // Numbers with massively different exponents would result in a very high number of + // zeros needing to be prepended, but this can be avoided while still ensuring correct + // rounding by limiting the number of zeros to `Math.ceil(pr / LOG_BASE) + 2`. + i = Math.max(Math.ceil(pr / LOG_BASE), len) + 2; - // Prepend zeros to equalise exponents. - d.reverse(); - for (i = k; i--;) d.push(0); - d.reverse(); + if (k > i) { + k = i; + d.length = 1; + } - // Base 1e7 exponents equal. - } else { + // Prepend zeros to equalise exponents. + d.reverse(); + for (i = k; i--;) d.push(0); + d.reverse(); - // Check digits to determine which is the bigger number. + // Base 1e7 exponents equal. + } else { - i = xd.length; - len = yd.length; - xLTy = i < len; - if (xLTy) len = i; + // Check digits to determine which is the bigger number. - for (i = 0; i < len; i++) { - if (xd[i] != yd[i]) { - xLTy = xd[i] < yd[i]; - break; - } - } + i = xd.length; + len = yd.length; + xLTy = i < len; + if (xLTy) len = i; - k = 0; + for (i = 0; i < len; i++) { + if (xd[i] != yd[i]) { + xLTy = xd[i] < yd[i]; + break; + } } - if (xLTy) { - d = xd; - xd = yd; - yd = d; - y.s = -y.s; - } + k = 0; + } - len = xd.length; + if (xLTy) { + d = xd; + xd = yd; + yd = d; + y.s = -y.s; + } - // Append zeros to `xd` if shorter. - // Don't add zeros to `yd` if shorter as subtraction only needs to start at `yd` length. - for (i = yd.length - len; i > 0; --i) xd[len++] = 0; + len = xd.length; - // Subtract yd from xd. - for (i = yd.length; i > k;) { + // Append zeros to `xd` if shorter. + // Don't add zeros to `yd` if shorter as subtraction only needs to start at `yd` length. + for (i = yd.length - len; i > 0; --i) xd[len++] = 0; - if (xd[--i] < yd[i]) { - for (j = i; j && xd[--j] === 0;) xd[j] = BASE - 1; - --xd[j]; - xd[i] += BASE; - } + // Subtract yd from xd. + for (i = yd.length; i > k;) { - xd[i] -= yd[i]; + if (xd[--i] < yd[i]) { + for (j = i; j && xd[--j] === 0;) xd[j] = BASE - 1; + --xd[j]; + xd[i] += BASE; } - // Remove trailing zeros. - for (; xd[--len] === 0;) xd.pop(); - - // Remove leading zeros and adjust exponent accordingly. - for (; xd[0] === 0; xd.shift()) --e; + xd[i] -= yd[i]; + } - // Zero? - if (!xd[0]) return new Ctor(rm === 3 ? -0 : 0); + // Remove trailing zeros. + for (; xd[--len] === 0;) xd.pop(); - y.d = xd; - y.e = getBase10Exponent(xd, e); + // Remove leading zeros and adjust exponent accordingly. + for (; xd[0] === 0; xd.shift()) --e; - return external ? finalise(y, pr, rm) : y; - }; + // Zero? + if (!xd[0]) return new Ctor(rm === 3 ? -0 : 0); + y.d = xd; + y.e = getBase10Exponent(xd, e); - /* - * n % 0 = N - * n % N = N - * n % I = n - * 0 % n = 0 - * -0 % n = -0 - * 0 % 0 = N - * 0 % N = N - * 0 % I = 0 - * N % n = N - * N % 0 = N - * N % N = N - * N % I = N - * I % n = N - * I % 0 = N - * I % N = N - * I % I = N - * - * Return a new Decimal whose value is the value of this Decimal modulo `y`, rounded to - * `precision` significant digits using rounding mode `rounding`. - * - * The result depends on the modulo mode. - * - */ - P.modulo = P.mod = function (y) { - var q, - x = this, - Ctor = x.constructor; - - y = new Ctor(y); + return external ? finalise(y, pr, rm) : y; +}; - // Return NaN if x is ±Infinity or NaN, or y is NaN or ±0. - if (!x.d || !y.s || y.d && !y.d[0]) return new Ctor(NaN); - // Return x if y is ±Infinity or x is ±0. - if (!y.d || x.d && !x.d[0]) { - return finalise(new Ctor(x), Ctor.precision, Ctor.rounding); - } +/* + * n % 0 = N + * n % N = N + * n % I = n + * 0 % n = 0 + * -0 % n = -0 + * 0 % 0 = N + * 0 % N = N + * 0 % I = 0 + * N % n = N + * N % 0 = N + * N % N = N + * N % I = N + * I % n = N + * I % 0 = N + * I % N = N + * I % I = N + * + * Return a new Decimal whose value is the value of this Decimal modulo `y`, rounded to + * `precision` significant digits using rounding mode `rounding`. + * + * The result depends on the modulo mode. + * + */ +P.modulo = P.mod = function (y) { + var q, + x = this, + Ctor = x.constructor; - // Prevent rounding of intermediate calculations. - external = false; + y = new Ctor(y); - if (Ctor.modulo == 9) { + // Return NaN if x is ±Infinity or NaN, or y is NaN or ±0. + if (!x.d || !y.s || y.d && !y.d[0]) return new Ctor(NaN); - // Euclidian division: q = sign(y) * floor(x / abs(y)) - // result = x - q * y where 0 <= result < abs(y) - q = divide(x, y.abs(), 0, 3, 1); - q.s *= y.s; - } else { - q = divide(x, y, 0, Ctor.modulo, 1); - } + // Return x if y is ±Infinity or x is ±0. + if (!y.d || x.d && !x.d[0]) { + return finalise(new Ctor(x), Ctor.precision, Ctor.rounding); + } - q = q.times(y); + // Prevent rounding of intermediate calculations. + external = false; - external = true; + if (Ctor.modulo == 9) { - return x.minus(q); - }; + // Euclidian division: q = sign(y) * floor(x / abs(y)) + // result = x - q * y where 0 <= result < abs(y) + q = divide(x, y.abs(), 0, 3, 1); + q.s *= y.s; + } else { + q = divide(x, y, 0, Ctor.modulo, 1); + } + q = q.times(y); - /* - * Return a new Decimal whose value is the natural exponential of the value of this Decimal, - * i.e. the base e raised to the power the value of this Decimal, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - */ - P.naturalExponential = P.exp = function () { - return naturalExponential(this); - }; + external = true; + return x.minus(q); +}; - /* - * Return a new Decimal whose value is the natural logarithm of the value of this Decimal, - * rounded to `precision` significant digits using rounding mode `rounding`. - * - */ - P.naturalLogarithm = P.ln = function () { - return naturalLogarithm(this); - }; +/* + * Return a new Decimal whose value is the natural exponential of the value of this Decimal, + * i.e. the base e raised to the power the value of this Decimal, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + */ +P.naturalExponential = P.exp = function () { + return naturalExponential(this); +}; - /* - * Return a new Decimal whose value is the value of this Decimal negated, i.e. as if multiplied by - * -1. - * - */ - P.negated = P.neg = function () { - var x = new this.constructor(this); - x.s = -x.s; - return finalise(x); - }; +/* + * Return a new Decimal whose value is the natural logarithm of the value of this Decimal, + * rounded to `precision` significant digits using rounding mode `rounding`. + * + */ +P.naturalLogarithm = P.ln = function () { + return naturalLogarithm(this); +}; - /* - * n + 0 = n - * n + N = N - * n + I = I - * 0 + n = n - * 0 + 0 = 0 - * 0 + N = N - * 0 + I = I - * N + n = N - * N + 0 = N - * N + N = N - * N + I = N - * I + n = I - * I + 0 = I - * I + N = N - * I + I = I - * - * Return a new Decimal whose value is the value of this Decimal plus `y`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - */ - P.plus = P.add = function (y) { - var carry, d, e, i, k, len, pr, rm, xd, yd, - x = this, - Ctor = x.constructor; - y = new Ctor(y); +/* + * Return a new Decimal whose value is the value of this Decimal negated, i.e. as if multiplied by + * -1. + * + */ +P.negated = P.neg = function () { + var x = new this.constructor(this); + x.s = -x.s; + return finalise(x); +}; - // If either is not finite... - if (!x.d || !y.d) { - // Return NaN if either is NaN. - if (!x.s || !y.s) y = new Ctor(NaN); +/* + * n + 0 = n + * n + N = N + * n + I = I + * 0 + n = n + * 0 + 0 = 0 + * 0 + N = N + * 0 + I = I + * N + n = N + * N + 0 = N + * N + N = N + * N + I = N + * I + n = I + * I + 0 = I + * I + N = N + * I + I = I + * + * Return a new Decimal whose value is the value of this Decimal plus `y`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + */ +P.plus = P.add = function (y) { + var carry, d, e, i, k, len, pr, rm, xd, yd, + x = this, + Ctor = x.constructor; - // Return x if y is finite and x is ±Infinity. - // Return x if both are ±Infinity with the same sign. - // Return NaN if both are ±Infinity with different signs. - // Return y if x is finite and y is ±Infinity. - else if (!x.d) y = new Ctor(y.d || x.s === y.s ? x : NaN); + y = new Ctor(y); - return y; - } + // If either is not finite... + if (!x.d || !y.d) { - // If signs differ... - if (x.s != y.s) { - y.s = -y.s; - return x.minus(y); - } + // Return NaN if either is NaN. + if (!x.s || !y.s) y = new Ctor(NaN); - xd = x.d; - yd = y.d; - pr = Ctor.precision; - rm = Ctor.rounding; + // Return x if y is finite and x is ±Infinity. + // Return x if both are ±Infinity with the same sign. + // Return NaN if both are ±Infinity with different signs. + // Return y if x is finite and y is ±Infinity. + else if (!x.d) y = new Ctor(y.d || x.s === y.s ? x : NaN); - // If either is zero... - if (!xd[0] || !yd[0]) { + return y; + } - // Return x if y is zero. - // Return y if y is non-zero. - if (!yd[0]) y = new Ctor(x); + // If signs differ... + if (x.s != y.s) { + y.s = -y.s; + return x.minus(y); + } - return external ? finalise(y, pr, rm) : y; - } + xd = x.d; + yd = y.d; + pr = Ctor.precision; + rm = Ctor.rounding; - // x and y are finite, non-zero numbers with the same sign. + // If either is zero... + if (!xd[0] || !yd[0]) { - // Calculate base 1e7 exponents. - k = mathfloor(x.e / LOG_BASE); - e = mathfloor(y.e / LOG_BASE); + // Return x if y is zero. + // Return y if y is non-zero. + if (!yd[0]) y = new Ctor(x); - xd = xd.slice(); - i = k - e; + return external ? finalise(y, pr, rm) : y; + } - // If base 1e7 exponents differ... - if (i) { + // x and y are finite, non-zero numbers with the same sign. - if (i < 0) { - d = xd; - i = -i; - len = yd.length; - } else { - d = yd; - e = k; - len = xd.length; - } + // Calculate base 1e7 exponents. + k = mathfloor(x.e / LOG_BASE); + e = mathfloor(y.e / LOG_BASE); - // Limit number of zeros prepended to max(ceil(pr / LOG_BASE), len) + 1. - k = Math.ceil(pr / LOG_BASE); - len = k > len ? k + 1 : len + 1; + xd = xd.slice(); + i = k - e; - if (i > len) { - i = len; - d.length = 1; - } + // If base 1e7 exponents differ... + if (i) { - // Prepend zeros to equalise exponents. Note: Faster to use reverse then do unshifts. - d.reverse(); - for (; i--;) d.push(0); - d.reverse(); + if (i < 0) { + d = xd; + i = -i; + len = yd.length; + } else { + d = yd; + e = k; + len = xd.length; } - len = xd.length; - i = yd.length; + // Limit number of zeros prepended to max(ceil(pr / LOG_BASE), len) + 1. + k = Math.ceil(pr / LOG_BASE); + len = k > len ? k + 1 : len + 1; - // If yd is longer than xd, swap xd and yd so xd points to the longer array. - if (len - i < 0) { + if (i > len) { i = len; - d = yd; - yd = xd; - xd = d; + d.length = 1; } - // Only start adding at yd.length - 1 as the further digits of xd can be left as they are. - for (carry = 0; i;) { - carry = (xd[--i] = xd[i] + yd[i] + carry) / BASE | 0; - xd[i] %= BASE; - } + // Prepend zeros to equalise exponents. Note: Faster to use reverse then do unshifts. + d.reverse(); + for (; i--;) d.push(0); + d.reverse(); + } - if (carry) { - xd.unshift(carry); - ++e; - } + len = xd.length; + i = yd.length; - // Remove trailing zeros. - // No need to check for zero, as +x + +y != 0 && -x + -y != 0 - for (len = xd.length; xd[--len] == 0;) xd.pop(); + // If yd is longer than xd, swap xd and yd so xd points to the longer array. + if (len - i < 0) { + i = len; + d = yd; + yd = xd; + xd = d; + } - y.d = xd; - y.e = getBase10Exponent(xd, e); + // Only start adding at yd.length - 1 as the further digits of xd can be left as they are. + for (carry = 0; i;) { + carry = (xd[--i] = xd[i] + yd[i] + carry) / BASE | 0; + xd[i] %= BASE; + } - return external ? finalise(y, pr, rm) : y; - }; + if (carry) { + xd.unshift(carry); + ++e; + } + // Remove trailing zeros. + // No need to check for zero, as +x + +y != 0 && -x + -y != 0 + for (len = xd.length; xd[--len] == 0;) xd.pop(); - /* - * Return the number of significant digits of the value of this Decimal. - * - * [z] {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0. - * - */ - P.precision = P.sd = function (z) { - var k, - x = this; + y.d = xd; + y.e = getBase10Exponent(xd, e); - if (z !== void 0 && z !== !!z && z !== 1 && z !== 0) throw Error(invalidArgument + z); + return external ? finalise(y, pr, rm) : y; +}; - if (x.d) { - k = getPrecision(x.d); - if (z && x.e + 1 > k) k = x.e + 1; - } else { - k = NaN; - } - return k; - }; +/* + * Return the number of significant digits of the value of this Decimal. + * + * [z] {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0. + * + */ +P.precision = P.sd = function (z) { + var k, + x = this; + if (z !== void 0 && z !== !!z && z !== 1 && z !== 0) throw Error(invalidArgument + z); - /* - * Return a new Decimal whose value is the value of this Decimal rounded to a whole number using - * rounding mode `rounding`. - * - */ - P.round = function () { - var x = this, - Ctor = x.constructor; + if (x.d) { + k = getPrecision(x.d); + if (z && x.e + 1 > k) k = x.e + 1; + } else { + k = NaN; + } - return finalise(new Ctor(x), x.e + 1, Ctor.rounding); - }; + return k; +}; - /* - * Return a new Decimal whose value is the sine of the value in radians of this Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-1, 1] - * - * sin(x) = x - x^3/3! + x^5/5! - ... - * - * sin(0) = 0 - * sin(-0) = -0 - * sin(Infinity) = NaN - * sin(-Infinity) = NaN - * sin(NaN) = NaN - * - */ - P.sine = P.sin = function () { - var pr, rm, - x = this, - Ctor = x.constructor; +/* + * Return a new Decimal whose value is the value of this Decimal rounded to a whole number using + * rounding mode `rounding`. + * + */ +P.round = function () { + var x = this, + Ctor = x.constructor; - if (!x.isFinite()) return new Ctor(NaN); - if (x.isZero()) return new Ctor(x); + return finalise(new Ctor(x), x.e + 1, Ctor.rounding); +}; - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + Math.max(x.e, x.sd()) + LOG_BASE; - Ctor.rounding = 1; - x = sine(Ctor, toLessThanHalfPi(Ctor, x)); +/* + * Return a new Decimal whose value is the sine of the value in radians of this Decimal. + * + * Domain: [-Infinity, Infinity] + * Range: [-1, 1] + * + * sin(x) = x - x^3/3! + x^5/5! - ... + * + * sin(0) = 0 + * sin(-0) = -0 + * sin(Infinity) = NaN + * sin(-Infinity) = NaN + * sin(NaN) = NaN + * + */ +P.sine = P.sin = function () { + var pr, rm, + x = this, + Ctor = x.constructor; - Ctor.precision = pr; - Ctor.rounding = rm; + if (!x.isFinite()) return new Ctor(NaN); + if (x.isZero()) return new Ctor(x); - return finalise(quadrant > 2 ? x.neg() : x, pr, rm, true); - }; + pr = Ctor.precision; + rm = Ctor.rounding; + Ctor.precision = pr + Math.max(x.e, x.sd()) + LOG_BASE; + Ctor.rounding = 1; + x = sine(Ctor, toLessThanHalfPi(Ctor, x)); - /* - * Return a new Decimal whose value is the square root of this Decimal, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * sqrt(-n) = N - * sqrt(N) = N - * sqrt(-I) = N - * sqrt(I) = I - * sqrt(0) = 0 - * sqrt(-0) = -0 - * - */ - P.squareRoot = P.sqrt = function () { - var m, n, sd, r, rep, t, - x = this, - d = x.d, - e = x.e, - s = x.s, - Ctor = x.constructor; + Ctor.precision = pr; + Ctor.rounding = rm; - // Negative/NaN/Infinity/zero? - if (s !== 1 || !d || !d[0]) { - return new Ctor(!s || s < 0 && (!d || d[0]) ? NaN : d ? x : 1 / 0); - } + return finalise(quadrant > 2 ? x.neg() : x, pr, rm, true); +}; - external = false; - // Initial estimate. - s = Math.sqrt(+x); +/* + * Return a new Decimal whose value is the square root of this Decimal, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * sqrt(-n) = N + * sqrt(N) = N + * sqrt(-I) = N + * sqrt(I) = I + * sqrt(0) = 0 + * sqrt(-0) = -0 + * + */ +P.squareRoot = P.sqrt = function () { + var m, n, sd, r, rep, t, + x = this, + d = x.d, + e = x.e, + s = x.s, + Ctor = x.constructor; + + // Negative/NaN/Infinity/zero? + if (s !== 1 || !d || !d[0]) { + return new Ctor(!s || s < 0 && (!d || d[0]) ? NaN : d ? x : 1 / 0); + } + + external = false; - // Math.sqrt underflow/overflow? - // Pass x to Math.sqrt as integer, then adjust the exponent of the result. - if (s == 0 || s == 1 / 0) { - n = digitsToString(d); + // Initial estimate. + s = Math.sqrt(+x); - if ((n.length + e) % 2 == 0) n += '0'; - s = Math.sqrt(n); - e = mathfloor((e + 1) / 2) - (e < 0 || e % 2); + // Math.sqrt underflow/overflow? + // Pass x to Math.sqrt as integer, then adjust the exponent of the result. + if (s == 0 || s == 1 / 0) { + n = digitsToString(d); - if (s == 1 / 0) { - n = '1e' + e; - } else { - n = s.toExponential(); - n = n.slice(0, n.indexOf('e') + 1) + e; - } + if ((n.length + e) % 2 == 0) n += '0'; + s = Math.sqrt(n); + e = mathfloor((e + 1) / 2) - (e < 0 || e % 2); - r = new Ctor(n); + if (s == 1 / 0) { + n = '1e' + e; } else { - r = new Ctor(s.toString()); + n = s.toExponential(); + n = n.slice(0, n.indexOf('e') + 1) + e; } - sd = (e = Ctor.precision) + 3; + r = new Ctor(n); + } else { + r = new Ctor(s.toString()); + } + + sd = (e = Ctor.precision) + 3; - // Newton-Raphson iteration. - for (;;) { - t = r; - r = t.plus(divide(x, t, sd + 2, 1)).times(0.5); + // Newton-Raphson iteration. + for (;;) { + t = r; + r = t.plus(divide(x, t, sd + 2, 1)).times(0.5); - // TODO? Replace with for-loop and checkRoundingDigits. - if (digitsToString(t.d).slice(0, sd) === (n = digitsToString(r.d)).slice(0, sd)) { - n = n.slice(sd - 3, sd + 1); + // TODO? Replace with for-loop and checkRoundingDigits. + if (digitsToString(t.d).slice(0, sd) === (n = digitsToString(r.d)).slice(0, sd)) { + n = n.slice(sd - 3, sd + 1); - // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or - // 4999, i.e. approaching a rounding boundary, continue the iteration. - if (n == '9999' || !rep && n == '4999') { + // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or + // 4999, i.e. approaching a rounding boundary, continue the iteration. + if (n == '9999' || !rep && n == '4999') { - // On the first iteration only, check to see if rounding up gives the exact result as the - // nines may infinitely repeat. - if (!rep) { - finalise(t, e + 1, 0); + // On the first iteration only, check to see if rounding up gives the exact result as the + // nines may infinitely repeat. + if (!rep) { + finalise(t, e + 1, 0); - if (t.times(t).eq(x)) { - r = t; - break; - } + if (t.times(t).eq(x)) { + r = t; + break; } + } - sd += 4; - rep = 1; - } else { - - // If the rounding digits are null, 0{0,4} or 50{0,3}, check for an exact result. - // If not, then there are further digits and m will be truthy. - if (!+n || !+n.slice(1) && n.charAt(0) == '5') { + sd += 4; + rep = 1; + } else { - // Truncate to the first rounding digit. - finalise(r, e + 1, 1); - m = !r.times(r).eq(x); - } + // If the rounding digits are null, 0{0,4} or 50{0,3}, check for an exact result. + // If not, then there are further digits and m will be truthy. + if (!+n || !+n.slice(1) && n.charAt(0) == '5') { - break; + // Truncate to the first rounding digit. + finalise(r, e + 1, 1); + m = !r.times(r).eq(x); } + + break; } } + } - external = true; + external = true; - return finalise(r, e, Ctor.rounding, m); - }; + return finalise(r, e, Ctor.rounding, m); +}; - /* - * Return a new Decimal whose value is the tangent of the value in radians of this Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-Infinity, Infinity] - * - * tan(0) = 0 - * tan(-0) = -0 - * tan(Infinity) = NaN - * tan(-Infinity) = NaN - * tan(NaN) = NaN - * - */ - P.tangent = P.tan = function () { - var pr, rm, - x = this, - Ctor = x.constructor; +/* + * Return a new Decimal whose value is the tangent of the value in radians of this Decimal. + * + * Domain: [-Infinity, Infinity] + * Range: [-Infinity, Infinity] + * + * tan(0) = 0 + * tan(-0) = -0 + * tan(Infinity) = NaN + * tan(-Infinity) = NaN + * tan(NaN) = NaN + * + */ +P.tangent = P.tan = function () { + var pr, rm, + x = this, + Ctor = x.constructor; - if (!x.isFinite()) return new Ctor(NaN); - if (x.isZero()) return new Ctor(x); + if (!x.isFinite()) return new Ctor(NaN); + if (x.isZero()) return new Ctor(x); - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + 10; - Ctor.rounding = 1; + pr = Ctor.precision; + rm = Ctor.rounding; + Ctor.precision = pr + 10; + Ctor.rounding = 1; - x = x.sin(); - x.s = 1; - x = divide(x, new Ctor(1).minus(x.times(x)).sqrt(), pr + 10, 0); + x = x.sin(); + x.s = 1; + x = divide(x, new Ctor(1).minus(x.times(x)).sqrt(), pr + 10, 0); - Ctor.precision = pr; - Ctor.rounding = rm; + Ctor.precision = pr; + Ctor.rounding = rm; - return finalise(quadrant == 2 || quadrant == 4 ? x.neg() : x, pr, rm, true); - }; + return finalise(quadrant == 2 || quadrant == 4 ? x.neg() : x, pr, rm, true); +}; - /* - * n * 0 = 0 - * n * N = N - * n * I = I - * 0 * n = 0 - * 0 * 0 = 0 - * 0 * N = N - * 0 * I = N - * N * n = N - * N * 0 = N - * N * N = N - * N * I = N - * I * n = I - * I * 0 = N - * I * N = N - * I * I = I - * - * Return a new Decimal whose value is this Decimal times `y`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - */ - P.times = P.mul = function (y) { - var carry, e, i, k, r, rL, t, xdL, ydL, - x = this, - Ctor = x.constructor, - xd = x.d, - yd = (y = new Ctor(y)).d; +/* + * n * 0 = 0 + * n * N = N + * n * I = I + * 0 * n = 0 + * 0 * 0 = 0 + * 0 * N = N + * 0 * I = N + * N * n = N + * N * 0 = N + * N * N = N + * N * I = N + * I * n = I + * I * 0 = N + * I * N = N + * I * I = I + * + * Return a new Decimal whose value is this Decimal times `y`, rounded to `precision` significant + * digits using rounding mode `rounding`. + * + */ +P.times = P.mul = function (y) { + var carry, e, i, k, r, rL, t, xdL, ydL, + x = this, + Ctor = x.constructor, + xd = x.d, + yd = (y = new Ctor(y)).d; - y.s *= x.s; + y.s *= x.s; - // If either is NaN, ±Infinity or ±0... - if (!xd || !xd[0] || !yd || !yd[0]) { + // If either is NaN, ±Infinity or ±0... + if (!xd || !xd[0] || !yd || !yd[0]) { - return new Ctor(!y.s || xd && !xd[0] && !yd || yd && !yd[0] && !xd + return new Ctor(!y.s || xd && !xd[0] && !yd || yd && !yd[0] && !xd - // Return NaN if either is NaN. - // Return NaN if x is ±0 and y is ±Infinity, or y is ±0 and x is ±Infinity. - ? NaN + // Return NaN if either is NaN. + // Return NaN if x is ±0 and y is ±Infinity, or y is ±0 and x is ±Infinity. + ? NaN - // Return ±Infinity if either is ±Infinity. - // Return ±0 if either is ±0. - : !xd || !yd ? y.s / 0 : y.s * 0); - } + // Return ±Infinity if either is ±Infinity. + // Return ±0 if either is ±0. + : !xd || !yd ? y.s / 0 : y.s * 0); + } - e = mathfloor(x.e / LOG_BASE) + mathfloor(y.e / LOG_BASE); - xdL = xd.length; - ydL = yd.length; + e = mathfloor(x.e / LOG_BASE) + mathfloor(y.e / LOG_BASE); + xdL = xd.length; + ydL = yd.length; - // Ensure xd points to the longer array. - if (xdL < ydL) { - r = xd; - xd = yd; - yd = r; - rL = xdL; - xdL = ydL; - ydL = rL; - } - - // Initialise the result array with zeros. - r = []; - rL = xdL + ydL; - for (i = rL; i--;) r.push(0); + // Ensure xd points to the longer array. + if (xdL < ydL) { + r = xd; + xd = yd; + yd = r; + rL = xdL; + xdL = ydL; + ydL = rL; + } - // Multiply! - for (i = ydL; --i >= 0;) { - carry = 0; - for (k = xdL + i; k > i;) { - t = r[k] + yd[i] * xd[k - i - 1] + carry; - r[k--] = t % BASE | 0; - carry = t / BASE | 0; - } + // Initialise the result array with zeros. + r = []; + rL = xdL + ydL; + for (i = rL; i--;) r.push(0); - r[k] = (r[k] + carry) % BASE | 0; + // Multiply! + for (i = ydL; --i >= 0;) { + carry = 0; + for (k = xdL + i; k > i;) { + t = r[k] + yd[i] * xd[k - i - 1] + carry; + r[k--] = t % BASE | 0; + carry = t / BASE | 0; } - // Remove trailing zeros. - for (; !r[--rL];) r.pop(); - - if (carry) ++e; - else r.shift(); + r[k] = (r[k] + carry) % BASE | 0; + } - y.d = r; - y.e = getBase10Exponent(r, e); + // Remove trailing zeros. + for (; !r[--rL];) r.pop(); - return external ? finalise(y, Ctor.precision, Ctor.rounding) : y; - }; + if (carry) ++e; + else r.shift(); + y.d = r; + y.e = getBase10Exponent(r, e); - /* - * Return a string representing the value of this Decimal in base 2, round to `sd` significant - * digits using rounding mode `rm`. - * - * If the optional `sd` argument is present then return binary exponential notation. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ - P.toBinary = function (sd, rm) { - return toStringBinary(this, 2, sd, rm); - }; + return external ? finalise(y, Ctor.precision, Ctor.rounding) : y; +}; - /* - * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `dp` - * decimal places using rounding mode `rm` or `rounding` if `rm` is omitted. - * - * If `dp` is omitted, return a new Decimal whose value is the value of this Decimal. - * - * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ - P.toDecimalPlaces = P.toDP = function (dp, rm) { - var x = this, - Ctor = x.constructor; +/* + * Return a string representing the value of this Decimal in base 2, round to `sd` significant + * digits using rounding mode `rm`. + * + * If the optional `sd` argument is present then return binary exponential notation. + * + * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toBinary = function (sd, rm) { + return toStringBinary(this, 2, sd, rm); +}; - x = new Ctor(x); - if (dp === void 0) return x; - checkInt32(dp, 0, MAX_DIGITS); +/* + * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `dp` + * decimal places using rounding mode `rm` or `rounding` if `rm` is omitted. + * + * If `dp` is omitted, return a new Decimal whose value is the value of this Decimal. + * + * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toDecimalPlaces = P.toDP = function (dp, rm) { + var x = this, + Ctor = x.constructor; - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); + x = new Ctor(x); + if (dp === void 0) return x; - return finalise(x, dp + x.e + 1, rm); - }; + checkInt32(dp, 0, MAX_DIGITS); + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); - /* - * Return a string representing the value of this Decimal in exponential notation rounded to - * `dp` fixed decimal places using rounding mode `rounding`. - * - * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ - P.toExponential = function (dp, rm) { - var str, - x = this, - Ctor = x.constructor; + return finalise(x, dp + x.e + 1, rm); +}; - if (dp === void 0) { - str = finiteToString(x, true); - } else { - checkInt32(dp, 0, MAX_DIGITS); - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); +/* + * Return a string representing the value of this Decimal in exponential notation rounded to + * `dp` fixed decimal places using rounding mode `rounding`. + * + * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toExponential = function (dp, rm) { + var str, + x = this, + Ctor = x.constructor; - x = finalise(new Ctor(x), dp + 1, rm); - str = finiteToString(x, true, dp + 1); - } + if (dp === void 0) { + str = finiteToString(x, true); + } else { + checkInt32(dp, 0, MAX_DIGITS); - return x.isNeg() && !x.isZero() ? '-' + str : str; - }; + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); + x = finalise(new Ctor(x), dp + 1, rm); + str = finiteToString(x, true, dp + 1); + } - /* - * Return a string representing the value of this Decimal in normal (fixed-point) notation to - * `dp` fixed decimal places and rounded using rounding mode `rm` or `rounding` if `rm` is - * omitted. - * - * As with JavaScript numbers, (-0).toFixed(0) is '0', but e.g. (-0.00001).toFixed(0) is '-0'. - * - * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - * (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'. - * (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'. - * (-0).toFixed(3) is '0.000'. - * (-0.5).toFixed(0) is '-0'. - * - */ - P.toFixed = function (dp, rm) { - var str, y, - x = this, - Ctor = x.constructor; + return x.isNeg() && !x.isZero() ? '-' + str : str; +}; - if (dp === void 0) { - str = finiteToString(x); - } else { - checkInt32(dp, 0, MAX_DIGITS); - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); +/* + * Return a string representing the value of this Decimal in normal (fixed-point) notation to + * `dp` fixed decimal places and rounded using rounding mode `rm` or `rounding` if `rm` is + * omitted. + * + * As with JavaScript numbers, (-0).toFixed(0) is '0', but e.g. (-0.00001).toFixed(0) is '-0'. + * + * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'. + * (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'. + * (-0).toFixed(3) is '0.000'. + * (-0.5).toFixed(0) is '-0'. + * + */ +P.toFixed = function (dp, rm) { + var str, y, + x = this, + Ctor = x.constructor; - y = finalise(new Ctor(x), dp + x.e + 1, rm); - str = finiteToString(y, false, dp + y.e + 1); - } + if (dp === void 0) { + str = finiteToString(x); + } else { + checkInt32(dp, 0, MAX_DIGITS); - // To determine whether to add the minus sign look at the value before it was rounded, - // i.e. look at `x` rather than `y`. - return x.isNeg() && !x.isZero() ? '-' + str : str; - }; + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); + y = finalise(new Ctor(x), dp + x.e + 1, rm); + str = finiteToString(y, false, dp + y.e + 1); + } - /* - * Return an array representing the value of this Decimal as a simple fraction with an integer - * numerator and an integer denominator. - * - * The denominator will be a positive non-zero value less than or equal to the specified maximum - * denominator. If a maximum denominator is not specified, the denominator will be the lowest - * value necessary to represent the number exactly. - * - * [maxD] {number|string|Decimal} Maximum denominator. Integer >= 1 and < Infinity. - * - */ - P.toFraction = function (maxD) { - var d, d0, d1, d2, e, k, n, n0, n1, pr, q, r, - x = this, - xd = x.d, - Ctor = x.constructor; + // To determine whether to add the minus sign look at the value before it was rounded, + // i.e. look at `x` rather than `y`. + return x.isNeg() && !x.isZero() ? '-' + str : str; +}; - if (!xd) return new Ctor(x); - n1 = d0 = new Ctor(1); - d1 = n0 = new Ctor(0); +/* + * Return an array representing the value of this Decimal as a simple fraction with an integer + * numerator and an integer denominator. + * + * The denominator will be a positive non-zero value less than or equal to the specified maximum + * denominator. If a maximum denominator is not specified, the denominator will be the lowest + * value necessary to represent the number exactly. + * + * [maxD] {number|string|Decimal} Maximum denominator. Integer >= 1 and < Infinity. + * + */ +P.toFraction = function (maxD) { + var d, d0, d1, d2, e, k, n, n0, n1, pr, q, r, + x = this, + xd = x.d, + Ctor = x.constructor; - d = new Ctor(d1); - e = d.e = getPrecision(xd) - x.e - 1; - k = e % LOG_BASE; - d.d[0] = mathpow(10, k < 0 ? LOG_BASE + k : k); + if (!xd) return new Ctor(x); - if (maxD == null) { + n1 = d0 = new Ctor(1); + d1 = n0 = new Ctor(0); - // d is 10**e, the minimum max-denominator needed. - maxD = e > 0 ? d : n1; - } else { - n = new Ctor(maxD); - if (!n.isInt() || n.lt(n1)) throw Error(invalidArgument + n); - maxD = n.gt(d) ? (e > 0 ? d : n1) : n; - } + d = new Ctor(d1); + e = d.e = getPrecision(xd) - x.e - 1; + k = e % LOG_BASE; + d.d[0] = mathpow(10, k < 0 ? LOG_BASE + k : k); - external = false; - n = new Ctor(digitsToString(xd)); - pr = Ctor.precision; - Ctor.precision = e = xd.length * LOG_BASE * 2; - - for (;;) { - q = divide(n, d, 0, 1, 1); - d2 = d0.plus(q.times(d1)); - if (d2.cmp(maxD) == 1) break; - d0 = d1; - d1 = d2; - d2 = n1; - n1 = n0.plus(q.times(d2)); - n0 = d2; - d2 = d; - d = n.minus(q.times(d2)); - n = d2; - } - - d2 = divide(maxD.minus(d0), d1, 0, 1, 1); - n0 = n0.plus(d2.times(n1)); - d0 = d0.plus(d2.times(d1)); - n0.s = n1.s = x.s; - - // Determine which fraction is closer to x, n0/d0 or n1/d1? - r = divide(n1, d1, e, 1).minus(x).abs().cmp(divide(n0, d0, e, 1).minus(x).abs()) < 1 - ? [n1, d1] : [n0, d0]; + if (maxD == null) { - Ctor.precision = pr; - external = true; + // d is 10**e, the minimum max-denominator needed. + maxD = e > 0 ? d : n1; + } else { + n = new Ctor(maxD); + if (!n.isInt() || n.lt(n1)) throw Error(invalidArgument + n); + maxD = n.gt(d) ? (e > 0 ? d : n1) : n; + } + + external = false; + n = new Ctor(digitsToString(xd)); + pr = Ctor.precision; + Ctor.precision = e = xd.length * LOG_BASE * 2; + + for (;;) { + q = divide(n, d, 0, 1, 1); + d2 = d0.plus(q.times(d1)); + if (d2.cmp(maxD) == 1) break; + d0 = d1; + d1 = d2; + d2 = n1; + n1 = n0.plus(q.times(d2)); + n0 = d2; + d2 = d; + d = n.minus(q.times(d2)); + n = d2; + } + + d2 = divide(maxD.minus(d0), d1, 0, 1, 1); + n0 = n0.plus(d2.times(n1)); + d0 = d0.plus(d2.times(d1)); + n0.s = n1.s = x.s; + + // Determine which fraction is closer to x, n0/d0 or n1/d1? + r = divide(n1, d1, e, 1).minus(x).abs().cmp(divide(n0, d0, e, 1).minus(x).abs()) < 1 + ? [n1, d1] : [n0, d0]; + + Ctor.precision = pr; + external = true; - return r; - }; + return r; +}; - /* - * Return a string representing the value of this Decimal in base 16, round to `sd` significant - * digits using rounding mode `rm`. - * - * If the optional `sd` argument is present then return binary exponential notation. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ - P.toHexadecimal = P.toHex = function (sd, rm) { - return toStringBinary(this, 16, sd, rm); - }; +/* + * Return a string representing the value of this Decimal in base 16, round to `sd` significant + * digits using rounding mode `rm`. + * + * If the optional `sd` argument is present then return binary exponential notation. + * + * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toHexadecimal = P.toHex = function (sd, rm) { + return toStringBinary(this, 16, sd, rm); +}; - /* - * Returns a new Decimal whose value is the nearest multiple of the magnitude of `y` to the value - * of this Decimal. - * - * If the value of this Decimal is equidistant from two multiples of `y`, the rounding mode `rm`, - * or `Decimal.rounding` if `rm` is omitted, determines the direction of the nearest multiple. - * - * In the context of this method, rounding mode 4 (ROUND_HALF_UP) is the same as rounding mode 0 - * (ROUND_UP), and so on. - * - * The return value will always have the same sign as this Decimal, unless either this Decimal - * or `y` is NaN, in which case the return value will be also be NaN. - * - * The return value is not affected by the value of `precision`. - * - * y {number|string|Decimal} The magnitude to round to a multiple of. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - * 'toNearest() rounding mode not an integer: {rm}' - * 'toNearest() rounding mode out of range: {rm}' - * - */ - P.toNearest = function (y, rm) { - var x = this, - Ctor = x.constructor; +/* + * Returns a new Decimal whose value is the nearest multiple of the magnitude of `y` to the value + * of this Decimal. + * + * If the value of this Decimal is equidistant from two multiples of `y`, the rounding mode `rm`, + * or `Decimal.rounding` if `rm` is omitted, determines the direction of the nearest multiple. + * + * In the context of this method, rounding mode 4 (ROUND_HALF_UP) is the same as rounding mode 0 + * (ROUND_UP), and so on. + * + * The return value will always have the same sign as this Decimal, unless either this Decimal + * or `y` is NaN, in which case the return value will be also be NaN. + * + * The return value is not affected by the value of `precision`. + * + * y {number|string|Decimal} The magnitude to round to a multiple of. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * 'toNearest() rounding mode not an integer: {rm}' + * 'toNearest() rounding mode out of range: {rm}' + * + */ +P.toNearest = function (y, rm) { + var x = this, + Ctor = x.constructor; - x = new Ctor(x); + x = new Ctor(x); - if (y == null) { + if (y == null) { - // If x is not finite, return x. - if (!x.d) return x; + // If x is not finite, return x. + if (!x.d) return x; - y = new Ctor(1); - rm = Ctor.rounding; - } else { - y = new Ctor(y); - if (rm !== void 0) checkInt32(rm, 0, 8); + y = new Ctor(1); + rm = Ctor.rounding; + } else { + y = new Ctor(y); + if (rm !== void 0) checkInt32(rm, 0, 8); - // If x is not finite, return x if y is not NaN, else NaN. - if (!x.d) return y.s ? x : y; + // If x is not finite, return x if y is not NaN, else NaN. + if (!x.d) return y.s ? x : y; - // If y is not finite, return Infinity with the sign of x if y is Infinity, else NaN. - if (!y.d) { - if (y.s) y.s = x.s; - return y; - } + // If y is not finite, return Infinity with the sign of x if y is Infinity, else NaN. + if (!y.d) { + if (y.s) y.s = x.s; + return y; } + } - // If y is not zero, calculate the nearest multiple of y to x. - if (y.d[0]) { - external = false; - if (rm < 4) rm = [4, 5, 7, 8][rm]; - x = divide(x, y, 0, rm, 1).times(y); - external = true; - finalise(x); + // If y is not zero, calculate the nearest multiple of y to x. + if (y.d[0]) { + external = false; + if (rm < 4) rm = [4, 5, 7, 8][rm]; + x = divide(x, y, 0, rm, 1).times(y); + external = true; + finalise(x); - // If y is zero, return zero with the sign of x. - } else { - y.s = x.s; - x = y; - } + // If y is zero, return zero with the sign of x. + } else { + y.s = x.s; + x = y; + } - return x; - }; + return x; +}; - /* - * Return the value of this Decimal converted to a number primitive. - * Zero keeps its sign. - * - */ - P.toNumber = function () { - return +this; - }; +/* + * Return the value of this Decimal converted to a number primitive. + * Zero keeps its sign. + * + */ +P.toNumber = function () { + return +this; +}; - /* - * Return a string representing the value of this Decimal in base 8, round to `sd` significant - * digits using rounding mode `rm`. - * - * If the optional `sd` argument is present then return binary exponential notation. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ - P.toOctal = function (sd, rm) { - return toStringBinary(this, 8, sd, rm); - }; +/* + * Return a string representing the value of this Decimal in base 8, round to `sd` significant + * digits using rounding mode `rm`. + * + * If the optional `sd` argument is present then return binary exponential notation. + * + * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toOctal = function (sd, rm) { + return toStringBinary(this, 8, sd, rm); +}; - /* - * Return a new Decimal whose value is the value of this Decimal raised to the power `y`, rounded - * to `precision` significant digits using rounding mode `rounding`. - * - * ECMAScript compliant. - * - * pow(x, NaN) = NaN - * pow(x, ±0) = 1 - - * pow(NaN, non-zero) = NaN - * pow(abs(x) > 1, +Infinity) = +Infinity - * pow(abs(x) > 1, -Infinity) = +0 - * pow(abs(x) == 1, ±Infinity) = NaN - * pow(abs(x) < 1, +Infinity) = +0 - * pow(abs(x) < 1, -Infinity) = +Infinity - * pow(+Infinity, y > 0) = +Infinity - * pow(+Infinity, y < 0) = +0 - * pow(-Infinity, odd integer > 0) = -Infinity - * pow(-Infinity, even integer > 0) = +Infinity - * pow(-Infinity, odd integer < 0) = -0 - * pow(-Infinity, even integer < 0) = +0 - * pow(+0, y > 0) = +0 - * pow(+0, y < 0) = +Infinity - * pow(-0, odd integer > 0) = -0 - * pow(-0, even integer > 0) = +0 - * pow(-0, odd integer < 0) = -Infinity - * pow(-0, even integer < 0) = +Infinity - * pow(finite x < 0, finite non-integer) = NaN - * - * For non-integer or very large exponents pow(x, y) is calculated using - * - * x^y = exp(y*ln(x)) - * - * Assuming the first 15 rounding digits are each equally likely to be any digit 0-9, the - * probability of an incorrectly rounded result - * P([49]9{14} | [50]0{14}) = 2 * 0.2 * 10^-14 = 4e-15 = 1/2.5e+14 - * i.e. 1 in 250,000,000,000,000 - * - * If a result is incorrectly rounded the maximum error will be 1 ulp (unit in last place). - * - * y {number|string|Decimal} The power to which to raise this Decimal. - * - */ - P.toPower = P.pow = function (y) { - var e, k, pr, r, rm, s, - x = this, - Ctor = x.constructor, - yn = +(y = new Ctor(y)); +/* + * Return a new Decimal whose value is the value of this Decimal raised to the power `y`, rounded + * to `precision` significant digits using rounding mode `rounding`. + * + * ECMAScript compliant. + * + * pow(x, NaN) = NaN + * pow(x, ±0) = 1 + + * pow(NaN, non-zero) = NaN + * pow(abs(x) > 1, +Infinity) = +Infinity + * pow(abs(x) > 1, -Infinity) = +0 + * pow(abs(x) == 1, ±Infinity) = NaN + * pow(abs(x) < 1, +Infinity) = +0 + * pow(abs(x) < 1, -Infinity) = +Infinity + * pow(+Infinity, y > 0) = +Infinity + * pow(+Infinity, y < 0) = +0 + * pow(-Infinity, odd integer > 0) = -Infinity + * pow(-Infinity, even integer > 0) = +Infinity + * pow(-Infinity, odd integer < 0) = -0 + * pow(-Infinity, even integer < 0) = +0 + * pow(+0, y > 0) = +0 + * pow(+0, y < 0) = +Infinity + * pow(-0, odd integer > 0) = -0 + * pow(-0, even integer > 0) = +0 + * pow(-0, odd integer < 0) = -Infinity + * pow(-0, even integer < 0) = +Infinity + * pow(finite x < 0, finite non-integer) = NaN + * + * For non-integer or very large exponents pow(x, y) is calculated using + * + * x^y = exp(y*ln(x)) + * + * Assuming the first 15 rounding digits are each equally likely to be any digit 0-9, the + * probability of an incorrectly rounded result + * P([49]9{14} | [50]0{14}) = 2 * 0.2 * 10^-14 = 4e-15 = 1/2.5e+14 + * i.e. 1 in 250,000,000,000,000 + * + * If a result is incorrectly rounded the maximum error will be 1 ulp (unit in last place). + * + * y {number|string|Decimal} The power to which to raise this Decimal. + * + */ +P.toPower = P.pow = function (y) { + var e, k, pr, r, rm, s, + x = this, + Ctor = x.constructor, + yn = +(y = new Ctor(y)); - // Either ±Infinity, NaN or ±0? - if (!x.d || !y.d || !x.d[0] || !y.d[0]) return new Ctor(mathpow(+x, yn)); + // Either ±Infinity, NaN or ±0? + if (!x.d || !y.d || !x.d[0] || !y.d[0]) return new Ctor(mathpow(+x, yn)); - x = new Ctor(x); + x = new Ctor(x); - if (x.eq(1)) return x; + if (x.eq(1)) return x; - pr = Ctor.precision; - rm = Ctor.rounding; + pr = Ctor.precision; + rm = Ctor.rounding; - if (y.eq(1)) return finalise(x, pr, rm); + if (y.eq(1)) return finalise(x, pr, rm); - // y exponent - e = mathfloor(y.e / LOG_BASE); + // y exponent + e = mathfloor(y.e / LOG_BASE); - // If y is a small integer use the 'exponentiation by squaring' algorithm. - if (e >= y.d.length - 1 && (k = yn < 0 ? -yn : yn) <= MAX_SAFE_INTEGER) { - r = intPow(Ctor, x, k, pr); - return y.s < 0 ? new Ctor(1).div(r) : finalise(r, pr, rm); - } + // If y is a small integer use the 'exponentiation by squaring' algorithm. + if (e >= y.d.length - 1 && (k = yn < 0 ? -yn : yn) <= MAX_SAFE_INTEGER) { + r = intPow(Ctor, x, k, pr); + return y.s < 0 ? new Ctor(1).div(r) : finalise(r, pr, rm); + } - s = x.s; + s = x.s; - // if x is negative - if (s < 0) { + // if x is negative + if (s < 0) { - // if y is not an integer - if (e < y.d.length - 1) return new Ctor(NaN); + // if y is not an integer + if (e < y.d.length - 1) return new Ctor(NaN); - // Result is positive if x is negative and the last digit of integer y is even. - if ((y.d[e] & 1) == 0) s = 1; + // Result is positive if x is negative and the last digit of integer y is even. + if ((y.d[e] & 1) == 0) s = 1; - // if x.eq(-1) - if (x.e == 0 && x.d[0] == 1 && x.d.length == 1) { - x.s = s; - return x; - } + // if x.eq(-1) + if (x.e == 0 && x.d[0] == 1 && x.d.length == 1) { + x.s = s; + return x; } + } - // Estimate result exponent. - // x^y = 10^e, where e = y * log10(x) - // log10(x) = log10(x_significand) + x_exponent - // log10(x_significand) = ln(x_significand) / ln(10) - k = mathpow(+x, yn); - e = k == 0 || !isFinite(k) - ? mathfloor(yn * (Math.log('0.' + digitsToString(x.d)) / Math.LN10 + x.e + 1)) - : new Ctor(k + '').e; + // Estimate result exponent. + // x^y = 10^e, where e = y * log10(x) + // log10(x) = log10(x_significand) + x_exponent + // log10(x_significand) = ln(x_significand) / ln(10) + k = mathpow(+x, yn); + e = k == 0 || !isFinite(k) + ? mathfloor(yn * (Math.log('0.' + digitsToString(x.d)) / Math.LN10 + x.e + 1)) + : new Ctor(k + '').e; - // Exponent estimate may be incorrect e.g. x: 0.999999999999999999, y: 2.29, e: 0, r.e: -1. + // Exponent estimate may be incorrect e.g. x: 0.999999999999999999, y: 2.29, e: 0, r.e: -1. - // Overflow/underflow? - if (e > Ctor.maxE + 1 || e < Ctor.minE - 1) return new Ctor(e > 0 ? s / 0 : 0); + // Overflow/underflow? + if (e > Ctor.maxE + 1 || e < Ctor.minE - 1) return new Ctor(e > 0 ? s / 0 : 0); - external = false; - Ctor.rounding = x.s = 1; + external = false; + Ctor.rounding = x.s = 1; - // Estimate the extra guard digits needed to ensure five correct rounding digits from - // naturalLogarithm(x). Example of failure without these extra digits (precision: 10): - // new Decimal(2.32456).pow('2087987436534566.46411') - // should be 1.162377823e+764914905173815, but is 1.162355823e+764914905173815 - k = Math.min(12, (e + '').length); + // Estimate the extra guard digits needed to ensure five correct rounding digits from + // naturalLogarithm(x). Example of failure without these extra digits (precision: 10): + // new Decimal(2.32456).pow('2087987436534566.46411') + // should be 1.162377823e+764914905173815, but is 1.162355823e+764914905173815 + k = Math.min(12, (e + '').length); - // r = x^y = exp(y*ln(x)) - r = naturalExponential(y.times(naturalLogarithm(x, pr + k)), pr); + // r = x^y = exp(y*ln(x)) + r = naturalExponential(y.times(naturalLogarithm(x, pr + k)), pr); - // r may be Infinity, e.g. (0.9999999999999999).pow(-1e+40) - if (r.d) { + // r may be Infinity, e.g. (0.9999999999999999).pow(-1e+40) + if (r.d) { - // Truncate to the required precision plus five rounding digits. - r = finalise(r, pr + 5, 1); + // Truncate to the required precision plus five rounding digits. + r = finalise(r, pr + 5, 1); - // If the rounding digits are [49]9999 or [50]0000 increase the precision by 10 and recalculate - // the result. - if (checkRoundingDigits(r.d, pr, rm)) { - e = pr + 10; + // If the rounding digits are [49]9999 or [50]0000 increase the precision by 10 and recalculate + // the result. + if (checkRoundingDigits(r.d, pr, rm)) { + e = pr + 10; - // Truncate to the increased precision plus five rounding digits. - r = finalise(naturalExponential(y.times(naturalLogarithm(x, e + k)), e), e + 5, 1); + // Truncate to the increased precision plus five rounding digits. + r = finalise(naturalExponential(y.times(naturalLogarithm(x, e + k)), e), e + 5, 1); - // Check for 14 nines from the 2nd rounding digit (the first rounding digit may be 4 or 9). - if (+digitsToString(r.d).slice(pr + 1, pr + 15) + 1 == 1e14) { - r = finalise(r, pr + 1, 0); - } + // Check for 14 nines from the 2nd rounding digit (the first rounding digit may be 4 or 9). + if (+digitsToString(r.d).slice(pr + 1, pr + 15) + 1 == 1e14) { + r = finalise(r, pr + 1, 0); } } + } - r.s = s; - external = true; - Ctor.rounding = rm; - - return finalise(r, pr, rm); - }; + r.s = s; + external = true; + Ctor.rounding = rm; + return finalise(r, pr, rm); +}; - /* - * Return a string representing the value of this Decimal rounded to `sd` significant digits - * using rounding mode `rounding`. - * - * Return exponential notation if `sd` is less than the number of digits necessary to represent - * the integer part of the value in normal notation. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ - P.toPrecision = function (sd, rm) { - var str, - x = this, - Ctor = x.constructor; - if (sd === void 0) { - str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos); - } else { - checkInt32(sd, 1, MAX_DIGITS); +/* + * Return a string representing the value of this Decimal rounded to `sd` significant digits + * using rounding mode `rounding`. + * + * Return exponential notation if `sd` is less than the number of digits necessary to represent + * the integer part of the value in normal notation. + * + * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toPrecision = function (sd, rm) { + var str, + x = this, + Ctor = x.constructor; - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); + if (sd === void 0) { + str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos); + } else { + checkInt32(sd, 1, MAX_DIGITS); - x = finalise(new Ctor(x), sd, rm); - str = finiteToString(x, sd <= x.e || x.e <= Ctor.toExpNeg, sd); - } + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); - return x.isNeg() && !x.isZero() ? '-' + str : str; - }; + x = finalise(new Ctor(x), sd, rm); + str = finiteToString(x, sd <= x.e || x.e <= Ctor.toExpNeg, sd); + } + return x.isNeg() && !x.isZero() ? '-' + str : str; +}; - /* - * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `sd` - * significant digits using rounding mode `rm`, or to `precision` and `rounding` respectively if - * omitted. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - * 'toSD() digits out of range: {sd}' - * 'toSD() digits not an integer: {sd}' - * 'toSD() rounding mode not an integer: {rm}' - * 'toSD() rounding mode out of range: {rm}' - * - */ - P.toSignificantDigits = P.toSD = function (sd, rm) { - var x = this, - Ctor = x.constructor; - if (sd === void 0) { - sd = Ctor.precision; - rm = Ctor.rounding; - } else { - checkInt32(sd, 1, MAX_DIGITS); +/* + * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `sd` + * significant digits using rounding mode `rm`, or to `precision` and `rounding` respectively if + * omitted. + * + * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * 'toSD() digits out of range: {sd}' + * 'toSD() digits not an integer: {sd}' + * 'toSD() rounding mode not an integer: {rm}' + * 'toSD() rounding mode out of range: {rm}' + * + */ +P.toSignificantDigits = P.toSD = function (sd, rm) { + var x = this, + Ctor = x.constructor; - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); - } + if (sd === void 0) { + sd = Ctor.precision; + rm = Ctor.rounding; + } else { + checkInt32(sd, 1, MAX_DIGITS); - return finalise(new Ctor(x), sd, rm); - }; + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); + } + return finalise(new Ctor(x), sd, rm); +}; - /* - * Return a string representing the value of this Decimal. - * - * Return exponential notation if this Decimal has a positive exponent equal to or greater than - * `toExpPos`, or a negative exponent equal to or less than `toExpNeg`. - * - */ - P.toString = function () { - var x = this, - Ctor = x.constructor, - str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos); - return x.isNeg() && !x.isZero() ? '-' + str : str; - }; +/* + * Return a string representing the value of this Decimal. + * + * Return exponential notation if this Decimal has a positive exponent equal to or greater than + * `toExpPos`, or a negative exponent equal to or less than `toExpNeg`. + * + */ +P.toString = function () { + var x = this, + Ctor = x.constructor, + str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos); + return x.isNeg() && !x.isZero() ? '-' + str : str; +}; - /* - * Return a new Decimal whose value is the value of this Decimal truncated to a whole number. - * - */ - P.truncated = P.trunc = function () { - return finalise(new this.constructor(this), this.e + 1, 1); - }; +/* + * Return a new Decimal whose value is the value of this Decimal truncated to a whole number. + * + */ +P.truncated = P.trunc = function () { + return finalise(new this.constructor(this), this.e + 1, 1); +}; - /* - * Return a string representing the value of this Decimal. - * Unlike `toString`, negative zero will include the minus sign. - * - */ - P.valueOf = P.toJSON = function () { - var x = this, - Ctor = x.constructor, - str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos); - return x.isNeg() ? '-' + str : str; - }; +/* + * Return a string representing the value of this Decimal. + * Unlike `toString`, negative zero will include the minus sign. + * + */ +P.valueOf = P.toJSON = function () { + var x = this, + Ctor = x.constructor, + str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos); + return x.isNeg() ? '-' + str : str; +}; - /* - // Add aliases to match BigDecimal method names. - // P.add = P.plus; - P.subtract = P.minus; - P.multiply = P.times; - P.divide = P.div; - P.remainder = P.mod; - P.compareTo = P.cmp; - P.negate = P.neg; - */ +/* +// Add aliases to match BigDecimal method names. +// P.add = P.plus; +P.subtract = P.minus; +P.multiply = P.times; +P.divide = P.div; +P.remainder = P.mod; +P.compareTo = P.cmp; +P.negate = P.neg; + */ - // Helper functions for Decimal.prototype (P) and/or Decimal methods, and their callers. +// Helper functions for Decimal.prototype (P) and/or Decimal methods, and their callers. - /* - * digitsToString P.cubeRoot, P.logarithm, P.squareRoot, P.toFraction, P.toPower, - * finiteToString, naturalExponential, naturalLogarithm - * checkInt32 P.toDecimalPlaces, P.toExponential, P.toFixed, P.toNearest, - * P.toPrecision, P.toSignificantDigits, toStringBinary, random - * checkRoundingDigits P.logarithm, P.toPower, naturalExponential, naturalLogarithm - * convertBase toStringBinary, parseOther - * cos P.cos - * divide P.atanh, P.cubeRoot, P.dividedBy, P.dividedToIntegerBy, - * P.logarithm, P.modulo, P.squareRoot, P.tan, P.tanh, P.toFraction, - * P.toNearest, toStringBinary, naturalExponential, naturalLogarithm, - * taylorSeries, atan2, parseOther - * finalise P.absoluteValue, P.atan, P.atanh, P.ceil, P.cos, P.cosh, - * P.cubeRoot, P.dividedToIntegerBy, P.floor, P.logarithm, P.minus, - * P.modulo, P.negated, P.plus, P.round, P.sin, P.sinh, P.squareRoot, - * P.tan, P.times, P.toDecimalPlaces, P.toExponential, P.toFixed, - * P.toNearest, P.toPower, P.toPrecision, P.toSignificantDigits, - * P.truncated, divide, getLn10, getPi, naturalExponential, - * naturalLogarithm, ceil, floor, round, trunc - * finiteToString P.toExponential, P.toFixed, P.toPrecision, P.toString, P.valueOf, - * toStringBinary - * getBase10Exponent P.minus, P.plus, P.times, parseOther - * getLn10 P.logarithm, naturalLogarithm - * getPi P.acos, P.asin, P.atan, toLessThanHalfPi, atan2 - * getPrecision P.precision, P.toFraction - * getZeroString digitsToString, finiteToString - * intPow P.toPower, parseOther - * isOdd toLessThanHalfPi - * maxOrMin max, min - * naturalExponential P.naturalExponential, P.toPower - * naturalLogarithm P.acosh, P.asinh, P.atanh, P.logarithm, P.naturalLogarithm, - * P.toPower, naturalExponential - * nonFiniteToString finiteToString, toStringBinary - * parseDecimal Decimal - * parseOther Decimal - * sin P.sin - * taylorSeries P.cosh, P.sinh, cos, sin - * toLessThanHalfPi P.cos, P.sin - * toStringBinary P.toBinary, P.toHexadecimal, P.toOctal - * truncate intPow - * - * Throws: P.logarithm, P.precision, P.toFraction, checkInt32, getLn10, getPi, - * naturalLogarithm, config, parseOther, random, Decimal - */ +/* + * digitsToString P.cubeRoot, P.logarithm, P.squareRoot, P.toFraction, P.toPower, + * finiteToString, naturalExponential, naturalLogarithm + * checkInt32 P.toDecimalPlaces, P.toExponential, P.toFixed, P.toNearest, + * P.toPrecision, P.toSignificantDigits, toStringBinary, random + * checkRoundingDigits P.logarithm, P.toPower, naturalExponential, naturalLogarithm + * convertBase toStringBinary, parseOther + * cos P.cos + * divide P.atanh, P.cubeRoot, P.dividedBy, P.dividedToIntegerBy, + * P.logarithm, P.modulo, P.squareRoot, P.tan, P.tanh, P.toFraction, + * P.toNearest, toStringBinary, naturalExponential, naturalLogarithm, + * taylorSeries, atan2, parseOther + * finalise P.absoluteValue, P.atan, P.atanh, P.ceil, P.cos, P.cosh, + * P.cubeRoot, P.dividedToIntegerBy, P.floor, P.logarithm, P.minus, + * P.modulo, P.negated, P.plus, P.round, P.sin, P.sinh, P.squareRoot, + * P.tan, P.times, P.toDecimalPlaces, P.toExponential, P.toFixed, + * P.toNearest, P.toPower, P.toPrecision, P.toSignificantDigits, + * P.truncated, divide, getLn10, getPi, naturalExponential, + * naturalLogarithm, ceil, floor, round, trunc + * finiteToString P.toExponential, P.toFixed, P.toPrecision, P.toString, P.valueOf, + * toStringBinary + * getBase10Exponent P.minus, P.plus, P.times, parseOther + * getLn10 P.logarithm, naturalLogarithm + * getPi P.acos, P.asin, P.atan, toLessThanHalfPi, atan2 + * getPrecision P.precision, P.toFraction + * getZeroString digitsToString, finiteToString + * intPow P.toPower, parseOther + * isOdd toLessThanHalfPi + * maxOrMin max, min + * naturalExponential P.naturalExponential, P.toPower + * naturalLogarithm P.acosh, P.asinh, P.atanh, P.logarithm, P.naturalLogarithm, + * P.toPower, naturalExponential + * nonFiniteToString finiteToString, toStringBinary + * parseDecimal Decimal + * parseOther Decimal + * sin P.sin + * taylorSeries P.cosh, P.sinh, cos, sin + * toLessThanHalfPi P.cos, P.sin + * toStringBinary P.toBinary, P.toHexadecimal, P.toOctal + * truncate intPow + * + * Throws: P.logarithm, P.precision, P.toFraction, checkInt32, getLn10, getPi, + * naturalLogarithm, config, parseOther, random, Decimal + */ - function digitsToString(d) { - var i, k, ws, - indexOfLastWord = d.length - 1, - str = '', - w = d[0]; - if (indexOfLastWord > 0) { - str += w; - for (i = 1; i < indexOfLastWord; i++) { - ws = d[i] + ''; - k = LOG_BASE - ws.length; - if (k) str += getZeroString(k); - str += ws; - } +function digitsToString(d) { + var i, k, ws, + indexOfLastWord = d.length - 1, + str = '', + w = d[0]; - w = d[i]; - ws = w + ''; + if (indexOfLastWord > 0) { + str += w; + for (i = 1; i < indexOfLastWord; i++) { + ws = d[i] + ''; k = LOG_BASE - ws.length; if (k) str += getZeroString(k); - } else if (w === 0) { - return '0'; + str += ws; } - // Remove trailing zeros of last w. - for (; w % 10 === 0;) w /= 10; - - return str + w; + w = d[i]; + ws = w + ''; + k = LOG_BASE - ws.length; + if (k) str += getZeroString(k); + } else if (w === 0) { + return '0'; } + // Remove trailing zeros of last w. + for (; w % 10 === 0;) w /= 10; - function checkInt32(i, min, max) { - if (i !== ~~i || i < min || i > max) { - throw Error(invalidArgument + i); - } + return str + w; +} + + +function checkInt32(i, min, max) { + if (i !== ~~i || i < min || i > max) { + throw Error(invalidArgument + i); } +} - /* - * Check 5 rounding digits if `repeating` is null, 4 otherwise. - * `repeating == null` if caller is `log` or `pow`, - * `repeating != null` if caller is `naturalLogarithm` or `naturalExponential`. - */ - function checkRoundingDigits(d, i, rm, repeating) { - var di, k, r, rd; +/* + * Check 5 rounding digits if `repeating` is null, 4 otherwise. + * `repeating == null` if caller is `log` or `pow`, + * `repeating != null` if caller is `naturalLogarithm` or `naturalExponential`. + */ +function checkRoundingDigits(d, i, rm, repeating) { + var di, k, r, rd; - // Get the length of the first word of the array d. - for (k = d[0]; k >= 10; k /= 10) --i; + // Get the length of the first word of the array d. + for (k = d[0]; k >= 10; k /= 10) --i; - // Is the rounding digit in the first word of d? - if (--i < 0) { - i += LOG_BASE; - di = 0; - } else { - di = Math.ceil((i + 1) / LOG_BASE); - i %= LOG_BASE; - } + // Is the rounding digit in the first word of d? + if (--i < 0) { + i += LOG_BASE; + di = 0; + } else { + di = Math.ceil((i + 1) / LOG_BASE); + i %= LOG_BASE; + } - // i is the index (0 - 6) of the rounding digit. - // E.g. if within the word 3487563 the first rounding digit is 5, - // then i = 4, k = 1000, rd = 3487563 % 1000 = 563 - k = mathpow(10, LOG_BASE - i); - rd = d[di] % k | 0; + // i is the index (0 - 6) of the rounding digit. + // E.g. if within the word 3487563 the first rounding digit is 5, + // then i = 4, k = 1000, rd = 3487563 % 1000 = 563 + k = mathpow(10, LOG_BASE - i); + rd = d[di] % k | 0; - if (repeating == null) { - if (i < 3) { - if (i == 0) rd = rd / 100 | 0; - else if (i == 1) rd = rd / 10 | 0; - r = rm < 4 && rd == 99999 || rm > 3 && rd == 49999 || rd == 50000 || rd == 0; - } else { - r = (rm < 4 && rd + 1 == k || rm > 3 && rd + 1 == k / 2) && - (d[di + 1] / k / 100 | 0) == mathpow(10, i - 2) - 1 || - (rd == k / 2 || rd == 0) && (d[di + 1] / k / 100 | 0) == 0; - } + if (repeating == null) { + if (i < 3) { + if (i == 0) rd = rd / 100 | 0; + else if (i == 1) rd = rd / 10 | 0; + r = rm < 4 && rd == 99999 || rm > 3 && rd == 49999 || rd == 50000 || rd == 0; } else { - if (i < 4) { - if (i == 0) rd = rd / 1000 | 0; - else if (i == 1) rd = rd / 100 | 0; - else if (i == 2) rd = rd / 10 | 0; - r = (repeating || rm < 4) && rd == 9999 || !repeating && rm > 3 && rd == 4999; - } else { - r = ((repeating || rm < 4) && rd + 1 == k || - (!repeating && rm > 3) && rd + 1 == k / 2) && - (d[di + 1] / k / 1000 | 0) == mathpow(10, i - 3) - 1; - } + r = (rm < 4 && rd + 1 == k || rm > 3 && rd + 1 == k / 2) && + (d[di + 1] / k / 100 | 0) == mathpow(10, i - 2) - 1 || + (rd == k / 2 || rd == 0) && (d[di + 1] / k / 100 | 0) == 0; + } + } else { + if (i < 4) { + if (i == 0) rd = rd / 1000 | 0; + else if (i == 1) rd = rd / 100 | 0; + else if (i == 2) rd = rd / 10 | 0; + r = (repeating || rm < 4) && rd == 9999 || !repeating && rm > 3 && rd == 4999; + } else { + r = ((repeating || rm < 4) && rd + 1 == k || + (!repeating && rm > 3) && rd + 1 == k / 2) && + (d[di + 1] / k / 1000 | 0) == mathpow(10, i - 3) - 1; } - - return r; } + return r; +} - // Convert string of `baseIn` to an array of numbers of `baseOut`. - // Eg. convertBase('255', 10, 16) returns [15, 15]. - // Eg. convertBase('ff', 16, 10) returns [2, 5, 5]. - function convertBase(str, baseIn, baseOut) { - var j, - arr = [0], - arrL, - i = 0, - strL = str.length; - for (; i < strL;) { - for (arrL = arr.length; arrL--;) arr[arrL] *= baseIn; - arr[0] += NUMERALS.indexOf(str.charAt(i++)); - for (j = 0; j < arr.length; j++) { - if (arr[j] > baseOut - 1) { - if (arr[j + 1] === void 0) arr[j + 1] = 0; - arr[j + 1] += arr[j] / baseOut | 0; - arr[j] %= baseOut; - } +// Convert string of `baseIn` to an array of numbers of `baseOut`. +// Eg. convertBase('255', 10, 16) returns [15, 15]. +// Eg. convertBase('ff', 16, 10) returns [2, 5, 5]. +function convertBase(str, baseIn, baseOut) { + var j, + arr = [0], + arrL, + i = 0, + strL = str.length; + + for (; i < strL;) { + for (arrL = arr.length; arrL--;) arr[arrL] *= baseIn; + arr[0] += NUMERALS.indexOf(str.charAt(i++)); + for (j = 0; j < arr.length; j++) { + if (arr[j] > baseOut - 1) { + if (arr[j + 1] === void 0) arr[j + 1] = 0; + arr[j + 1] += arr[j] / baseOut | 0; + arr[j] %= baseOut; } } + } + + return arr.reverse(); +} + + +/* + * cos(x) = 1 - x^2/2! + x^4/4! - ... + * |x| < pi/2 + * + */ +function cosine(Ctor, x) { + var k, y, + len = x.d.length; + + // Argument reduction: cos(4x) = 8*(cos^4(x) - cos^2(x)) + 1 + // i.e. cos(x) = 8*(cos^4(x/4) - cos^2(x/4)) + 1 - return arr.reverse(); + // Estimate the optimum number of times to use the argument reduction. + if (len < 32) { + k = Math.ceil(len / 3); + y = Math.pow(4, -k).toString(); + } else { + k = 16; + y = '2.3283064365386962890625e-10'; } + Ctor.precision += k; - /* - * cos(x) = 1 - x^2/2! + x^4/4! - ... - * |x| < pi/2 - * - */ - function cosine(Ctor, x) { - var k, y, - len = x.d.length; + x = taylorSeries(Ctor, 1, x.times(y), new Ctor(1)); - // Argument reduction: cos(4x) = 8*(cos^4(x) - cos^2(x)) + 1 - // i.e. cos(x) = 8*(cos^4(x/4) - cos^2(x/4)) + 1 + // Reverse argument reduction + for (var i = k; i--;) { + var cos2x = x.times(x); + x = cos2x.times(cos2x).minus(cos2x).times(8).plus(1); + } - // Estimate the optimum number of times to use the argument reduction. - if (len < 32) { - k = Math.ceil(len / 3); - y = Math.pow(4, -k).toString(); - } else { - k = 16; - y = '2.3283064365386962890625e-10'; - } + Ctor.precision -= k; - Ctor.precision += k; + return x; +} - x = taylorSeries(Ctor, 1, x.times(y), new Ctor(1)); - // Reverse argument reduction - for (var i = k; i--;) { - var cos2x = x.times(x); - x = cos2x.times(cos2x).minus(cos2x).times(8).plus(1); +/* + * Perform division in the specified base. + */ +var divide = (function () { + + // Assumes non-zero x and k, and hence non-zero result. + function multiplyInteger(x, k, base) { + var temp, + carry = 0, + i = x.length; + + for (x = x.slice(); i--;) { + temp = x[i] * k + carry; + x[i] = temp % base | 0; + carry = temp / base | 0; } - Ctor.precision -= k; + if (carry) x.unshift(carry); return x; } + function compare(a, b, aL, bL) { + var i, r; - /* - * Perform division in the specified base. - */ - var divide = (function () { - - // Assumes non-zero x and k, and hence non-zero result. - function multiplyInteger(x, k, base) { - var temp, - carry = 0, - i = x.length; - - for (x = x.slice(); i--;) { - temp = x[i] * k + carry; - x[i] = temp % base | 0; - carry = temp / base | 0; + if (aL != bL) { + r = aL > bL ? 1 : -1; + } else { + for (i = r = 0; i < aL; i++) { + if (a[i] != b[i]) { + r = a[i] > b[i] ? 1 : -1; + break; + } } + } - if (carry) x.unshift(carry); + return r; + } - return x; + function subtract(a, b, aL, base) { + var i = 0; + + // Subtract b from a. + for (; aL--;) { + a[aL] -= i; + i = a[aL] < b[aL] ? 1 : 0; + a[aL] = i * base + a[aL] - b[aL]; } - function compare(a, b, aL, bL) { - var i, r; + // Remove leading zeros. + for (; !a[0] && a.length > 1;) a.shift(); + } - if (aL != bL) { - r = aL > bL ? 1 : -1; - } else { - for (i = r = 0; i < aL; i++) { - if (a[i] != b[i]) { - r = a[i] > b[i] ? 1 : -1; - break; - } - } - } + return function (x, y, pr, rm, dp, base) { + var cmp, e, i, k, logBase, more, prod, prodL, q, qd, rem, remL, rem0, sd, t, xi, xL, yd0, + yL, yz, + Ctor = x.constructor, + sign = x.s == y.s ? 1 : -1, + xd = x.d, + yd = y.d; - return r; - } + // Either NaN, Infinity or 0? + if (!xd || !xd[0] || !yd || !yd[0]) { - function subtract(a, b, aL, base) { - var i = 0; + return new Ctor(// Return NaN if either NaN, or both Infinity or 0. + !x.s || !y.s || (xd ? yd && xd[0] == yd[0] : !yd) ? NaN : - // Subtract b from a. - for (; aL--;) { - a[aL] -= i; - i = a[aL] < b[aL] ? 1 : 0; - a[aL] = i * base + a[aL] - b[aL]; - } + // Return ±0 if x is 0 or y is ±Infinity, or return ±Infinity as y is 0. + xd && xd[0] == 0 || !yd ? sign * 0 : sign / 0); + } - // Remove leading zeros. - for (; !a[0] && a.length > 1;) a.shift(); + if (base) { + logBase = 1; + e = x.e - y.e; + } else { + base = BASE; + logBase = LOG_BASE; + e = mathfloor(x.e / logBase) - mathfloor(y.e / logBase); } - return function (x, y, pr, rm, dp, base) { - var cmp, e, i, k, logBase, more, prod, prodL, q, qd, rem, remL, rem0, sd, t, xi, xL, yd0, - yL, yz, - Ctor = x.constructor, - sign = x.s == y.s ? 1 : -1, - xd = x.d, - yd = y.d; + yL = yd.length; + xL = xd.length; + q = new Ctor(sign); + qd = q.d = []; - // Either NaN, Infinity or 0? - if (!xd || !xd[0] || !yd || !yd[0]) { + // Result exponent may be one less than e. + // The digit array of a Decimal from toStringBinary may have trailing zeros. + for (i = 0; yd[i] == (xd[i] || 0); i++); - return new Ctor(// Return NaN if either NaN, or both Infinity or 0. - !x.s || !y.s || (xd ? yd && xd[0] == yd[0] : !yd) ? NaN : + if (yd[i] > (xd[i] || 0)) e--; - // Return ±0 if x is 0 or y is ±Infinity, or return ±Infinity as y is 0. - xd && xd[0] == 0 || !yd ? sign * 0 : sign / 0); - } + if (pr == null) { + sd = pr = Ctor.precision; + rm = Ctor.rounding; + } else if (dp) { + sd = pr + (x.e - y.e) + 1; + } else { + sd = pr; + } - if (base) { - logBase = 1; - e = x.e - y.e; - } else { - base = BASE; - logBase = LOG_BASE; - e = mathfloor(x.e / logBase) - mathfloor(y.e / logBase); - } + if (sd < 0) { + qd.push(1); + more = true; + } else { + + // Convert precision in number of base 10 digits to base 1e7 digits. + sd = sd / logBase + 2 | 0; + i = 0; - yL = yd.length; - xL = xd.length; - q = new Ctor(sign); - qd = q.d = []; + // divisor < 1e7 + if (yL == 1) { + k = 0; + yd = yd[0]; + sd++; - // Result exponent may be one less than e. - // The digit array of a Decimal from toStringBinary may have trailing zeros. - for (i = 0; yd[i] == (xd[i] || 0); i++); + // k is the carry. + for (; (i < xL || k) && sd--; i++) { + t = k * base + (xd[i] || 0); + qd[i] = t / yd | 0; + k = t % yd | 0; + } - if (yd[i] > (xd[i] || 0)) e--; + more = k || i < xL; - if (pr == null) { - sd = pr = Ctor.precision; - rm = Ctor.rounding; - } else if (dp) { - sd = pr + (x.e - y.e) + 1; + // divisor >= 1e7 } else { - sd = pr; - } - if (sd < 0) { - qd.push(1); - more = true; - } else { + // Normalise xd and yd so highest order digit of yd is >= base/2 + k = base / (yd[0] + 1) | 0; - // Convert precision in number of base 10 digits to base 1e7 digits. - sd = sd / logBase + 2 | 0; - i = 0; + if (k > 1) { + yd = multiplyInteger(yd, k, base); + xd = multiplyInteger(xd, k, base); + yL = yd.length; + xL = xd.length; + } - // divisor < 1e7 - if (yL == 1) { - k = 0; - yd = yd[0]; - sd++; - - // k is the carry. - for (; (i < xL || k) && sd--; i++) { - t = k * base + (xd[i] || 0); - qd[i] = t / yd | 0; - k = t % yd | 0; - } + xi = yL; + rem = xd.slice(0, yL); + remL = rem.length; - more = k || i < xL; + // Add zeros to make remainder as long as divisor. + for (; remL < yL;) rem[remL++] = 0; - // divisor >= 1e7 - } else { + yz = yd.slice(); + yz.unshift(0); + yd0 = yd[0]; - // Normalise xd and yd so highest order digit of yd is >= base/2 - k = base / (yd[0] + 1) | 0; + if (yd[1] >= base / 2) ++yd0; - if (k > 1) { - yd = multiplyInteger(yd, k, base); - xd = multiplyInteger(xd, k, base); - yL = yd.length; - xL = xd.length; - } + do { + k = 0; - xi = yL; - rem = xd.slice(0, yL); - remL = rem.length; + // Compare divisor and remainder. + cmp = compare(yd, rem, yL, remL); - // Add zeros to make remainder as long as divisor. - for (; remL < yL;) rem[remL++] = 0; + // If divisor < remainder. + if (cmp < 0) { - yz = yd.slice(); - yz.unshift(0); - yd0 = yd[0]; + // Calculate trial digit, k. + rem0 = rem[0]; + if (yL != remL) rem0 = rem0 * base + (rem[1] || 0); - if (yd[1] >= base / 2) ++yd0; + // k will be how many times the divisor goes into the current remainder. + k = rem0 / yd0 | 0; - do { - k = 0; + // Algorithm: + // 1. product = divisor * trial digit (k) + // 2. if product > remainder: product -= divisor, k-- + // 3. remainder -= product + // 4. if product was < remainder at 2: + // 5. compare new remainder and divisor + // 6. If remainder > divisor: remainder -= divisor, k++ - // Compare divisor and remainder. - cmp = compare(yd, rem, yL, remL); + if (k > 1) { + if (k >= base) k = base - 1; - // If divisor < remainder. - if (cmp < 0) { + // product = divisor * trial digit. + prod = multiplyInteger(yd, k, base); + prodL = prod.length; + remL = rem.length; - // Calculate trial digit, k. - rem0 = rem[0]; - if (yL != remL) rem0 = rem0 * base + (rem[1] || 0); + // Compare product and remainder. + cmp = compare(prod, rem, prodL, remL); - // k will be how many times the divisor goes into the current remainder. - k = rem0 / yd0 | 0; + // product > remainder. + if (cmp == 1) { + k--; + + // Subtract divisor from product. + subtract(prod, yL < prodL ? yz : yd, prodL, base); + } + } else { - // Algorithm: - // 1. product = divisor * trial digit (k) - // 2. if product > remainder: product -= divisor, k-- - // 3. remainder -= product - // 4. if product was < remainder at 2: - // 5. compare new remainder and divisor - // 6. If remainder > divisor: remainder -= divisor, k++ + // cmp is -1. + // If k is 0, there is no need to compare yd and rem again below, so change cmp to 1 + // to avoid it. If k is 1 there is a need to compare yd and rem again below. + if (k == 0) cmp = k = 1; + prod = yd.slice(); + } - if (k > 1) { - if (k >= base) k = base - 1; + prodL = prod.length; + if (prodL < remL) prod.unshift(0); - // product = divisor * trial digit. - prod = multiplyInteger(yd, k, base); - prodL = prod.length; - remL = rem.length; + // Subtract product from remainder. + subtract(rem, prod, remL, base); - // Compare product and remainder. - cmp = compare(prod, rem, prodL, remL); + // If product was < previous remainder. + if (cmp == -1) { + remL = rem.length; - // product > remainder. - if (cmp == 1) { - k--; + // Compare divisor and new remainder. + cmp = compare(yd, rem, yL, remL); - // Subtract divisor from product. - subtract(prod, yL < prodL ? yz : yd, prodL, base); - } - } else { + // If divisor < new remainder, subtract divisor from remainder. + if (cmp < 1) { + k++; - // cmp is -1. - // If k is 0, there is no need to compare yd and rem again below, so change cmp to 1 - // to avoid it. If k is 1 there is a need to compare yd and rem again below. - if (k == 0) cmp = k = 1; - prod = yd.slice(); + // Subtract divisor from remainder. + subtract(rem, yL < remL ? yz : yd, remL, base); } + } - prodL = prod.length; - if (prodL < remL) prod.unshift(0); - - // Subtract product from remainder. - subtract(rem, prod, remL, base); + remL = rem.length; + } else if (cmp === 0) { + k++; + rem = [0]; + } // if cmp === 1, k will be 0 - // If product was < previous remainder. - if (cmp == -1) { - remL = rem.length; + // Add the next digit, k, to the result array. + qd[i++] = k; - // Compare divisor and new remainder. - cmp = compare(yd, rem, yL, remL); + // Update the remainder. + if (cmp && rem[0]) { + rem[remL++] = xd[xi] || 0; + } else { + rem = [xd[xi]]; + remL = 1; + } - // If divisor < new remainder, subtract divisor from remainder. - if (cmp < 1) { - k++; + } while ((xi++ < xL || rem[0] !== void 0) && sd--); - // Subtract divisor from remainder. - subtract(rem, yL < remL ? yz : yd, remL, base); - } - } + more = rem[0] !== void 0; + } - remL = rem.length; - } else if (cmp === 0) { - k++; - rem = [0]; - } // if cmp === 1, k will be 0 + // Leading zero? + if (!qd[0]) qd.shift(); + } - // Add the next digit, k, to the result array. - qd[i++] = k; + // logBase is 1 when divide is being used for base conversion. + if (logBase == 1) { + q.e = e; + inexact = more; + } else { - // Update the remainder. - if (cmp && rem[0]) { - rem[remL++] = xd[xi] || 0; - } else { - rem = [xd[xi]]; - remL = 1; - } + // To calculate q.e, first get the number of digits of qd[0]. + for (i = 1, k = qd[0]; k >= 10; k /= 10) i++; + q.e = i + e * logBase - 1; - } while ((xi++ < xL || rem[0] !== void 0) && sd--); + finalise(q, dp ? pr + q.e + 1 : pr, rm, more); + } - more = rem[0] !== void 0; - } + return q; + }; +})(); - // Leading zero? - if (!qd[0]) qd.shift(); - } - // logBase is 1 when divide is being used for base conversion. - if (logBase == 1) { - q.e = e; - inexact = more; - } else { +/* + * Round `x` to `sd` significant digits using rounding mode `rm`. + * Check for over/under-flow. + */ + function finalise(x, sd, rm, isTruncated) { + var digits, i, j, k, rd, roundUp, w, xd, xdi, + Ctor = x.constructor; - // To calculate q.e, first get the number of digits of qd[0]. - for (i = 1, k = qd[0]; k >= 10; k /= 10) i++; - q.e = i + e * logBase - 1; + // Don't round if sd is null or undefined. + out: if (sd != null) { + xd = x.d; - finalise(q, dp ? pr + q.e + 1 : pr, rm, more); - } + // Infinity/NaN. + if (!xd) return x; - return q; - }; - })(); + // rd: the rounding digit, i.e. the digit after the digit that may be rounded up. + // w: the word of xd containing rd, a base 1e7 number. + // xdi: the index of w within xd. + // digits: the number of digits of w. + // i: what would be the index of rd within w if all the numbers were 7 digits long (i.e. if + // they had leading zeros) + // j: if > 0, the actual index of rd within w (if < 0, rd is a leading zero). + // Get the length of the first word of the digits array xd. + for (digits = 1, k = xd[0]; k >= 10; k /= 10) digits++; + i = sd - digits; - /* - * Round `x` to `sd` significant digits using rounding mode `rm`. - * Check for over/under-flow. - */ - function finalise(x, sd, rm, isTruncated) { - var digits, i, j, k, rd, roundUp, w, xd, xdi, - Ctor = x.constructor; - - // Don't round if sd is null or undefined. - out: if (sd != null) { - xd = x.d; - - // Infinity/NaN. - if (!xd) return x; - - // rd: the rounding digit, i.e. the digit after the digit that may be rounded up. - // w: the word of xd containing rd, a base 1e7 number. - // xdi: the index of w within xd. - // digits: the number of digits of w. - // i: what would be the index of rd within w if all the numbers were 7 digits long (i.e. if - // they had leading zeros) - // j: if > 0, the actual index of rd within w (if < 0, rd is a leading zero). - - // Get the length of the first word of the digits array xd. - for (digits = 1, k = xd[0]; k >= 10; k /= 10) digits++; - i = sd - digits; - - // Is the rounding digit in the first word of xd? - if (i < 0) { - i += LOG_BASE; - j = sd; - w = xd[xdi = 0]; + // Is the rounding digit in the first word of xd? + if (i < 0) { + i += LOG_BASE; + j = sd; + w = xd[xdi = 0]; - // Get the rounding digit at index j of w. - rd = w / mathpow(10, digits - j - 1) % 10 | 0; - } else { - xdi = Math.ceil((i + 1) / LOG_BASE); - k = xd.length; - if (xdi >= k) { - if (isTruncated) { - - // Needed by `naturalExponential`, `naturalLogarithm` and `squareRoot`. - for (; k++ <= xdi;) xd.push(0); - w = rd = 0; - digits = 1; - i %= LOG_BASE; - j = i - LOG_BASE + 1; - } else { - break out; - } + // Get the rounding digit at index j of w. + rd = w / mathpow(10, digits - j - 1) % 10 | 0; + } else { + xdi = Math.ceil((i + 1) / LOG_BASE); + k = xd.length; + if (xdi >= k) { + if (isTruncated) { + + // Needed by `naturalExponential`, `naturalLogarithm` and `squareRoot`. + for (; k++ <= xdi;) xd.push(0); + w = rd = 0; + digits = 1; + i %= LOG_BASE; + j = i - LOG_BASE + 1; } else { - w = k = xd[xdi]; + break out; + } + } else { + w = k = xd[xdi]; - // Get the number of digits of w. - for (digits = 1; k >= 10; k /= 10) digits++; + // Get the number of digits of w. + for (digits = 1; k >= 10; k /= 10) digits++; - // Get the index of rd within w. - i %= LOG_BASE; + // Get the index of rd within w. + i %= LOG_BASE; - // Get the index of rd within w, adjusted for leading zeros. - // The number of leading zeros of w is given by LOG_BASE - digits. - j = i - LOG_BASE + digits; + // Get the index of rd within w, adjusted for leading zeros. + // The number of leading zeros of w is given by LOG_BASE - digits. + j = i - LOG_BASE + digits; - // Get the rounding digit at index j of w. - rd = j < 0 ? 0 : w / mathpow(10, digits - j - 1) % 10 | 0; - } + // Get the rounding digit at index j of w. + rd = j < 0 ? 0 : w / mathpow(10, digits - j - 1) % 10 | 0; } + } - // Are there any non-zero digits after the rounding digit? - isTruncated = isTruncated || sd < 0 || - xd[xdi + 1] !== void 0 || (j < 0 ? w : w % mathpow(10, digits - j - 1)); - - // The expression `w % mathpow(10, digits - j - 1)` returns all the digits of w to the right - // of the digit at (left-to-right) index j, e.g. if w is 908714 and j is 2, the expression - // will give 714. + // Are there any non-zero digits after the rounding digit? + isTruncated = isTruncated || sd < 0 || + xd[xdi + 1] !== void 0 || (j < 0 ? w : w % mathpow(10, digits - j - 1)); - roundUp = rm < 4 - ? (rd || isTruncated) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) - : rd > 5 || rd == 5 && (rm == 4 || isTruncated || rm == 6 && + // The expression `w % mathpow(10, digits - j - 1)` returns all the digits of w to the right + // of the digit at (left-to-right) index j, e.g. if w is 908714 and j is 2, the expression + // will give 714. - // Check whether the digit to the left of the rounding digit is odd. - ((i > 0 ? j > 0 ? w / mathpow(10, digits - j) : 0 : xd[xdi - 1]) % 10) & 1 || - rm == (x.s < 0 ? 8 : 7)); + roundUp = rm < 4 + ? (rd || isTruncated) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) + : rd > 5 || rd == 5 && (rm == 4 || isTruncated || rm == 6 && - if (sd < 1 || !xd[0]) { - xd.length = 0; - if (roundUp) { + // Check whether the digit to the left of the rounding digit is odd. + ((i > 0 ? j > 0 ? w / mathpow(10, digits - j) : 0 : xd[xdi - 1]) % 10) & 1 || + rm == (x.s < 0 ? 8 : 7)); - // Convert sd to decimal places. - sd -= x.e + 1; + if (sd < 1 || !xd[0]) { + xd.length = 0; + if (roundUp) { - // 1, 0.1, 0.01, 0.001, 0.0001 etc. - xd[0] = mathpow(10, (LOG_BASE - sd % LOG_BASE) % LOG_BASE); - x.e = -sd || 0; - } else { + // Convert sd to decimal places. + sd -= x.e + 1; - // Zero. - xd[0] = x.e = 0; - } + // 1, 0.1, 0.01, 0.001, 0.0001 etc. + xd[0] = mathpow(10, (LOG_BASE - sd % LOG_BASE) % LOG_BASE); + x.e = -sd || 0; + } else { - return x; + // Zero. + xd[0] = x.e = 0; } - // Remove excess digits. - if (i == 0) { - xd.length = xdi; - k = 1; - xdi--; - } else { - xd.length = xdi + 1; - k = mathpow(10, LOG_BASE - i); + return x; + } - // E.g. 56700 becomes 56000 if 7 is the rounding digit. - // j > 0 means i > number of leading zeros of w. - xd[xdi] = j > 0 ? (w / mathpow(10, digits - j) % mathpow(10, j) | 0) * k : 0; - } + // Remove excess digits. + if (i == 0) { + xd.length = xdi; + k = 1; + xdi--; + } else { + xd.length = xdi + 1; + k = mathpow(10, LOG_BASE - i); - if (roundUp) { - for (;;) { + // E.g. 56700 becomes 56000 if 7 is the rounding digit. + // j > 0 means i > number of leading zeros of w. + xd[xdi] = j > 0 ? (w / mathpow(10, digits - j) % mathpow(10, j) | 0) * k : 0; + } - // Is the digit to be rounded up in the first word of xd? - if (xdi == 0) { + if (roundUp) { + for (;;) { - // i will be the length of xd[0] before k is added. - for (i = 1, j = xd[0]; j >= 10; j /= 10) i++; - j = xd[0] += k; - for (k = 1; j >= 10; j /= 10) k++; + // Is the digit to be rounded up in the first word of xd? + if (xdi == 0) { - // if i != k the length has increased. - if (i != k) { - x.e++; - if (xd[0] == BASE) xd[0] = 1; - } + // i will be the length of xd[0] before k is added. + for (i = 1, j = xd[0]; j >= 10; j /= 10) i++; + j = xd[0] += k; + for (k = 1; j >= 10; j /= 10) k++; - break; - } else { - xd[xdi] += k; - if (xd[xdi] != BASE) break; - xd[xdi--] = 0; - k = 1; + // if i != k the length has increased. + if (i != k) { + x.e++; + if (xd[0] == BASE) xd[0] = 1; } + + break; + } else { + xd[xdi] += k; + if (xd[xdi] != BASE) break; + xd[xdi--] = 0; + k = 1; } } - - // Remove trailing zeros. - for (i = xd.length; xd[--i] === 0;) xd.pop(); } - if (external) { + // Remove trailing zeros. + for (i = xd.length; xd[--i] === 0;) xd.pop(); + } - // Overflow? - if (x.e > Ctor.maxE) { + if (external) { - // Infinity. - x.d = null; - x.e = NaN; + // Overflow? + if (x.e > Ctor.maxE) { - // Underflow? - } else if (x.e < Ctor.minE) { + // Infinity. + x.d = null; + x.e = NaN; - // Zero. - x.e = 0; - x.d = [0]; - // Ctor.underflow = true; - } // else Ctor.underflow = false; - } + // Underflow? + } else if (x.e < Ctor.minE) { - return x; + // Zero. + x.e = 0; + x.d = [0]; + // Ctor.underflow = true; + } // else Ctor.underflow = false; } + return x; +} - function finiteToString(x, isExp, sd) { - if (!x.isFinite()) return nonFiniteToString(x); - var k, - e = x.e, - str = digitsToString(x.d), - len = str.length; - if (isExp) { - if (sd && (k = sd - len) > 0) { - str = str.charAt(0) + '.' + str.slice(1) + getZeroString(k); - } else if (len > 1) { - str = str.charAt(0) + '.' + str.slice(1); - } +function finiteToString(x, isExp, sd) { + if (!x.isFinite()) return nonFiniteToString(x); + var k, + e = x.e, + str = digitsToString(x.d), + len = str.length; - str = str + (x.e < 0 ? 'e' : 'e+') + x.e; - } else if (e < 0) { - str = '0.' + getZeroString(-e - 1) + str; - if (sd && (k = sd - len) > 0) str += getZeroString(k); - } else if (e >= len) { - str += getZeroString(e + 1 - len); - if (sd && (k = sd - e - 1) > 0) str = str + '.' + getZeroString(k); - } else { - if ((k = e + 1) < len) str = str.slice(0, k) + '.' + str.slice(k); - if (sd && (k = sd - len) > 0) { - if (e + 1 === len) str += '.'; - str += getZeroString(k); - } + if (isExp) { + if (sd && (k = sd - len) > 0) { + str = str.charAt(0) + '.' + str.slice(1) + getZeroString(k); + } else if (len > 1) { + str = str.charAt(0) + '.' + str.slice(1); } - return str; + str = str + (x.e < 0 ? 'e' : 'e+') + x.e; + } else if (e < 0) { + str = '0.' + getZeroString(-e - 1) + str; + if (sd && (k = sd - len) > 0) str += getZeroString(k); + } else if (e >= len) { + str += getZeroString(e + 1 - len); + if (sd && (k = sd - e - 1) > 0) str = str + '.' + getZeroString(k); + } else { + if ((k = e + 1) < len) str = str.slice(0, k) + '.' + str.slice(k); + if (sd && (k = sd - len) > 0) { + if (e + 1 === len) str += '.'; + str += getZeroString(k); + } } + return str; +} - // Calculate the base 10 exponent from the base 1e7 exponent. - function getBase10Exponent(digits, e) { - var w = digits[0]; - - // Add the number of digits of the first word of the digits array. - for ( e *= LOG_BASE; w >= 10; w /= 10) e++; - return e; - } +// Calculate the base 10 exponent from the base 1e7 exponent. +function getBase10Exponent(digits, e) { + var w = digits[0]; - function getLn10(Ctor, sd, pr) { - if (sd > LN10_PRECISION) { + // Add the number of digits of the first word of the digits array. + for ( e *= LOG_BASE; w >= 10; w /= 10) e++; + return e; +} - // Reset global state in case the exception is caught. - external = true; - if (pr) Ctor.precision = pr; - throw Error(precisionLimitExceeded); - } - return finalise(new Ctor(LN10), sd, 1, true); - } +function getLn10(Ctor, sd, pr) { + if (sd > LN10_PRECISION) { - function getPi(Ctor, sd, rm) { - if (sd > PI_PRECISION) throw Error(precisionLimitExceeded); - return finalise(new Ctor(PI), sd, rm, true); + // Reset global state in case the exception is caught. + external = true; + if (pr) Ctor.precision = pr; + throw Error(precisionLimitExceeded); } + return finalise(new Ctor(LN10), sd, 1, true); +} - function getPrecision(digits) { - var w = digits.length - 1, - len = w * LOG_BASE + 1; - - w = digits[w]; +function getPi(Ctor, sd, rm) { + if (sd > PI_PRECISION) throw Error(precisionLimitExceeded); + return finalise(new Ctor(PI), sd, rm, true); +} - // If non-zero... - if (w) { - // Subtract the number of trailing zeros of the last word. - for (; w % 10 == 0; w /= 10) len--; +function getPrecision(digits) { + var w = digits.length - 1, + len = w * LOG_BASE + 1; - // Add the number of digits of the first word. - for (w = digits[0]; w >= 10; w /= 10) len++; - } + w = digits[w]; - return len; - } + // If non-zero... + if (w) { + // Subtract the number of trailing zeros of the last word. + for (; w % 10 == 0; w /= 10) len--; - function getZeroString(k) { - var zs = ''; - for (; k--;) zs += '0'; - return zs; + // Add the number of digits of the first word. + for (w = digits[0]; w >= 10; w /= 10) len++; } + return len; +} - /* - * Return a new Decimal whose value is the value of Decimal `x` to the power `n`, where `n` is an - * integer of type number. - * - * Implements 'exponentiation by squaring'. Called by `pow` and `parseOther`. - * - */ - function intPow(Ctor, x, n, pr) { - var isTruncated, - r = new Ctor(1), - // Max n of 9007199254740991 takes 53 loop iterations. - // Maximum digits array length; leaves [28, 34] guard digits. - k = Math.ceil(pr / LOG_BASE + 4); +function getZeroString(k) { + var zs = ''; + for (; k--;) zs += '0'; + return zs; +} - external = false; - for (;;) { - if (n % 2) { - r = r.times(x); - if (truncate(r.d, k)) isTruncated = true; - } +/* + * Return a new Decimal whose value is the value of Decimal `x` to the power `n`, where `n` is an + * integer of type number. + * + * Implements 'exponentiation by squaring'. Called by `pow` and `parseOther`. + * + */ +function intPow(Ctor, x, n, pr) { + var isTruncated, + r = new Ctor(1), - n = mathfloor(n / 2); - if (n === 0) { + // Max n of 9007199254740991 takes 53 loop iterations. + // Maximum digits array length; leaves [28, 34] guard digits. + k = Math.ceil(pr / LOG_BASE + 4); - // To ensure correct rounding when r.d is truncated, increment the last word if it is zero. - n = r.d.length - 1; - if (isTruncated && r.d[n] === 0) ++r.d[n]; - break; - } + external = false; - x = x.times(x); - truncate(x.d, k); + for (;;) { + if (n % 2) { + r = r.times(x); + if (truncate(r.d, k)) isTruncated = true; } - external = true; - - return r; - } + n = mathfloor(n / 2); + if (n === 0) { + // To ensure correct rounding when r.d is truncated, increment the last word if it is zero. + n = r.d.length - 1; + if (isTruncated && r.d[n] === 0) ++r.d[n]; + break; + } - function isOdd(n) { - return n.d[n.d.length - 1] & 1; + x = x.times(x); + truncate(x.d, k); } + external = true; - /* - * Handle `max` and `min`. `ltgt` is 'lt' or 'gt'. - */ - function maxOrMin(Ctor, args, ltgt) { - var y, - x = new Ctor(args[0]), - i = 0; - - for (; ++i < args.length;) { - y = new Ctor(args[i]); - if (!y.s) { - x = y; - break; - } else if (x[ltgt](y)) { - x = y; - } - } + return r; +} - return x; - } +function isOdd(n) { + return n.d[n.d.length - 1] & 1; +} - /* - * Return a new Decimal whose value is the natural exponential of `x` rounded to `sd` significant - * digits. - * - * Taylor/Maclaurin series. - * - * exp(x) = x^0/0! + x^1/1! + x^2/2! + x^3/3! + ... - * - * Argument reduction: - * Repeat x = x / 32, k += 5, until |x| < 0.1 - * exp(x) = exp(x / 2^k)^(2^k) - * - * Previously, the argument was initially reduced by - * exp(x) = exp(r) * 10^k where r = x - k * ln10, k = floor(x / ln10) - * to first put r in the range [0, ln10], before dividing by 32 until |x| < 0.1, but this was - * found to be slower than just dividing repeatedly by 32 as above. - * - * Max integer argument: exp('20723265836946413') = 6.3e+9000000000000000 - * Min integer argument: exp('-20723265836946411') = 1.2e-9000000000000000 - * (Math object integer min/max: Math.exp(709) = 8.2e+307, Math.exp(-745) = 5e-324) - * - * exp(Infinity) = Infinity - * exp(-Infinity) = 0 - * exp(NaN) = NaN - * exp(±0) = 1 - * - * exp(x) is non-terminating for any finite, non-zero x. - * - * The result will always be correctly rounded. - * - */ - function naturalExponential(x, sd) { - var denominator, guard, j, pow, sum, t, wpr, - rep = 0, - i = 0, - k = 0, - Ctor = x.constructor, - rm = Ctor.rounding, - pr = Ctor.precision; - // 0/NaN/Infinity? - if (!x.d || !x.d[0] || x.e > 17) { +/* + * Handle `max` and `min`. `ltgt` is 'lt' or 'gt'. + */ +function maxOrMin(Ctor, args, ltgt) { + var y, + x = new Ctor(args[0]), + i = 0; - return new Ctor(x.d - ? !x.d[0] ? 1 : x.s < 0 ? 0 : 1 / 0 - : x.s ? x.s < 0 ? 0 : x : 0 / 0); + for (; ++i < args.length;) { + y = new Ctor(args[i]); + if (!y.s) { + x = y; + break; + } else if (x[ltgt](y)) { + x = y; } + } - if (sd == null) { - external = false; - wpr = pr; - } else { - wpr = sd; - } + return x; +} + + +/* + * Return a new Decimal whose value is the natural exponential of `x` rounded to `sd` significant + * digits. + * + * Taylor/Maclaurin series. + * + * exp(x) = x^0/0! + x^1/1! + x^2/2! + x^3/3! + ... + * + * Argument reduction: + * Repeat x = x / 32, k += 5, until |x| < 0.1 + * exp(x) = exp(x / 2^k)^(2^k) + * + * Previously, the argument was initially reduced by + * exp(x) = exp(r) * 10^k where r = x - k * ln10, k = floor(x / ln10) + * to first put r in the range [0, ln10], before dividing by 32 until |x| < 0.1, but this was + * found to be slower than just dividing repeatedly by 32 as above. + * + * Max integer argument: exp('20723265836946413') = 6.3e+9000000000000000 + * Min integer argument: exp('-20723265836946411') = 1.2e-9000000000000000 + * (Math object integer min/max: Math.exp(709) = 8.2e+307, Math.exp(-745) = 5e-324) + * + * exp(Infinity) = Infinity + * exp(-Infinity) = 0 + * exp(NaN) = NaN + * exp(±0) = 1 + * + * exp(x) is non-terminating for any finite, non-zero x. + * + * The result will always be correctly rounded. + * + */ +function naturalExponential(x, sd) { + var denominator, guard, j, pow, sum, t, wpr, + rep = 0, + i = 0, + k = 0, + Ctor = x.constructor, + rm = Ctor.rounding, + pr = Ctor.precision; - t = new Ctor(0.03125); + // 0/NaN/Infinity? + if (!x.d || !x.d[0] || x.e > 17) { - // while abs(x) >= 0.1 - while (x.e > -2) { + return new Ctor(x.d + ? !x.d[0] ? 1 : x.s < 0 ? 0 : 1 / 0 + : x.s ? x.s < 0 ? 0 : x : 0 / 0); + } - // x = x / 2^5 - x = x.times(t); - k += 5; - } + if (sd == null) { + external = false; + wpr = pr; + } else { + wpr = sd; + } - // Use 2 * log10(2^k) + 5 (empirically derived) to estimate the increase in precision - // necessary to ensure the first 4 rounding digits are correct. - guard = Math.log(mathpow(2, k)) / Math.LN10 * 2 + 5 | 0; - wpr += guard; - denominator = pow = sum = new Ctor(1); - Ctor.precision = wpr; + t = new Ctor(0.03125); - for (;;) { - pow = finalise(pow.times(x), wpr, 1); - denominator = denominator.times(++i); - t = sum.plus(divide(pow, denominator, wpr, 1)); + // while abs(x) >= 0.1 + while (x.e > -2) { - if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { - j = k; - while (j--) sum = finalise(sum.times(sum), wpr, 1); + // x = x / 2^5 + x = x.times(t); + k += 5; + } - // Check to see if the first 4 rounding digits are [49]999. - // If so, repeat the summation with a higher precision, otherwise - // e.g. with precision: 18, rounding: 1 - // exp(18.404272462595034083567793919843761) = 98372560.1229999999 (should be 98372560.123) - // `wpr - guard` is the index of first rounding digit. - if (sd == null) { + // Use 2 * log10(2^k) + 5 (empirically derived) to estimate the increase in precision + // necessary to ensure the first 4 rounding digits are correct. + guard = Math.log(mathpow(2, k)) / Math.LN10 * 2 + 5 | 0; + wpr += guard; + denominator = pow = sum = new Ctor(1); + Ctor.precision = wpr; - if (rep < 3 && checkRoundingDigits(sum.d, wpr - guard, rm, rep)) { - Ctor.precision = wpr += 10; - denominator = pow = t = new Ctor(1); - i = 0; - rep++; - } else { - return finalise(sum, Ctor.precision = pr, rm, external = true); - } + for (;;) { + pow = finalise(pow.times(x), wpr, 1); + denominator = denominator.times(++i); + t = sum.plus(divide(pow, denominator, wpr, 1)); + + if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { + j = k; + while (j--) sum = finalise(sum.times(sum), wpr, 1); + + // Check to see if the first 4 rounding digits are [49]999. + // If so, repeat the summation with a higher precision, otherwise + // e.g. with precision: 18, rounding: 1 + // exp(18.404272462595034083567793919843761) = 98372560.1229999999 (should be 98372560.123) + // `wpr - guard` is the index of first rounding digit. + if (sd == null) { + + if (rep < 3 && checkRoundingDigits(sum.d, wpr - guard, rm, rep)) { + Ctor.precision = wpr += 10; + denominator = pow = t = new Ctor(1); + i = 0; + rep++; } else { - Ctor.precision = pr; - return sum; + return finalise(sum, Ctor.precision = pr, rm, external = true); } + } else { + Ctor.precision = pr; + return sum; } - - sum = t; } + + sum = t; } +} - /* - * Return a new Decimal whose value is the natural logarithm of `x` rounded to `sd` significant - * digits. - * - * ln(-n) = NaN - * ln(0) = -Infinity - * ln(-0) = -Infinity - * ln(1) = 0 - * ln(Infinity) = Infinity - * ln(-Infinity) = NaN - * ln(NaN) = NaN - * - * ln(n) (n != 1) is non-terminating. - * - */ - function naturalLogarithm(y, sd) { - var c, c0, denominator, e, numerator, rep, sum, t, wpr, x1, x2, - n = 1, - guard = 10, - x = y, - xd = x.d, - Ctor = x.constructor, - rm = Ctor.rounding, - pr = Ctor.precision; +/* + * Return a new Decimal whose value is the natural logarithm of `x` rounded to `sd` significant + * digits. + * + * ln(-n) = NaN + * ln(0) = -Infinity + * ln(-0) = -Infinity + * ln(1) = 0 + * ln(Infinity) = Infinity + * ln(-Infinity) = NaN + * ln(NaN) = NaN + * + * ln(n) (n != 1) is non-terminating. + * + */ +function naturalLogarithm(y, sd) { + var c, c0, denominator, e, numerator, rep, sum, t, wpr, x1, x2, + n = 1, + guard = 10, + x = y, + xd = x.d, + Ctor = x.constructor, + rm = Ctor.rounding, + pr = Ctor.precision; + + // Is x negative or Infinity, NaN, 0 or 1? + if (x.s < 0 || !xd || !xd[0] || !x.e && xd[0] == 1 && xd.length == 1) { + return new Ctor(xd && !xd[0] ? -1 / 0 : x.s != 1 ? NaN : xd ? 0 : x); + } + + if (sd == null) { + external = false; + wpr = pr; + } else { + wpr = sd; + } + + Ctor.precision = wpr += guard; + c = digitsToString(xd); + c0 = c.charAt(0); - // Is x negative or Infinity, NaN, 0 or 1? - if (x.s < 0 || !xd || !xd[0] || !x.e && xd[0] == 1 && xd.length == 1) { - return new Ctor(xd && !xd[0] ? -1 / 0 : x.s != 1 ? NaN : xd ? 0 : x); + if (Math.abs(e = x.e) < 1.5e15) { + + // Argument reduction. + // The series converges faster the closer the argument is to 1, so using + // ln(a^b) = b * ln(a), ln(a) = ln(a^b) / b + // multiply the argument by itself until the leading digits of the significand are 7, 8, 9, + // 10, 11, 12 or 13, recording the number of multiplications so the sum of the series can + // later be divided by this number, then separate out the power of 10 using + // ln(a*10^b) = ln(a) + b*ln(10). + + // max n is 21 (gives 0.9, 1.0 or 1.1) (9e15 / 21 = 4.2e14). + //while (c0 < 9 && c0 != 1 || c0 == 1 && c.charAt(1) > 1) { + // max n is 6 (gives 0.7 - 1.3) + while (c0 < 7 && c0 != 1 || c0 == 1 && c.charAt(1) > 3) { + x = x.times(y); + c = digitsToString(x.d); + c0 = c.charAt(0); + n++; } - if (sd == null) { - external = false; - wpr = pr; + e = x.e; + + if (c0 > 1) { + x = new Ctor('0.' + c); + e++; } else { - wpr = sd; - } - - Ctor.precision = wpr += guard; - c = digitsToString(xd); - c0 = c.charAt(0); - - if (Math.abs(e = x.e) < 1.5e15) { - - // Argument reduction. - // The series converges faster the closer the argument is to 1, so using - // ln(a^b) = b * ln(a), ln(a) = ln(a^b) / b - // multiply the argument by itself until the leading digits of the significand are 7, 8, 9, - // 10, 11, 12 or 13, recording the number of multiplications so the sum of the series can - // later be divided by this number, then separate out the power of 10 using - // ln(a*10^b) = ln(a) + b*ln(10). - - // max n is 21 (gives 0.9, 1.0 or 1.1) (9e15 / 21 = 4.2e14). - //while (c0 < 9 && c0 != 1 || c0 == 1 && c.charAt(1) > 1) { - // max n is 6 (gives 0.7 - 1.3) - while (c0 < 7 && c0 != 1 || c0 == 1 && c.charAt(1) > 3) { - x = x.times(y); - c = digitsToString(x.d); - c0 = c.charAt(0); - n++; - } + x = new Ctor(c0 + '.' + c.slice(1)); + } + } else { - e = x.e; + // The argument reduction method above may result in overflow if the argument y is a massive + // number with exponent >= 1500000000000000 (9e15 / 6 = 1.5e15), so instead recall this + // function using ln(x*10^e) = ln(x) + e*ln(10). + t = getLn10(Ctor, wpr + 2, pr).times(e + ''); + x = naturalLogarithm(new Ctor(c0 + '.' + c.slice(1)), wpr - guard).plus(t); + Ctor.precision = pr; - if (c0 > 1) { - x = new Ctor('0.' + c); - e++; - } else { - x = new Ctor(c0 + '.' + c.slice(1)); - } - } else { + return sd == null ? finalise(x, pr, rm, external = true) : x; + } - // The argument reduction method above may result in overflow if the argument y is a massive - // number with exponent >= 1500000000000000 (9e15 / 6 = 1.5e15), so instead recall this - // function using ln(x*10^e) = ln(x) + e*ln(10). - t = getLn10(Ctor, wpr + 2, pr).times(e + ''); - x = naturalLogarithm(new Ctor(c0 + '.' + c.slice(1)), wpr - guard).plus(t); - Ctor.precision = pr; - - return sd == null ? finalise(x, pr, rm, external = true) : x; - } - - // x1 is x reduced to a value near 1. - x1 = x; - - // Taylor series. - // ln(y) = ln((1 + x)/(1 - x)) = 2(x + x^3/3 + x^5/5 + x^7/7 + ...) - // where x = (y - 1)/(y + 1) (|x| < 1) - sum = numerator = x = divide(x.minus(1), x.plus(1), wpr, 1); - x2 = finalise(x.times(x), wpr, 1); - denominator = 3; - - for (;;) { - numerator = finalise(numerator.times(x2), wpr, 1); - t = sum.plus(divide(numerator, new Ctor(denominator), wpr, 1)); - - if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { - sum = sum.times(2); - - // Reverse the argument reduction. Check that e is not 0 because, besides preventing an - // unnecessary calculation, -0 + 0 = +0 and to ensure correct rounding -0 needs to stay -0. - if (e !== 0) sum = sum.plus(getLn10(Ctor, wpr + 2, pr).times(e + '')); - sum = divide(sum, new Ctor(n), wpr, 1); - - // Is rm > 3 and the first 4 rounding digits 4999, or rm < 4 (or the summation has - // been repeated previously) and the first 4 rounding digits 9999? - // If so, restart the summation with a higher precision, otherwise - // e.g. with precision: 12, rounding: 1 - // ln(135520028.6126091714265381533) = 18.7246299999 when it should be 18.72463. - // `wpr - guard` is the index of first rounding digit. - if (sd == null) { - if (checkRoundingDigits(sum.d, wpr - guard, rm, rep)) { - Ctor.precision = wpr += guard; - t = numerator = x = divide(x1.minus(1), x1.plus(1), wpr, 1); - x2 = finalise(x.times(x), wpr, 1); - denominator = rep = 1; - } else { - return finalise(sum, Ctor.precision = pr, rm, external = true); - } + // x1 is x reduced to a value near 1. + x1 = x; + + // Taylor series. + // ln(y) = ln((1 + x)/(1 - x)) = 2(x + x^3/3 + x^5/5 + x^7/7 + ...) + // where x = (y - 1)/(y + 1) (|x| < 1) + sum = numerator = x = divide(x.minus(1), x.plus(1), wpr, 1); + x2 = finalise(x.times(x), wpr, 1); + denominator = 3; + + for (;;) { + numerator = finalise(numerator.times(x2), wpr, 1); + t = sum.plus(divide(numerator, new Ctor(denominator), wpr, 1)); + + if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { + sum = sum.times(2); + + // Reverse the argument reduction. Check that e is not 0 because, besides preventing an + // unnecessary calculation, -0 + 0 = +0 and to ensure correct rounding -0 needs to stay -0. + if (e !== 0) sum = sum.plus(getLn10(Ctor, wpr + 2, pr).times(e + '')); + sum = divide(sum, new Ctor(n), wpr, 1); + + // Is rm > 3 and the first 4 rounding digits 4999, or rm < 4 (or the summation has + // been repeated previously) and the first 4 rounding digits 9999? + // If so, restart the summation with a higher precision, otherwise + // e.g. with precision: 12, rounding: 1 + // ln(135520028.6126091714265381533) = 18.7246299999 when it should be 18.72463. + // `wpr - guard` is the index of first rounding digit. + if (sd == null) { + if (checkRoundingDigits(sum.d, wpr - guard, rm, rep)) { + Ctor.precision = wpr += guard; + t = numerator = x = divide(x1.minus(1), x1.plus(1), wpr, 1); + x2 = finalise(x.times(x), wpr, 1); + denominator = rep = 1; } else { - Ctor.precision = pr; - return sum; + return finalise(sum, Ctor.precision = pr, rm, external = true); } + } else { + Ctor.precision = pr; + return sum; } - - sum = t; - denominator += 2; } + + sum = t; + denominator += 2; } +} + + +// ±Infinity, NaN. +function nonFiniteToString(x) { + // Unsigned. + return String(x.s * x.s / 0); +} + +/* + * Parse the value of a new Decimal `x` from string `str`. + */ +function parseDecimal(x, str) { + var e, i, len; + + // Decimal point? + if ((e = str.indexOf('.')) > -1) str = str.replace('.', ''); + + // Exponential form? + if ((i = str.search(/e/i)) > 0) { - // ±Infinity, NaN. - function nonFiniteToString(x) { - // Unsigned. - return String(x.s * x.s / 0); + // Determine exponent. + if (e < 0) e = i; + e += +str.slice(i + 1); + str = str.substring(0, i); + } else if (e < 0) { + + // Integer. + e = str.length; } + // Determine leading zeros. + for (i = 0; str.charCodeAt(i) === 48; i++); - /* - * Parse the value of a new Decimal `x` from string `str`. - */ - function parseDecimal(x, str) { - var e, i, len; + // Determine trailing zeros. + for (len = str.length; str.charCodeAt(len - 1) === 48; --len); + str = str.slice(i, len); - // Decimal point? - if ((e = str.indexOf('.')) > -1) str = str.replace('.', ''); + if (str) { + len -= i; + x.e = e = e - i - 1; + x.d = []; - // Exponential form? - if ((i = str.search(/e/i)) > 0) { + // Transform base - // Determine exponent. - if (e < 0) e = i; - e += +str.slice(i + 1); - str = str.substring(0, i); - } else if (e < 0) { + // e is the base 10 exponent. + // i is where to slice str to get the first word of the digits array. + i = (e + 1) % LOG_BASE; + if (e < 0) i += LOG_BASE; - // Integer. - e = str.length; + if (i < len) { + if (i) x.d.push(+str.slice(0, i)); + for (len -= LOG_BASE; i < len;) x.d.push(+str.slice(i, i += LOG_BASE)); + str = str.slice(i); + i = LOG_BASE - str.length; + } else { + i -= len; } - // Determine leading zeros. - for (i = 0; str.charCodeAt(i) === 48; i++); + for (; i--;) str += '0'; + x.d.push(+str); - // Determine trailing zeros. - for (len = str.length; str.charCodeAt(len - 1) === 48; --len); - str = str.slice(i, len); + if (external) { - if (str) { - len -= i; - x.e = e = e - i - 1; - x.d = []; + // Overflow? + if (x.e > x.constructor.maxE) { - // Transform base + // Infinity. + x.d = null; + x.e = NaN; - // e is the base 10 exponent. - // i is where to slice str to get the first word of the digits array. - i = (e + 1) % LOG_BASE; - if (e < 0) i += LOG_BASE; + // Underflow? + } else if (x.e < x.constructor.minE) { - if (i < len) { - if (i) x.d.push(+str.slice(0, i)); - for (len -= LOG_BASE; i < len;) x.d.push(+str.slice(i, i += LOG_BASE)); - str = str.slice(i); - i = LOG_BASE - str.length; - } else { - i -= len; - } + // Zero. + x.e = 0; + x.d = [0]; + // x.constructor.underflow = true; + } // else x.constructor.underflow = false; + } + } else { - for (; i--;) str += '0'; - x.d.push(+str); + // Zero. + x.e = 0; + x.d = [0]; + } - if (external) { + return x; +} - // Overflow? - if (x.e > x.constructor.maxE) { - // Infinity. - x.d = null; - x.e = NaN; +/* + * Parse the value of a new Decimal `x` from a string `str`, which is not a decimal value. + */ +function parseOther(x, str) { + var base, Ctor, divisor, i, isFloat, len, p, xd, xe; - // Underflow? - } else if (x.e < x.constructor.minE) { + if (str === 'Infinity' || str === 'NaN') { + if (!+str) x.s = NaN; + x.e = NaN; + x.d = null; + return x; + } - // Zero. - x.e = 0; - x.d = [0]; - // x.constructor.underflow = true; - } // else x.constructor.underflow = false; - } - } else { + if (isHex.test(str)) { + base = 16; + str = str.toLowerCase(); + } else if (isBinary.test(str)) { + base = 2; + } else if (isOctal.test(str)) { + base = 8; + } else { + throw Error(invalidArgument + str); + } - // Zero. - x.e = 0; - x.d = [0]; - } + // Is there a binary exponent part? + i = str.search(/p/i); - return x; + if (i > 0) { + p = +str.slice(i + 1); + str = str.substring(2, i); + } else { + str = str.slice(2); } + // Convert `str` as an integer then divide the result by `base` raised to a power such that the + // fraction part will be restored. + i = str.indexOf('.'); + isFloat = i >= 0; + Ctor = x.constructor; - /* - * Parse the value of a new Decimal `x` from a string `str`, which is not a decimal value. - */ - function parseOther(x, str) { - var base, Ctor, divisor, i, isFloat, len, p, xd, xe; + if (isFloat) { + str = str.replace('.', ''); + len = str.length; + i = len - i; - if (str === 'Infinity' || str === 'NaN') { - if (!+str) x.s = NaN; - x.e = NaN; - x.d = null; - return x; - } + // log[10](16) = 1.2041... , log[10](88) = 1.9444.... + divisor = intPow(Ctor, new Ctor(base), i, i * 2); + } - if (isHex.test(str)) { - base = 16; - str = str.toLowerCase(); - } else if (isBinary.test(str)) { - base = 2; - } else if (isOctal.test(str)) { - base = 8; - } else { - throw Error(invalidArgument + str); - } + xd = convertBase(str, base, BASE); + xe = xd.length - 1; - // Is there a binary exponent part? - i = str.search(/p/i); + // Remove trailing zeros. + for (i = xe; xd[i] === 0; --i) xd.pop(); + if (i < 0) return new Ctor(x.s * 0); + x.e = getBase10Exponent(xd, xe); + x.d = xd; + external = false; - if (i > 0) { - p = +str.slice(i + 1); - str = str.substring(2, i); - } else { - str = str.slice(2); - } + // At what precision to perform the division to ensure exact conversion? + // maxDecimalIntegerPartDigitCount = ceil(log[10](b) * otherBaseIntegerPartDigitCount) + // log[10](2) = 0.30103, log[10](8) = 0.90309, log[10](16) = 1.20412 + // E.g. ceil(1.2 * 3) = 4, so up to 4 decimal digits are needed to represent 3 hex int digits. + // maxDecimalFractionPartDigitCount = {Hex:4|Oct:3|Bin:1} * otherBaseFractionPartDigitCount + // Therefore using 4 * the number of digits of str will always be enough. + if (isFloat) x = divide(x, divisor, len * 4); - // Convert `str` as an integer then divide the result by `base` raised to a power such that the - // fraction part will be restored. - i = str.indexOf('.'); - isFloat = i >= 0; - Ctor = x.constructor; + // Multiply by the binary exponent part if present. + if (p) x = x.times(Math.abs(p) < 54 ? Math.pow(2, p) : Decimal.pow(2, p)); + external = true; - if (isFloat) { - str = str.replace('.', ''); - len = str.length; - i = len - i; + return x; +} - // log[10](16) = 1.2041... , log[10](88) = 1.9444.... - divisor = intPow(Ctor, new Ctor(base), i, i * 2); - } - xd = convertBase(str, base, BASE); - xe = xd.length - 1; +/* + * sin(x) = x - x^3/3! + x^5/5! - ... + * |x| < pi/2 + * + */ +function sine(Ctor, x) { + var k, + len = x.d.length; + + if (len < 3) return taylorSeries(Ctor, 2, x, x); - // Remove trailing zeros. - for (i = xe; xd[i] === 0; --i) xd.pop(); - if (i < 0) return new Ctor(x.s * 0); - x.e = getBase10Exponent(xd, xe); - x.d = xd; - external = false; + // Argument reduction: sin(5x) = 16*sin^5(x) - 20*sin^3(x) + 5*sin(x) + // i.e. sin(x) = 16*sin^5(x/5) - 20*sin^3(x/5) + 5*sin(x/5) + // and sin(x) = sin(x/5)(5 + sin^2(x/5)(16sin^2(x/5) - 20)) - // At what precision to perform the division to ensure exact conversion? - // maxDecimalIntegerPartDigitCount = ceil(log[10](b) * otherBaseIntegerPartDigitCount) - // log[10](2) = 0.30103, log[10](8) = 0.90309, log[10](16) = 1.20412 - // E.g. ceil(1.2 * 3) = 4, so up to 4 decimal digits are needed to represent 3 hex int digits. - // maxDecimalFractionPartDigitCount = {Hex:4|Oct:3|Bin:1} * otherBaseFractionPartDigitCount - // Therefore using 4 * the number of digits of str will always be enough. - if (isFloat) x = divide(x, divisor, len * 4); + // Estimate the optimum number of times to use the argument reduction. + k = 1.4 * Math.sqrt(len); + k = k > 16 ? 16 : k | 0; - // Multiply by the binary exponent part if present. - if (p) x = x.times(Math.abs(p) < 54 ? Math.pow(2, p) : Decimal.pow(2, p)); - external = true; + // Max k before Math.pow precision loss is 22 + x = x.times(Math.pow(5, -k)); + x = taylorSeries(Ctor, 2, x, x); - return x; + // Reverse argument reduction + var sin2_x, + d5 = new Ctor(5), + d16 = new Ctor(16), + d20 = new Ctor(20); + for (; k--;) { + sin2_x = x.times(x); + x = x.times(d5.plus(sin2_x.times(d16.times(sin2_x).minus(d20)))); } + return x; +} - /* - * sin(x) = x - x^3/3! + x^5/5! - ... - * |x| < pi/2 - * - */ - function sine(Ctor, x) { - var k, - len = x.d.length; - - if (len < 3) return taylorSeries(Ctor, 2, x, x); - // Argument reduction: sin(5x) = 16*sin^5(x) - 20*sin^3(x) + 5*sin(x) - // i.e. sin(x) = 16*sin^5(x/5) - 20*sin^3(x/5) + 5*sin(x/5) - // and sin(x) = sin(x/5)(5 + sin^2(x/5)(16sin^2(x/5) - 20)) +// Calculate Taylor series for `cos`, `cosh`, `sin` and `sinh`. +function taylorSeries(Ctor, n, x, y, isHyperbolic) { + var j, t, u, x2, + i = 1, + pr = Ctor.precision, + k = Math.ceil(pr / LOG_BASE); - // Estimate the optimum number of times to use the argument reduction. - k = 1.4 * Math.sqrt(len); - k = k > 16 ? 16 : k | 0; + external = false; + x2 = x.times(x); + u = new Ctor(y); - // Max k before Math.pow precision loss is 22 - x = x.times(Math.pow(5, -k)); - x = taylorSeries(Ctor, 2, x, x); + for (;;) { + t = divide(u.times(x2), new Ctor(n++ * n++), pr, 1); + u = isHyperbolic ? y.plus(t) : y.minus(t); + y = divide(t.times(x2), new Ctor(n++ * n++), pr, 1); + t = u.plus(y); - // Reverse argument reduction - var sin2_x, - d5 = new Ctor(5), - d16 = new Ctor(16), - d20 = new Ctor(20); - for (; k--;) { - sin2_x = x.times(x); - x = x.times(d5.plus(sin2_x.times(d16.times(sin2_x).minus(d20)))); + if (t.d[k] !== void 0) { + for (j = k; t.d[j] === u.d[j] && j--;); + if (j == -1) break; } - return x; + j = u; + u = y; + y = t; + t = j; + i++; } + external = true; + t.d.length = k + 1; - // Calculate Taylor series for `cos`, `cosh`, `sin` and `sinh`. - function taylorSeries(Ctor, n, x, y, isHyperbolic) { - var j, t, u, x2, - i = 1, - pr = Ctor.precision, - k = Math.ceil(pr / LOG_BASE); + return t; +} - external = false; - x2 = x.times(x); - u = new Ctor(y); - - for (;;) { - t = divide(u.times(x2), new Ctor(n++ * n++), pr, 1); - u = isHyperbolic ? y.plus(t) : y.minus(t); - y = divide(t.times(x2), new Ctor(n++ * n++), pr, 1); - t = u.plus(y); - - if (t.d[k] !== void 0) { - for (j = k; t.d[j] === u.d[j] && j--;); - if (j == -1) break; - } - j = u; - u = y; - y = t; - t = j; - i++; - } +// Return the absolute value of `x` reduced to less than or equal to half pi. +function toLessThanHalfPi(Ctor, x) { + var t, + isNeg = x.s < 0, + pi = getPi(Ctor, Ctor.precision, 1), + halfPi = pi.times(0.5); - external = true; - t.d.length = k + 1; + x = x.abs(); - return t; + if (x.lte(halfPi)) { + quadrant = isNeg ? 4 : 1; + return x; } + t = x.divToInt(pi); - // Return the absolute value of `x` reduced to less than or equal to half pi. - function toLessThanHalfPi(Ctor, x) { - var t, - isNeg = x.s < 0, - pi = getPi(Ctor, Ctor.precision, 1), - halfPi = pi.times(0.5); - - x = x.abs(); + if (t.isZero()) { + quadrant = isNeg ? 3 : 2; + } else { + x = x.minus(t.times(pi)); + // 0 <= x < pi if (x.lte(halfPi)) { - quadrant = isNeg ? 4 : 1; + quadrant = isOdd(t) ? (isNeg ? 2 : 3) : (isNeg ? 4 : 1); return x; } - t = x.divToInt(pi); + quadrant = isOdd(t) ? (isNeg ? 1 : 4) : (isNeg ? 3 : 2); + } - if (t.isZero()) { - quadrant = isNeg ? 3 : 2; - } else { - x = x.minus(t.times(pi)); + return x.minus(pi).abs(); +} - // 0 <= x < pi - if (x.lte(halfPi)) { - quadrant = isOdd(t) ? (isNeg ? 2 : 3) : (isNeg ? 4 : 1); - return x; - } - quadrant = isOdd(t) ? (isNeg ? 1 : 4) : (isNeg ? 3 : 2); - } +/* + * Return the value of Decimal `x` as a string in base `baseOut`. + * + * If the optional `sd` argument is present include a binary exponent suffix. + */ +function toStringBinary(x, baseOut, sd, rm) { + var base, e, i, k, len, roundUp, str, xd, y, + Ctor = x.constructor, + isExp = sd !== void 0; - return x.minus(pi).abs(); + if (isExp) { + checkInt32(sd, 1, MAX_DIGITS); + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); + } else { + sd = Ctor.precision; + rm = Ctor.rounding; } + if (!x.isFinite()) { + str = nonFiniteToString(x); + } else { + str = finiteToString(x); + i = str.indexOf('.'); - /* - * Return the value of Decimal `x` as a string in base `baseOut`. - * - * If the optional `sd` argument is present include a binary exponent suffix. - */ - function toStringBinary(x, baseOut, sd, rm) { - var base, e, i, k, len, roundUp, str, xd, y, - Ctor = x.constructor, - isExp = sd !== void 0; + // Use exponential notation according to `toExpPos` and `toExpNeg`? No, but if required: + // maxBinaryExponent = floor((decimalExponent + 1) * log[2](10)) + // minBinaryExponent = floor(decimalExponent * log[2](10)) + // log[2](10) = 3.321928094887362347870319429489390175864 if (isExp) { - checkInt32(sd, 1, MAX_DIGITS); - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); + base = 2; + if (baseOut == 16) { + sd = sd * 4 - 3; + } else if (baseOut == 8) { + sd = sd * 3 - 2; + } } else { - sd = Ctor.precision; - rm = Ctor.rounding; + base = baseOut; } - if (!x.isFinite()) { - str = nonFiniteToString(x); - } else { - str = finiteToString(x); - i = str.indexOf('.'); - - // Use exponential notation according to `toExpPos` and `toExpNeg`? No, but if required: - // maxBinaryExponent = floor((decimalExponent + 1) * log[2](10)) - // minBinaryExponent = floor(decimalExponent * log[2](10)) - // log[2](10) = 3.321928094887362347870319429489390175864 - - if (isExp) { - base = 2; - if (baseOut == 16) { - sd = sd * 4 - 3; - } else if (baseOut == 8) { - sd = sd * 3 - 2; - } - } else { - base = baseOut; - } - - // Convert the number as an integer then divide the result by its base raised to a power such - // that the fraction part will be restored. + // Convert the number as an integer then divide the result by its base raised to a power such + // that the fraction part will be restored. - // Non-integer. - if (i >= 0) { - str = str.replace('.', ''); - y = new Ctor(1); - y.e = str.length - i; - y.d = convertBase(finiteToString(y), 10, base); - y.e = y.d.length; - } + // Non-integer. + if (i >= 0) { + str = str.replace('.', ''); + y = new Ctor(1); + y.e = str.length - i; + y.d = convertBase(finiteToString(y), 10, base); + y.e = y.d.length; + } - xd = convertBase(str, 10, base); - e = len = xd.length; + xd = convertBase(str, 10, base); + e = len = xd.length; - // Remove trailing zeros. - for (; xd[--len] == 0;) xd.pop(); + // Remove trailing zeros. + for (; xd[--len] == 0;) xd.pop(); - if (!xd[0]) { - str = isExp ? '0p+0' : '0'; + if (!xd[0]) { + str = isExp ? '0p+0' : '0'; + } else { + if (i < 0) { + e--; } else { - if (i < 0) { - e--; - } else { - x = new Ctor(x); - x.d = xd; - x.e = e; - x = divide(x, y, sd, rm, 0, base); - xd = x.d; - e = x.e; - roundUp = inexact; - } + x = new Ctor(x); + x.d = xd; + x.e = e; + x = divide(x, y, sd, rm, 0, base); + xd = x.d; + e = x.e; + roundUp = inexact; + } - // The rounding digit, i.e. the digit after the digit that may be rounded up. - i = xd[sd]; - k = base / 2; - roundUp = roundUp || xd[sd + 1] !== void 0; + // The rounding digit, i.e. the digit after the digit that may be rounded up. + i = xd[sd]; + k = base / 2; + roundUp = roundUp || xd[sd + 1] !== void 0; - roundUp = rm < 4 - ? (i !== void 0 || roundUp) && (rm === 0 || rm === (x.s < 0 ? 3 : 2)) - : i > k || i === k && (rm === 4 || roundUp || rm === 6 && xd[sd - 1] & 1 || - rm === (x.s < 0 ? 8 : 7)); + roundUp = rm < 4 + ? (i !== void 0 || roundUp) && (rm === 0 || rm === (x.s < 0 ? 3 : 2)) + : i > k || i === k && (rm === 4 || roundUp || rm === 6 && xd[sd - 1] & 1 || + rm === (x.s < 0 ? 8 : 7)); - xd.length = sd; + xd.length = sd; - if (roundUp) { + if (roundUp) { - // Rounding up may mean the previous digit has to be rounded up and so on. - for (; ++xd[--sd] > base - 1;) { - xd[sd] = 0; - if (!sd) { - ++e; - xd.unshift(1); - } + // Rounding up may mean the previous digit has to be rounded up and so on. + for (; ++xd[--sd] > base - 1;) { + xd[sd] = 0; + if (!sd) { + ++e; + xd.unshift(1); } } + } - // Determine trailing zeros. - for (len = xd.length; !xd[len - 1]; --len); - - // E.g. [4, 11, 15] becomes 4bf. - for (i = 0, str = ''; i < len; i++) str += NUMERALS.charAt(xd[i]); + // Determine trailing zeros. + for (len = xd.length; !xd[len - 1]; --len); - // Add binary exponent suffix? - if (isExp) { - if (len > 1) { - if (baseOut == 16 || baseOut == 8) { - i = baseOut == 16 ? 4 : 3; - for (--len; len % i; len++) str += '0'; - xd = convertBase(str, base, baseOut); - for (len = xd.length; !xd[len - 1]; --len); + // E.g. [4, 11, 15] becomes 4bf. + for (i = 0, str = ''; i < len; i++) str += NUMERALS.charAt(xd[i]); - // xd[0] will always be be 1 - for (i = 1, str = '1.'; i < len; i++) str += NUMERALS.charAt(xd[i]); - } else { - str = str.charAt(0) + '.' + str.slice(1); - } + // Add binary exponent suffix? + if (isExp) { + if (len > 1) { + if (baseOut == 16 || baseOut == 8) { + i = baseOut == 16 ? 4 : 3; + for (--len; len % i; len++) str += '0'; + xd = convertBase(str, base, baseOut); + for (len = xd.length; !xd[len - 1]; --len); + + // xd[0] will always be be 1 + for (i = 1, str = '1.'; i < len; i++) str += NUMERALS.charAt(xd[i]); + } else { + str = str.charAt(0) + '.' + str.slice(1); } - - str = str + (e < 0 ? 'p' : 'p+') + e; - } else if (e < 0) { - for (; ++e;) str = '0' + str; - str = '0.' + str; - } else { - if (++e > len) for (e -= len; e-- ;) str += '0'; - else if (e < len) str = str.slice(0, e) + '.' + str.slice(e); } - } - str = (baseOut == 16 ? '0x' : baseOut == 2 ? '0b' : baseOut == 8 ? '0o' : '') + str; + str = str + (e < 0 ? 'p' : 'p+') + e; + } else if (e < 0) { + for (; ++e;) str = '0' + str; + str = '0.' + str; + } else { + if (++e > len) for (e -= len; e-- ;) str += '0'; + else if (e < len) str = str.slice(0, e) + '.' + str.slice(e); + } } - return x.s < 0 ? '-' + str : str; + str = (baseOut == 16 ? '0x' : baseOut == 2 ? '0b' : baseOut == 8 ? '0o' : '') + str; } + return x.s < 0 ? '-' + str : str; +} - // Does not strip trailing zeros. - function truncate(arr, len) { - if (arr.length > len) { - arr.length = len; - return true; - } - } +// Does not strip trailing zeros. +function truncate(arr, len) { + if (arr.length > len) { + arr.length = len; + return true; + } +} - // Decimal methods +// Decimal methods - /* - * abs - * acos - * acosh - * add - * asin - * asinh - * atan - * atanh - * atan2 - * cbrt - * ceil - * clone - * config - * cos - * cosh - * div - * exp - * floor - * hypot - * ln - * log - * log2 - * log10 - * max - * min - * mod - * mul - * pow - * random - * round - * set - * sign - * sin - * sinh - * sqrt - * sub - * tan - * tanh - * trunc - */ +/* + * abs + * acos + * acosh + * add + * asin + * asinh + * atan + * atanh + * atan2 + * cbrt + * ceil + * clone + * config + * cos + * cosh + * div + * exp + * floor + * hypot + * ln + * log + * log2 + * log10 + * max + * min + * mod + * mul + * pow + * random + * round + * set + * sign + * sin + * sinh + * sqrt + * sub + * tan + * tanh + * trunc + */ - /* - * Return a new Decimal whose value is the absolute value of `x`. - * - * x {number|string|Decimal} - * - */ - function abs(x) { - return new this(x).abs(); - } +/* + * Return a new Decimal whose value is the absolute value of `x`. + * + * x {number|string|Decimal} + * + */ +function abs(x) { + return new this(x).abs(); +} - /* - * Return a new Decimal whose value is the arccosine in radians of `x`. - * - * x {number|string|Decimal} - * - */ - function acos(x) { - return new this(x).acos(); - } +/* + * Return a new Decimal whose value is the arccosine in radians of `x`. + * + * x {number|string|Decimal} + * + */ +function acos(x) { + return new this(x).acos(); +} - /* - * Return a new Decimal whose value is the inverse of the hyperbolic cosine of `x`, rounded to - * `precision` significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function acosh(x) { - return new this(x).acosh(); - } +/* + * Return a new Decimal whose value is the inverse of the hyperbolic cosine of `x`, rounded to + * `precision` significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} A value in radians. + * + */ +function acosh(x) { + return new this(x).acosh(); +} - /* - * Return a new Decimal whose value is the sum of `x` and `y`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * y {number|string|Decimal} - * - */ - function add(x, y) { - return new this(x).plus(y); - } +/* + * Return a new Decimal whose value is the sum of `x` and `y`, rounded to `precision` significant + * digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * y {number|string|Decimal} + * + */ +function add(x, y) { + return new this(x).plus(y); +} - /* - * Return a new Decimal whose value is the arcsine in radians of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function asin(x) { - return new this(x).asin(); - } +/* + * Return a new Decimal whose value is the arcsine in radians of `x`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * + */ +function asin(x) { + return new this(x).asin(); +} - /* - * Return a new Decimal whose value is the inverse of the hyperbolic sine of `x`, rounded to - * `precision` significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function asinh(x) { - return new this(x).asinh(); - } +/* + * Return a new Decimal whose value is the inverse of the hyperbolic sine of `x`, rounded to + * `precision` significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} A value in radians. + * + */ +function asinh(x) { + return new this(x).asinh(); +} - /* - * Return a new Decimal whose value is the arctangent in radians of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function atan(x) { - return new this(x).atan(); - } +/* + * Return a new Decimal whose value is the arctangent in radians of `x`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * + */ +function atan(x) { + return new this(x).atan(); +} - /* - * Return a new Decimal whose value is the inverse of the hyperbolic tangent of `x`, rounded to - * `precision` significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function atanh(x) { - return new this(x).atanh(); - } +/* + * Return a new Decimal whose value is the inverse of the hyperbolic tangent of `x`, rounded to + * `precision` significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} A value in radians. + * + */ +function atanh(x) { + return new this(x).atanh(); +} - /* - * Return a new Decimal whose value is the arctangent in radians of `y/x` in the range -pi to pi - * (inclusive), rounded to `precision` significant digits using rounding mode `rounding`. - * - * Domain: [-Infinity, Infinity] - * Range: [-pi, pi] - * - * y {number|string|Decimal} The y-coordinate. - * x {number|string|Decimal} The x-coordinate. - * - * atan2(±0, -0) = ±pi - * atan2(±0, +0) = ±0 - * atan2(±0, -x) = ±pi for x > 0 - * atan2(±0, x) = ±0 for x > 0 - * atan2(-y, ±0) = -pi/2 for y > 0 - * atan2(y, ±0) = pi/2 for y > 0 - * atan2(±y, -Infinity) = ±pi for finite y > 0 - * atan2(±y, +Infinity) = ±0 for finite y > 0 - * atan2(±Infinity, x) = ±pi/2 for finite x - * atan2(±Infinity, -Infinity) = ±3*pi/4 - * atan2(±Infinity, +Infinity) = ±pi/4 - * atan2(NaN, x) = NaN - * atan2(y, NaN) = NaN - * - */ - function atan2(y, x) { - y = new this(y); - x = new this(x); - var r, - pr = this.precision, - rm = this.rounding, - wpr = pr + 4; - - // Either NaN - if (!y.s || !x.s) { - r = new this(NaN); - - // Both ±Infinity - } else if (!y.d && !x.d) { - r = getPi(this, wpr, 1).times(x.s > 0 ? 0.25 : 0.75); - r.s = y.s; - - // x is ±Infinity or y is ±0 - } else if (!x.d || y.isZero()) { - r = x.s < 0 ? getPi(this, pr, rm) : new this(0); - r.s = y.s; - - // y is ±Infinity or x is ±0 - } else if (!y.d || x.isZero()) { - r = getPi(this, wpr, 1).times(0.5); - r.s = y.s; - - // Both non-zero and finite - } else if (x.s < 0) { - this.precision = wpr; - this.rounding = 1; - r = this.atan(divide(y, x, wpr, 1)); - x = getPi(this, wpr, 1); - this.precision = pr; - this.rounding = rm; - r = y.s < 0 ? r.minus(x) : r.plus(x); - } else { - r = this.atan(divide(y, x, wpr, 1)); - } - return r; +/* + * Return a new Decimal whose value is the arctangent in radians of `y/x` in the range -pi to pi + * (inclusive), rounded to `precision` significant digits using rounding mode `rounding`. + * + * Domain: [-Infinity, Infinity] + * Range: [-pi, pi] + * + * y {number|string|Decimal} The y-coordinate. + * x {number|string|Decimal} The x-coordinate. + * + * atan2(±0, -0) = ±pi + * atan2(±0, +0) = ±0 + * atan2(±0, -x) = ±pi for x > 0 + * atan2(±0, x) = ±0 for x > 0 + * atan2(-y, ±0) = -pi/2 for y > 0 + * atan2(y, ±0) = pi/2 for y > 0 + * atan2(±y, -Infinity) = ±pi for finite y > 0 + * atan2(±y, +Infinity) = ±0 for finite y > 0 + * atan2(±Infinity, x) = ±pi/2 for finite x + * atan2(±Infinity, -Infinity) = ±3*pi/4 + * atan2(±Infinity, +Infinity) = ±pi/4 + * atan2(NaN, x) = NaN + * atan2(y, NaN) = NaN + * + */ +function atan2(y, x) { + y = new this(y); + x = new this(x); + var r, + pr = this.precision, + rm = this.rounding, + wpr = pr + 4; + + // Either NaN + if (!y.s || !x.s) { + r = new this(NaN); + + // Both ±Infinity + } else if (!y.d && !x.d) { + r = getPi(this, wpr, 1).times(x.s > 0 ? 0.25 : 0.75); + r.s = y.s; + + // x is ±Infinity or y is ±0 + } else if (!x.d || y.isZero()) { + r = x.s < 0 ? getPi(this, pr, rm) : new this(0); + r.s = y.s; + + // y is ±Infinity or x is ±0 + } else if (!y.d || x.isZero()) { + r = getPi(this, wpr, 1).times(0.5); + r.s = y.s; + + // Both non-zero and finite + } else if (x.s < 0) { + this.precision = wpr; + this.rounding = 1; + r = this.atan(divide(y, x, wpr, 1)); + x = getPi(this, wpr, 1); + this.precision = pr; + this.rounding = rm; + r = y.s < 0 ? r.minus(x) : r.plus(x); + } else { + r = this.atan(divide(y, x, wpr, 1)); } + return r; +} + - /* - * Return a new Decimal whose value is the cube root of `x`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function cbrt(x) { - return new this(x).cbrt(); - } +/* + * Return a new Decimal whose value is the cube root of `x`, rounded to `precision` significant + * digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * + */ +function cbrt(x) { + return new this(x).cbrt(); +} - /* - * Return a new Decimal whose value is `x` rounded to an integer using `ROUND_CEIL`. - * - * x {number|string|Decimal} - * - */ - function ceil(x) { - return finalise(x = new this(x), x.e + 1, 2); - } +/* + * Return a new Decimal whose value is `x` rounded to an integer using `ROUND_CEIL`. + * + * x {number|string|Decimal} + * + */ +function ceil(x) { + return finalise(x = new this(x), x.e + 1, 2); +} - /* - * Configure global settings for a Decimal constructor. - * - * `obj` is an object with one or more of the following properties, - * - * precision {number} - * rounding {number} - * toExpNeg {number} - * toExpPos {number} - * maxE {number} - * minE {number} - * modulo {number} - * crypto {boolean|number} - * - * E.g. Decimal.config({ precision: 20, rounding: 4 }) - * - */ - function config(obj) { - if (!obj || typeof obj !== 'object') throw Error(decimalError + 'Object expected'); - var i, p, v, - ps = [ - 'precision', 1, MAX_DIGITS, - 'rounding', 0, 8, - 'toExpNeg', -EXP_LIMIT, 0, - 'toExpPos', 0, EXP_LIMIT, - 'maxE', 0, EXP_LIMIT, - 'minE', -EXP_LIMIT, 0, - 'modulo', 0, 9 - ]; - - for (i = 0; i < ps.length; i += 3) { - if ((v = obj[p = ps[i]]) !== void 0) { - if (mathfloor(v) === v && v >= ps[i + 1] && v <= ps[i + 2]) this[p] = v; - else throw Error(invalidArgument + p + ': ' + v); - } +/* + * Configure global settings for a Decimal constructor. + * + * `obj` is an object with one or more of the following properties, + * + * precision {number} + * rounding {number} + * toExpNeg {number} + * toExpPos {number} + * maxE {number} + * minE {number} + * modulo {number} + * crypto {boolean|number} + * + * E.g. Decimal.config({ precision: 20, rounding: 4 }) + * + */ +function config(obj) { + if (!obj || typeof obj !== 'object') throw Error(decimalError + 'Object expected'); + var i, p, v, + ps = [ + 'precision', 1, MAX_DIGITS, + 'rounding', 0, 8, + 'toExpNeg', -EXP_LIMIT, 0, + 'toExpPos', 0, EXP_LIMIT, + 'maxE', 0, EXP_LIMIT, + 'minE', -EXP_LIMIT, 0, + 'modulo', 0, 9 + ]; + + for (i = 0; i < ps.length; i += 3) { + if ((v = obj[p = ps[i]]) !== void 0) { + if (mathfloor(v) === v && v >= ps[i + 1] && v <= ps[i + 2]) this[p] = v; + else throw Error(invalidArgument + p + ': ' + v); } + } - if ((v = obj[p = 'crypto']) !== void 0) { - if (v === true || v === false || v === 0 || v === 1) { - if (v) { - if (typeof crypto != 'undefined' && crypto && - (crypto.getRandomValues || crypto.randomBytes)) { - this[p] = true; - } else { - throw Error(cryptoUnavailable); - } + if ((v = obj[p = 'crypto']) !== void 0) { + if (v === true || v === false || v === 0 || v === 1) { + if (v) { + if (typeof crypto != 'undefined' && crypto && + (crypto.getRandomValues || crypto.randomBytes)) { + this[p] = true; } else { - this[p] = false; + throw Error(cryptoUnavailable); } } else { - throw Error(invalidArgument + p + ': ' + v); + this[p] = false; } + } else { + throw Error(invalidArgument + p + ': ' + v); } - - return this; } + return this; +} - /* - * Return a new Decimal whose value is the cosine of `x`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function cos(x) { - return new this(x).cos(); - } +/* + * Return a new Decimal whose value is the cosine of `x`, rounded to `precision` significant + * digits using rounding mode `rounding`. + * + * x {number|string|Decimal} A value in radians. + * + */ +function cos(x) { + return new this(x).cos(); +} - /* - * Return a new Decimal whose value is the hyperbolic cosine of `x`, rounded to precision - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function cosh(x) { - return new this(x).cosh(); - } +/* + * Return a new Decimal whose value is the hyperbolic cosine of `x`, rounded to precision + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} A value in radians. + * + */ +function cosh(x) { + return new this(x).cosh(); +} + + +/* + * Create and return a Decimal constructor with the same configuration properties as this Decimal + * constructor. + * + */ +function clone(obj) { + var i, p, ps; /* - * Create and return a Decimal constructor with the same configuration properties as this Decimal - * constructor. + * The Decimal constructor and exported function. + * Return a new Decimal instance. + * + * v {number|string|Decimal} A numeric value. * */ - function clone(obj) { - var i, p, ps; - - /* - * The Decimal constructor and exported function. - * Return a new Decimal instance. - * - * v {number|string|Decimal} A numeric value. - * - */ - function Decimal(v) { - var e, i, t, - x = this; - - // Decimal called without new. - if (!(x instanceof Decimal)) return new Decimal(v); - - // Retain a reference to this Decimal constructor, and shadow Decimal.prototype.constructor - // which points to Object. - x.constructor = Decimal; - - // Duplicate. - if (v instanceof Decimal) { - x.s = v.s; - x.e = v.e; - x.d = (v = v.d) ? v.slice() : v; - return; - } - - t = typeof v; - - if (t === 'number') { - if (v === 0) { - x.s = 1 / v < 0 ? -1 : 1; - x.e = 0; - x.d = [0]; - return; - } + function Decimal(v) { + var e, i, t, + x = this; - if (v < 0) { - v = -v; - x.s = -1; - } else { - x.s = 1; - } + // Decimal called without new. + if (!(x instanceof Decimal)) return new Decimal(v); - // Fast path for small integers. - if (v === ~~v && v < 1e7) { - for (e = 0, i = v; i >= 10; i /= 10) e++; - x.e = e; - x.d = [v]; - return; + // Retain a reference to this Decimal constructor, and shadow Decimal.prototype.constructor + // which points to Object. + x.constructor = Decimal; - // Infinity, NaN. - } else if (v * 0 !== 0) { - if (!v) x.s = NaN; - x.e = NaN; - x.d = null; - return; - } + // Duplicate. + if (v instanceof Decimal) { + x.s = v.s; + x.e = v.e; + x.d = (v = v.d) ? v.slice() : v; + return; + } - return parseDecimal(x, v.toString()); + t = typeof v; - } else if (t !== 'string') { - throw Error(invalidArgument + v); + if (t === 'number') { + if (v === 0) { + x.s = 1 / v < 0 ? -1 : 1; + x.e = 0; + x.d = [0]; + return; } - // Minus sign? - if (v.charCodeAt(0) === 45) { - v = v.slice(1); + if (v < 0) { + v = -v; x.s = -1; } else { x.s = 1; } - return isDecimal.test(v) ? parseDecimal(x, v) : parseOther(x, v); - } - - Decimal.prototype = P; - - Decimal.ROUND_UP = 0; - Decimal.ROUND_DOWN = 1; - Decimal.ROUND_CEIL = 2; - Decimal.ROUND_FLOOR = 3; - Decimal.ROUND_HALF_UP = 4; - Decimal.ROUND_HALF_DOWN = 5; - Decimal.ROUND_HALF_EVEN = 6; - Decimal.ROUND_HALF_CEIL = 7; - Decimal.ROUND_HALF_FLOOR = 8; - Decimal.EUCLID = 9; - - Decimal.config = Decimal.set = config; - Decimal.clone = clone; - - Decimal.abs = abs; - Decimal.acos = acos; - Decimal.acosh = acosh; // ES6 - Decimal.add = add; - Decimal.asin = asin; - Decimal.asinh = asinh; // ES6 - Decimal.atan = atan; - Decimal.atanh = atanh; // ES6 - Decimal.atan2 = atan2; - Decimal.cbrt = cbrt; // ES6 - Decimal.ceil = ceil; - Decimal.cos = cos; - Decimal.cosh = cosh; // ES6 - Decimal.div = div; - Decimal.exp = exp; - Decimal.floor = floor; - Decimal.hypot = hypot; // ES6 - Decimal.ln = ln; - Decimal.log = log; - Decimal.log10 = log10; // ES6 - Decimal.log2 = log2; // ES6 - Decimal.max = max; - Decimal.min = min; - Decimal.mod = mod; - Decimal.mul = mul; - Decimal.pow = pow; - Decimal.random = random; - Decimal.round = round; - Decimal.sign = sign; // ES6 - Decimal.sin = sin; - Decimal.sinh = sinh; // ES6 - Decimal.sqrt = sqrt; - Decimal.sub = sub; - Decimal.tan = tan; - Decimal.tanh = tanh; // ES6 - Decimal.trunc = trunc; // ES6 - - if (obj === void 0) obj = {}; - if (obj) { - ps = ['precision', 'rounding', 'toExpNeg', 'toExpPos', 'maxE', 'minE', 'modulo', 'crypto']; - for (i = 0; i < ps.length;) if (!obj.hasOwnProperty(p = ps[i++])) obj[p] = this[p]; - } - - Decimal.config(obj); - - return Decimal; - } - - - /* - * Return a new Decimal whose value is `x` divided by `y`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * y {number|string|Decimal} - * - */ - function div(x, y) { - return new this(x).div(y); - } + // Fast path for small integers. + if (v === ~~v && v < 1e7) { + for (e = 0, i = v; i >= 10; i /= 10) e++; + x.e = e; + x.d = [v]; + return; + // Infinity, NaN. + } else if (v * 0 !== 0) { + if (!v) x.s = NaN; + x.e = NaN; + x.d = null; + return; + } - /* - * Return a new Decimal whose value is the natural exponential of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} The power to which to raise the base of the natural log. - * - */ - function exp(x) { - return new this(x).exp(); - } + return parseDecimal(x, v.toString()); + } else if (t !== 'string') { + throw Error(invalidArgument + v); + } - /* - * Return a new Decimal whose value is `x` round to an integer using `ROUND_FLOOR`. - * - * x {number|string|Decimal} - * - */ - function floor(x) { - return finalise(x = new this(x), x.e + 1, 3); + // Minus sign? + if (v.charCodeAt(0) === 45) { + v = v.slice(1); + x.s = -1; + } else { + x.s = 1; + } + + return isDecimal.test(v) ? parseDecimal(x, v) : parseOther(x, v); + } + + Decimal.prototype = P; + + Decimal.ROUND_UP = 0; + Decimal.ROUND_DOWN = 1; + Decimal.ROUND_CEIL = 2; + Decimal.ROUND_FLOOR = 3; + Decimal.ROUND_HALF_UP = 4; + Decimal.ROUND_HALF_DOWN = 5; + Decimal.ROUND_HALF_EVEN = 6; + Decimal.ROUND_HALF_CEIL = 7; + Decimal.ROUND_HALF_FLOOR = 8; + Decimal.EUCLID = 9; + + Decimal.config = Decimal.set = config; + Decimal.clone = clone; + + Decimal.abs = abs; + Decimal.acos = acos; + Decimal.acosh = acosh; // ES6 + Decimal.add = add; + Decimal.asin = asin; + Decimal.asinh = asinh; // ES6 + Decimal.atan = atan; + Decimal.atanh = atanh; // ES6 + Decimal.atan2 = atan2; + Decimal.cbrt = cbrt; // ES6 + Decimal.ceil = ceil; + Decimal.cos = cos; + Decimal.cosh = cosh; // ES6 + Decimal.div = div; + Decimal.exp = exp; + Decimal.floor = floor; + Decimal.hypot = hypot; // ES6 + Decimal.ln = ln; + Decimal.log = log; + Decimal.log10 = log10; // ES6 + Decimal.log2 = log2; // ES6 + Decimal.max = max; + Decimal.min = min; + Decimal.mod = mod; + Decimal.mul = mul; + Decimal.pow = pow; + Decimal.random = random; + Decimal.round = round; + Decimal.sign = sign; // ES6 + Decimal.sin = sin; + Decimal.sinh = sinh; // ES6 + Decimal.sqrt = sqrt; + Decimal.sub = sub; + Decimal.tan = tan; + Decimal.tanh = tanh; // ES6 + Decimal.trunc = trunc; // ES6 + + if (obj === void 0) obj = {}; + if (obj) { + ps = ['precision', 'rounding', 'toExpNeg', 'toExpPos', 'maxE', 'minE', 'modulo', 'crypto']; + for (i = 0; i < ps.length;) if (!obj.hasOwnProperty(p = ps[i++])) obj[p] = this[p]; } + Decimal.config(obj); - /* - * Return a new Decimal whose value is the square root of the sum of the squares of the arguments, - * rounded to `precision` significant digits using rounding mode `rounding`. - * - * hypot(a, b, ...) = sqrt(a^2 + b^2 + ...) - * - */ - function hypot() { - var i, n, - t = new this(0); + return Decimal; +} - external = false; - for (i = 0; i < arguments.length;) { - n = new this(arguments[i++]); - if (!n.d) { - if (n.s) { - external = true; - return new this(1 / 0); - } - t = n; - } else if (t.d) { - t = t.plus(n.times(n)); - } - } +/* + * Return a new Decimal whose value is `x` divided by `y`, rounded to `precision` significant + * digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * y {number|string|Decimal} + * + */ +function div(x, y) { + return new this(x).div(y); +} - external = true; - return t.sqrt(); - } +/* + * Return a new Decimal whose value is the natural exponential of `x`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} The power to which to raise the base of the natural log. + * + */ +function exp(x) { + return new this(x).exp(); +} - /* - * Return a new Decimal whose value is the natural logarithm of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function ln(x) { - return new this(x).ln(); - } +/* + * Return a new Decimal whose value is `x` round to an integer using `ROUND_FLOOR`. + * + * x {number|string|Decimal} + * + */ +function floor(x) { + return finalise(x = new this(x), x.e + 1, 3); +} - /* - * Return a new Decimal whose value is the log of `x` to the base `y`, or to base 10 if no base - * is specified, rounded to `precision` significant digits using rounding mode `rounding`. - * - * log[y](x) - * - * x {number|string|Decimal} The argument of the logarithm. - * y {number|string|Decimal} The base of the logarithm. - * - */ - function log(x, y) { - return new this(x).log(y); +/* + * Return a new Decimal whose value is the square root of the sum of the squares of the arguments, + * rounded to `precision` significant digits using rounding mode `rounding`. + * + * hypot(a, b, ...) = sqrt(a^2 + b^2 + ...) + * + */ +function hypot() { + var i, n, + t = new this(0); + + external = false; + + for (i = 0; i < arguments.length;) { + n = new this(arguments[i++]); + if (!n.d) { + if (n.s) { + external = true; + return new this(1 / 0); + } + t = n; + } else if (t.d) { + t = t.plus(n.times(n)); + } } + external = true; - /* - * Return a new Decimal whose value is the base 2 logarithm of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function log2(x) { - return new this(x).log(2); - } + return t.sqrt(); +} - /* - * Return a new Decimal whose value is the base 10 logarithm of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function log10(x) { - return new this(x).log(10); - } +/* + * Return a new Decimal whose value is the natural logarithm of `x`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * + */ +function ln(x) { + return new this(x).ln(); +} - /* - * Return a new Decimal whose value is the maximum of the arguments. - * - * arguments {number|string|Decimal} - * - */ - function max() { - return maxOrMin(this, arguments, 'lt'); - } +/* + * Return a new Decimal whose value is the log of `x` to the base `y`, or to base 10 if no base + * is specified, rounded to `precision` significant digits using rounding mode `rounding`. + * + * log[y](x) + * + * x {number|string|Decimal} The argument of the logarithm. + * y {number|string|Decimal} The base of the logarithm. + * + */ +function log(x, y) { + return new this(x).log(y); +} - /* - * Return a new Decimal whose value is the minimum of the arguments. - * - * arguments {number|string|Decimal} - * - */ - function min() { - return maxOrMin(this, arguments, 'gt'); - } +/* + * Return a new Decimal whose value is the base 2 logarithm of `x`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * + */ +function log2(x) { + return new this(x).log(2); +} - /* - * Return a new Decimal whose value is `x` modulo `y`, rounded to `precision` significant digits - * using rounding mode `rounding`. - * - * x {number|string|Decimal} - * y {number|string|Decimal} - * - */ - function mod(x, y) { - return new this(x).mod(y); - } +/* + * Return a new Decimal whose value is the base 10 logarithm of `x`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * + */ +function log10(x) { + return new this(x).log(10); +} - /* - * Return a new Decimal whose value is `x` multiplied by `y`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * y {number|string|Decimal} - * - */ - function mul(x, y) { - return new this(x).mul(y); - } +/* + * Return a new Decimal whose value is the maximum of the arguments. + * + * arguments {number|string|Decimal} + * + */ +function max() { + return maxOrMin(this, arguments, 'lt'); +} - /* - * Return a new Decimal whose value is `x` raised to the power `y`, rounded to precision - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} The base. - * y {number|string|Decimal} The exponent. - * - */ - function pow(x, y) { - return new this(x).pow(y); - } +/* + * Return a new Decimal whose value is the minimum of the arguments. + * + * arguments {number|string|Decimal} + * + */ +function min() { + return maxOrMin(this, arguments, 'gt'); +} - /* - * Returns a new Decimal with a random value equal to or greater than 0 and less than 1, and with - * `sd`, or `Decimal.precision` if `sd` is omitted, significant digits (or less if trailing zeros - * are produced). - * - * [sd] {number} Significant digits. Integer, 0 to MAX_DIGITS inclusive. - * - */ - function random(sd) { - var d, e, k, n, - i = 0, - r = new this(1), - rd = []; +/* + * Return a new Decimal whose value is `x` modulo `y`, rounded to `precision` significant digits + * using rounding mode `rounding`. + * + * x {number|string|Decimal} + * y {number|string|Decimal} + * + */ +function mod(x, y) { + return new this(x).mod(y); +} - if (sd === void 0) sd = this.precision; - else checkInt32(sd, 1, MAX_DIGITS); - k = Math.ceil(sd / LOG_BASE); +/* + * Return a new Decimal whose value is `x` multiplied by `y`, rounded to `precision` significant + * digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * y {number|string|Decimal} + * + */ +function mul(x, y) { + return new this(x).mul(y); +} - if (!this.crypto) { - for (; i < k;) rd[i++] = Math.random() * 1e7 | 0; - // Browsers supporting crypto.getRandomValues. - } else if (crypto.getRandomValues) { - d = crypto.getRandomValues(new Uint32Array(k)); +/* + * Return a new Decimal whose value is `x` raised to the power `y`, rounded to precision + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} The base. + * y {number|string|Decimal} The exponent. + * + */ +function pow(x, y) { + return new this(x).pow(y); +} - for (; i < k;) { - n = d[i]; - // 0 <= n < 4294967296 - // Probability n >= 4.29e9, is 4967296 / 4294967296 = 0.00116 (1 in 865). - if (n >= 4.29e9) { - d[i] = crypto.getRandomValues(new Uint32Array(1))[0]; - } else { +/* + * Returns a new Decimal with a random value equal to or greater than 0 and less than 1, and with + * `sd`, or `Decimal.precision` if `sd` is omitted, significant digits (or less if trailing zeros + * are produced). + * + * [sd] {number} Significant digits. Integer, 0 to MAX_DIGITS inclusive. + * + */ +function random(sd) { + var d, e, k, n, + i = 0, + r = new this(1), + rd = []; - // 0 <= n <= 4289999999 - // 0 <= (n % 1e7) <= 9999999 - rd[i++] = n % 1e7; - } - } + if (sd === void 0) sd = this.precision; + else checkInt32(sd, 1, MAX_DIGITS); - // Node.js supporting crypto.randomBytes. - } else if (crypto.randomBytes) { + k = Math.ceil(sd / LOG_BASE); - // buffer - d = crypto.randomBytes(k *= 4); + if (!this.crypto) { + for (; i < k;) rd[i++] = Math.random() * 1e7 | 0; - for (; i < k;) { + // Browsers supporting crypto.getRandomValues. + } else if (crypto.getRandomValues) { + d = crypto.getRandomValues(new Uint32Array(k)); - // 0 <= n < 2147483648 - n = d[i] + (d[i + 1] << 8) + (d[i + 2] << 16) + ((d[i + 3] & 0x7f) << 24); + for (; i < k;) { + n = d[i]; - // Probability n >= 2.14e9, is 7483648 / 2147483648 = 0.0035 (1 in 286). - if (n >= 2.14e9) { - crypto.randomBytes(4).copy(d, i); - } else { + // 0 <= n < 4294967296 + // Probability n >= 4.29e9, is 4967296 / 4294967296 = 0.00116 (1 in 865). + if (n >= 4.29e9) { + d[i] = crypto.getRandomValues(new Uint32Array(1))[0]; + } else { - // 0 <= n <= 2139999999 - // 0 <= (n % 1e7) <= 9999999 - rd.push(n % 1e7); - i += 4; - } + // 0 <= n <= 4289999999 + // 0 <= (n % 1e7) <= 9999999 + rd[i++] = n % 1e7; } - - i = k / 4; - } else { - throw Error(cryptoUnavailable); } - k = rd[--i]; - sd %= LOG_BASE; - - // Convert trailing digits to zeros according to sd. - if (k && sd) { - n = mathpow(10, LOG_BASE - sd); - rd[i] = (k / n | 0) * n; - } + // Node.js supporting crypto.randomBytes. + } else if (crypto.randomBytes) { - // Remove trailing words which are zero. - for (; rd[i] === 0; i--) rd.pop(); + // buffer + d = crypto.randomBytes(k *= 4); - // Zero? - if (i < 0) { - e = 0; - rd = [0]; - } else { - e = -1; + for (; i < k;) { - // Remove leading words which are zero and adjust exponent accordingly. - for (; rd[0] === 0; e -= LOG_BASE) rd.shift(); + // 0 <= n < 2147483648 + n = d[i] + (d[i + 1] << 8) + (d[i + 2] << 16) + ((d[i + 3] & 0x7f) << 24); - // Count the digits of the first word of rd to determine leading zeros. - for (k = 1, n = rd[0]; n >= 10; n /= 10) k++; + // Probability n >= 2.14e9, is 7483648 / 2147483648 = 0.0035 (1 in 286). + if (n >= 2.14e9) { + crypto.randomBytes(4).copy(d, i); + } else { - // Adjust the exponent for leading zeros of the first word of rd. - if (k < LOG_BASE) e -= LOG_BASE - k; + // 0 <= n <= 2139999999 + // 0 <= (n % 1e7) <= 9999999 + rd.push(n % 1e7); + i += 4; + } } - r.e = e; - r.d = rd; - - return r; + i = k / 4; + } else { + throw Error(cryptoUnavailable); } + k = rd[--i]; + sd %= LOG_BASE; - /* - * Return a new Decimal whose value is `x` rounded to an integer using rounding mode `rounding`. - * - * To emulate `Math.round`, set rounding to 7 (ROUND_HALF_CEIL). - * - * x {number|string|Decimal} - * - */ - function round(x) { - return finalise(x = new this(x), x.e + 1, this.rounding); + // Convert trailing digits to zeros according to sd. + if (k && sd) { + n = mathpow(10, LOG_BASE - sd); + rd[i] = (k / n | 0) * n; } + // Remove trailing words which are zero. + for (; rd[i] === 0; i--) rd.pop(); - /* - * Return - * 1 if x > 0, - * -1 if x < 0, - * 0 if x is 0, - * -0 if x is -0, - * NaN otherwise - * - */ - function sign(x) { - x = new this(x); - return x.d ? (x.d[0] ? x.s : 0 * x.s) : x.s || NaN; - } + // Zero? + if (i < 0) { + e = 0; + rd = [0]; + } else { + e = -1; + // Remove leading words which are zero and adjust exponent accordingly. + for (; rd[0] === 0; e -= LOG_BASE) rd.shift(); - /* - * Return a new Decimal whose value is the sine of `x`, rounded to `precision` significant digits - * using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function sin(x) { - return new this(x).sin(); + // Count the digits of the first word of rd to determine leading zeros. + for (k = 1, n = rd[0]; n >= 10; n /= 10) k++; + + // Adjust the exponent for leading zeros of the first word of rd. + if (k < LOG_BASE) e -= LOG_BASE - k; } + r.e = e; + r.d = rd; - /* - * Return a new Decimal whose value is the hyperbolic sine of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function sinh(x) { - return new this(x).sinh(); - } + return r; +} - /* - * Return a new Decimal whose value is the square root of `x`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function sqrt(x) { - return new this(x).sqrt(); - } +/* + * Return a new Decimal whose value is `x` rounded to an integer using rounding mode `rounding`. + * + * To emulate `Math.round`, set rounding to 7 (ROUND_HALF_CEIL). + * + * x {number|string|Decimal} + * + */ +function round(x) { + return finalise(x = new this(x), x.e + 1, this.rounding); +} - /* - * Return a new Decimal whose value is `x` minus `y`, rounded to `precision` significant digits - * using rounding mode `rounding`. - * - * x {number|string|Decimal} - * y {number|string|Decimal} - * - */ - function sub(x, y) { - return new this(x).sub(y); - } +/* + * Return + * 1 if x > 0, + * -1 if x < 0, + * 0 if x is 0, + * -0 if x is -0, + * NaN otherwise + * + */ +function sign(x) { + x = new this(x); + return x.d ? (x.d[0] ? x.s : 0 * x.s) : x.s || NaN; +} - /* - * Return a new Decimal whose value is the tangent of `x`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function tan(x) { - return new this(x).tan(); - } +/* + * Return a new Decimal whose value is the sine of `x`, rounded to `precision` significant digits + * using rounding mode `rounding`. + * + * x {number|string|Decimal} A value in radians. + * + */ +function sin(x) { + return new this(x).sin(); +} - /* - * Return a new Decimal whose value is the hyperbolic tangent of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function tanh(x) { - return new this(x).tanh(); - } +/* + * Return a new Decimal whose value is the hyperbolic sine of `x`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} A value in radians. + * + */ +function sinh(x) { + return new this(x).sinh(); +} - /* - * Return a new Decimal whose value is `x` truncated to an integer. - * - * x {number|string|Decimal} - * - */ - function trunc(x) { - return finalise(x = new this(x), x.e + 1, 1); - } +/* + * Return a new Decimal whose value is the square root of `x`, rounded to `precision` significant + * digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * + */ +function sqrt(x) { + return new this(x).sqrt(); +} + +/* + * Return a new Decimal whose value is `x` minus `y`, rounded to `precision` significant digits + * using rounding mode `rounding`. + * + * x {number|string|Decimal} + * y {number|string|Decimal} + * + */ +function sub(x, y) { + return new this(x).sub(y); +} - // Create and configure initial Decimal constructor. - Decimal = clone(Decimal); - // Create the internal constants from their string values. - LN10 = new Decimal(LN10); - PI = new Decimal(PI); +/* + * Return a new Decimal whose value is the tangent of `x`, rounded to `precision` significant + * digits using rounding mode `rounding`. + * + * x {number|string|Decimal} A value in radians. + * + */ +function tan(x) { + return new this(x).tan(); +} - // Export. +/* + * Return a new Decimal whose value is the hyperbolic tangent of `x`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} A value in radians. + * + */ +function tanh(x) { + return new this(x).tanh(); +} - // AMD. - if (true) { - !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () { - return Decimal; - }).call(exports, __webpack_require__, exports, module), - __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); +/* + * Return a new Decimal whose value is `x` truncated to an integer. + * + * x {number|string|Decimal} + * + */ +function trunc(x) { + return finalise(x = new this(x), x.e + 1, 1); +} + + +// Create and configure initial Decimal constructor. +Decimal = clone(defaults); + +// Create the internal constants from their string values. +LN10 = new Decimal(ln10); +PI = new Decimal(pi); - // Node and other environments that support module.exports. - } else {} -})(this); +/* harmony default export */ __webpack_exports__["default"] = (Decimal); /***/ }), @@ -29317,7 +29314,7 @@ function initBladeburner() { Skills[SkillNames.Overclock] = new Skill({ name:SkillNames.Overclock, desc:"Each level of this skill decreases the time it takes " + - "to attempt a contract or operation by 1% (Max Level: 99)", + "to attempt a contract or operation by 1% (Max Level: 95)", baseCost:5, costInc:1, maxLvl:95, actionTime:1 }); @@ -30289,8 +30286,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./NetscriptEvaluator.js */ 6); /* harmony import */ var _NetscriptEnvironment_js__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./NetscriptEnvironment.js */ 69); /* harmony import */ var _NetscriptPort_js__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./NetscriptPort.js */ 46); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../utils/decimal.js */ 24); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_27___default = /*#__PURE__*/__webpack_require__.n(_utils_decimal_js__WEBPACK_IMPORTED_MODULE_27__); +/* harmony import */ var decimal_js__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! decimal.js */ 24); /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../utils/DialogBox.js */ 7); /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1); /* harmony import */ var _utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ../utils/IPAddress.js */ 16); @@ -30419,7 +30415,7 @@ function NetscriptFunctions(workerScript) { Math : Math, Date : Date, Number : Number, - hacknetnodes : _Player_js__WEBPACK_IMPORTED_MODULE_15__["Player"].hacknetNodes, + hacknetnodes : _Player_js__WEBPACK_IMPORTED_MODULE_15__["Player"].hacknetNodeWrappers, sprintf : sprintf, vsprintf: vsprintf, scan : function(ip=workerScript.serverIp, hostnames=true){ @@ -31386,7 +31382,8 @@ function NetscriptFunctions(workerScript) { if (!hasAISF) { throw Object(_NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_24__["makeRuntimeRejectMsg"])(workerScript, "Cannot run getBitNodeMultipliers(). It requires Source-File 5 to run."); } - return _BitNode_js__WEBPACK_IMPORTED_MODULE_2__["BitNodeMultipliers"]; + let copy = Object.assign({}, _BitNode_js__WEBPACK_IMPORTED_MODULE_2__["BitNodeMultipliers"]); + return copy; }, getServerMoneyAvailable : function(ip){ if (workerScript.checkingRam) { @@ -52297,6 +52294,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateHacknetNodesContent", function() { return updateHacknetNodesContent; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "processAllHacknetNodeEarnings", function() { return processAllHacknetNodeEarnings; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getHacknetNode", function() { return getHacknetNode; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createPlayerHacknetNodeWrappers", function() { return createPlayerHacknetNodeWrappers; }); /* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BitNode.js */ 15); /* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Constants.js */ 3); /* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./engine.js */ 5); @@ -52362,6 +52360,7 @@ function HacknetNode(name) { this.moneyGainRatePerSecond = 0; } + HacknetNode.prototype.updateMoneyGainRate = function() { //How much extra $/s is gained per level var gainPerLevel = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMoneyGainPerLevel; @@ -52486,6 +52485,36 @@ HacknetNode.fromJSON = function(value) { _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_7__["Reviver"].constructors.HacknetNode = HacknetNode; +var HacknetNodeWrapper = function(hacknetNodeObj) { + var _node = hacknetNodeObj; + return { + name : _node.name, + level : _node.level, + ram : _node.ram, + cores : _node.cores, + totalMoneyGenerated : _node.totalMoneyGenerated, + onlineTimeSeconds : _node.onlineTimeSeconds, + moneyGainRatePerSecond : _node.moneyGainRatePerSecond, + upgradeLevel : function(n) { + return _node.upgradeLevel(n); + }, + upgradeRam : function() { + return _node.upgradeRam(); + }, + upgradeCore : function() { + return _node.upgradeCore(); + }, + getLevelUpgradeCost : function(n) { + return _node.getLevelUpgradeCost(n); + }, + getRamUpgradeCost : function() { + return _node.getRamUpgradeCost(); + }, + getCoreUpgradeCost : function() { + return _node.getCoreUpgradeCost(); + } + } +} function purchaseHacknet() { /* INTERACTIVE TUTORIAL */ @@ -52775,8 +52804,31 @@ function updateHacknetNodeDomElement(nodeObj) { } } +function createPlayerHacknetNodeWrappers() { + _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers.length = _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length; + for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length; ++i) { + _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers[i] = new HacknetNodeWrapper(_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i]); + } +} + +function updatePlayerHacknetNodeWrappers() { + if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers.length !== _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length) { + return createPlayerHacknetNodeWrappers(); + } + for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers.length; ++i) { + if (!(_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers[i] instanceof HacknetNodeWrapper)) {return createPlayerHacknetNodeWrappers();} + _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers[i].level = _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i].level; + _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers[i].ram = _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i].ram; + _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers[i].cores = _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i].cores; + _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers[i].totalMoneyGenerated = _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i].totalMoneyGenerated; + _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers[i].onlineTimeSeconds = _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i].onlineTimeSeconds; + _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers[i].moneyGainRatePerSecond = _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i].moneyGainRatePerSecond; + } +} + function processAllHacknetNodeEarnings(numCycles) { var total = 0; + updatePlayerHacknetNodeWrappers(); for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length; ++i) { total += processSingleHacknetNodeEarnings(numCycles, _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i]); } @@ -53128,8 +53180,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _Literature_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Literature.js */ 53); /* harmony import */ var _Location_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Location.js */ 4); /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Player.js */ 0); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/decimal.js */ 24); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_utils_decimal_js__WEBPACK_IMPORTED_MODULE_6__); +/* harmony import */ var decimal_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! decimal.js */ 24); /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/DialogBox.js */ 7); /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1); /* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8); @@ -53763,10 +53814,10 @@ function Industry(params={}) { this.prodMult = 0; //Production multiplier //Financials - this.lastCycleRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); - this.lastCycleExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); - this.thisCycleRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); - this.thisCycleExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); + this.lastCycleRevenue = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); + this.lastCycleExpenses = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); + this.thisCycleRevenue = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); + this.thisCycleExpenses = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); //Upgrades var numUpgrades = Object.keys(IndustryUpgrades).length; @@ -54064,13 +54115,13 @@ Industry.prototype.process = function(marketCycles=1, state, company) { console.log(this.thisCycleRevenue.toString()); console.log(this.thisCycleExpenses.toString()); Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Something went wrong when compting Corporation's revenue/expenses. This is a bug. Please report to game developer"); - this.thisCycleRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); - this.thisCycleExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); + this.thisCycleRevenue = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); + this.thisCycleExpenses = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); } this.lastCycleRevenue = this.thisCycleRevenue.dividedBy(marketCycles * SecsPerMarketCycle); this.lastCycleExpenses = this.thisCycleExpenses.dividedBy(marketCycles * SecsPerMarketCycle); - this.thisCycleRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); - this.thisCycleExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); + this.thisCycleRevenue = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); + this.thisCycleExpenses = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); //Once you start making revenue, the player should no longer be //considered new, and therefore no longer needs the 'tutorial' UI elements @@ -56181,9 +56232,9 @@ function Corporation(params={}) { this.divisions = []; //Financial stats - this.funds = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(150e9); - this.revenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); - this.expenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); + this.funds = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](150e9); + this.revenue = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); + this.expenses = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); this.fundingRound = 0; this.public = false; //Publicly traded this.numShares = TOTALSHARES; @@ -56217,8 +56268,8 @@ Corporation.prototype.process = function() { //At the start of a new cycle, calculate profits from previous cycle if (state === "START") { - this.revenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); - this.expenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); + this.revenue = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); + this.expenses = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); this.divisions.forEach((ind)=>{ this.revenue = this.revenue.plus(ind.lastCycleRevenue); this.expenses = this.expenses.plus(ind.lastCycleExpenses); @@ -56229,7 +56280,7 @@ Corporation.prototype.process = function() { Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("There was an error calculating your Corporations funds and they got reset to 0. " + "This is a bug. Please report to game developer.

" + "(Your funds have been set to $150b for the inconvenience)"); - this.funds = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(150e9); + this.funds = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](150e9); } this.funds = this.funds.plus(cycleProfit); this.updateSharePrice(); @@ -57139,8 +57190,8 @@ Corporation.prototype.updateCorporationOverviewContent = function() { return; } var totalFunds = this.funds, - totalRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0), - totalExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); + totalRevenue = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0), + totalExpenses = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); var profit = this.revenue.minus(this.expenses).toNumber(), profitStr = profit >= 0 ? _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(profit).format("$0.000a") : "-" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(-1 * profit).format("$0.000a"); @@ -58810,8 +58861,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1); /* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8); /* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../utils/decimal.js */ 24); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20___default = /*#__PURE__*/__webpack_require__.n(_utils_decimal_js__WEBPACK_IMPORTED_MODULE_20__); +/* harmony import */ var decimal_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! decimal.js */ 24); @@ -59036,6 +59086,8 @@ function loadGame(saveString) { } } + //Re-initialize Hacknet Node Wrappers + Object(_HacknetNode_js__WEBPACK_IMPORTED_MODULE_7__["createPlayerHacknetNodeWrappers"])(); return true; } @@ -59062,9 +59114,9 @@ function loadImportedGame(saveObj, saveString) { tempPlayer = JSON.parse(tempSaveObj.PlayerSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]); //Parse Decimal.js objects - tempPlayer.money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20___default.a(tempPlayer.money); - tempPlayer.total_money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20___default.a(tempPlayer.total_money); - tempPlayer.lifetime_money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20___default.a(tempPlayer.lifetime_money); + tempPlayer.money = new decimal_js__WEBPACK_IMPORTED_MODULE_20__["default"](tempPlayer.money); + tempPlayer.total_money = new decimal_js__WEBPACK_IMPORTED_MODULE_20__["default"](tempPlayer.total_money); + tempPlayer.lifetime_money = new decimal_js__WEBPACK_IMPORTED_MODULE_20__["default"](tempPlayer.lifetime_money); tempAllServers = JSON.parse(tempSaveObj.AllServersSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]); tempCompanies = JSON.parse(tempSaveObj.CompaniesSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]); @@ -59252,6 +59304,9 @@ function loadImportedGame(saveObj, saveString) { } } + //Re-initialize Hacknet Node Wrappers + Object(_HacknetNode_js__WEBPACK_IMPORTED_MODULE_7__["createPlayerHacknetNodeWrappers"])(); + var popupId = "import-game-restart-game-notice"; var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__["createElement"])("p", { innerText:"Imported game! I would suggest saving the game and then reloading the page " + @@ -60687,8 +60742,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./SpecialServerIps.js */ 17); /* harmony import */ var _StockMarket_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./StockMarket.js */ 22); /* harmony import */ var _Terminal_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./Terminal.js */ 18); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../utils/decimal.js */ 24); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18___default = /*#__PURE__*/__webpack_require__.n(_utils_decimal_js__WEBPACK_IMPORTED_MODULE_18__); +/* harmony import */ var decimal_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! decimal.js */ 24); /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../utils/DialogBox.js */ 7); /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1); /* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 12); @@ -60715,6 +60769,8 @@ __webpack_require__.r(__webpack_exports__); + +let BitNode8StartingMoney = 250e6; //Prestige by purchasing augmentation function prestigeAugmentation() { @@ -60743,7 +60799,7 @@ function prestigeAugmentation() { } if (Object(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["augmentationExists"])(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["AugmentationNames"].CashRoot) && _Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["Augmentations"][_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["AugmentationNames"].CashRoot].owned) { - _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].setMoney(new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18___default.a(1000000)); + _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].setMoney(new decimal_js__WEBPACK_IMPORTED_MODULE_18__["default"](1000000)); homeComp.programs.push(_CreateProgram_js__WEBPACK_IMPORTED_MODULE_5__["Programs"].BruteSSHProgram); } @@ -60809,7 +60865,7 @@ function prestigeAugmentation() { _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bladeburner = null; //BitNode 8: Ghost of Wall Street - if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 8) {_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18___default.a(100e6);} + if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 8) {_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].money = new decimal_js__WEBPACK_IMPORTED_MODULE_18__["default"](BitNode8StartingMoney);} if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 8 || _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_11__["hasWallStreetSF"]) { _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].hasWseAccount = true; _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].hasTixApiAccess = true; @@ -60937,7 +60993,7 @@ function prestigeSourceFile() { //BitNode 3: Corporatocracy if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 3) { - _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18___default.a(150e9); + _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].money = new decimal_js__WEBPACK_IMPORTED_MODULE_18__["default"](150e9); homeComp.messages.push("corporation-management-handbook.lit"); Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_19__["dialogBoxCreate"])("You received a copy of the Corporation Management Handbook on your home computer. " + "Read it if you need help getting started with Corporations!"); @@ -60987,6 +61043,13 @@ function prestigeSourceFile() { } + //BitNode 8: Ghost of Wall Street + if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 8) {_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].money = new decimal_js__WEBPACK_IMPORTED_MODULE_18__["default"](BitNode8StartingMoney);} + if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 8 || _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_11__["hasWallStreetSF"]) { + _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].hasWseAccount = true; + _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].hasTixApiAccess = true; + } + //Gain int exp _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].gainIntelligenceExp(5); } @@ -95697,7 +95760,7 @@ var NetscriptHighlightRules = function(options) { "JSON|Math|" + // Other "this|arguments|prototype|window|document" , // Pseudo "keyword": - "const|yield|import|get|set|async|await|foop|" + + "const|yield|import|get|set|async|await|" + "break|case|catch|continue|default|delete|do|else|finally|for|function|" + "if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|" + "__parent__|__count__|escape|unescape|with|__proto__|" + diff --git a/dist/tests.bundle.js b/dist/tests.bundle.js index c9c7a4235f..2fb124d925 100644 --- a/dist/tests.bundle.js +++ b/dist/tests.bundle.js @@ -95,8 +95,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _Server_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./Server.js */ 10); /* harmony import */ var _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./SpecialServerIps.js */ 17); /* harmony import */ var _SourceFile_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./SourceFile.js */ 44); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../utils/decimal.js */ 24); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(_utils_decimal_js__WEBPACK_IMPORTED_MODULE_15__); +/* harmony import */ var decimal_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! decimal.js */ 24); /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../utils/DialogBox.js */ 7); /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1); /* harmony import */ var _utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../utils/IPAddress.js */ 16); @@ -179,9 +178,9 @@ function PlayerObject() { this.faction_rep_mult = 1; //Money - this.money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(1000); - this.total_money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(0); //Total money ever earned in this "simulation" - this.lifetime_money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(0); //Total money ever earned + this.money = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](1000); + this.total_money = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](0); //Total money ever earned in this "simulation" + this.lifetime_money = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](0); //Total money ever earned //IP Address of Starting (home) computer this.homeComputer = ""; @@ -198,6 +197,7 @@ function PlayerObject() { this.currentServer = ""; //IP address of Server currently being accessed through terminal this.purchasedServers = []; //IP Addresses of purchased servers this.hacknetNodes = []; + this.hacknetNodeWrappers = []; this.totalHacknetNodeProduction = 0; //Factions @@ -345,7 +345,7 @@ PlayerObject.prototype.prestigeAugmentation = function() { this.agility_exp = 0; this.charisma_exp = 0; - this.money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(1000); + this.money = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](1000); this.city = _Location_js__WEBPACK_IMPORTED_MODULE_10__["Locations"].Sector12; this.location = ""; @@ -426,7 +426,7 @@ PlayerObject.prototype.prestigeSourceFile = function() { this.agility_exp = 0; this.charisma_exp = 0; - this.money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(1000); + this.money = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](1000); this.city = _Location_js__WEBPACK_IMPORTED_MODULE_10__["Locations"].Sector12; this.location = ""; @@ -486,19 +486,11 @@ PlayerObject.prototype.prestigeSourceFile = function() { this.hasTixApiAccess = false; //BitNode 3: Corporatocracy - if (this.bitNodeN === 3) {this.money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(150e9);} + if (this.bitNodeN === 3) {this.money = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](150e9);} this.corporation = 0; - //Reset Bladeburner this.bladeburner = 0; - //BitNode 8: Ghost of Wall Street - if (this.bitNodeN === 8) {this.money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(100000000);} - if (this.bitNodeN === 8 || _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_11__["hasWallStreetSF"]) { - this.hasWseAccount = true; - this.hasTixApiAccess = true; - } - this.playtimeSinceLastAug = 0; this.scriptProdSinceLastAug = 0; } @@ -2453,21 +2445,21 @@ function loadPlayer(saveString) { Player = JSON.parse(saveString, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_19__["Reviver"]); //Parse Decimal.js objects - Player.money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(Player.money); - Player.total_money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(Player.total_money); - Player.lifetime_money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(Player.lifetime_money); + Player.money = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](Player.money); + Player.total_money = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](Player.total_money); + Player.lifetime_money = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](Player.lifetime_money); if (Player.corporation instanceof _CompanyManagement_js__WEBPACK_IMPORTED_MODULE_4__["Corporation"]) { - Player.corporation.funds = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(Player.corporation.funds); - Player.corporation.revenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(Player.corporation.revenue); - Player.corporation.expenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(Player.corporation.expenses); + Player.corporation.funds = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](Player.corporation.funds); + Player.corporation.revenue = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](Player.corporation.revenue); + Player.corporation.expenses = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](Player.corporation.expenses); for (var i = 0; i < Player.corporation.divisions.length; ++i) { var ind = Player.corporation.divisions[i]; - ind.lastCycleRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(ind.lastCycleRevenue); - ind.lastCycleExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(ind.lastCycleExpenses); - ind.thisCycleRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(ind.thisCycleRevenue); - ind.thisCycleExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_15___default.a(ind.thisCycleExpenses); + ind.lastCycleRevenue = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](ind.lastCycleRevenue); + ind.lastCycleExpenses = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](ind.lastCycleExpenses); + ind.thisCycleRevenue = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](ind.thisCycleRevenue); + ind.thisCycleExpenses = new decimal_js__WEBPACK_IMPORTED_MODULE_15__["default"](ind.thisCycleExpenses); } } } @@ -2957,7 +2949,7 @@ function generateRandomString(n) { __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CONSTANTS", function() { return CONSTANTS; }); let CONSTANTS = { - Version: "0.37.1", + Version: "0.37.2", //Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience //and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then @@ -3442,16 +3434,13 @@ let CONSTANTS = { "World Stock Exchange account and TIX API Access
", LatestUpdate: - "v0.37.1
" + - "* You now earn money from successfully completing Bladeburner contracts. The amount you earn is based " + - "on the difficulty of the contract.
" + - "* Completing Field Analysis in Bladeburner now grants 0.1 rank
" + - "* The maximum RAM you can get on a purchased server is now 1,048,576GB (2^20)
" + - "* Bug Fix: Fixed Netscript syntax highlighting issues with the new NetscriptJS
" + - "* Bug Fix: Netscript Functions now properly incur RAM costs in NetscriptJS
" + - "* Bug Fix: deleteServer() now fails if its called on the server you are currently connected to
" + - "* Removed in-game Netscript documentation, since it was outdated and difficult to maintain.
" + - "* Bug Fix: Updated the gymWorkout() Singularity function with the new exp/cost values for gyms
" + "v0.37.2
" + + "* After joining the Bladeburners division, there is now a button to go to the Bladeburner content " + + "in the 'City' page
" + + "* You now start with $250m in BitNode-8 (increased from $100m)
" + + "* Bug Fix: You can now no longer directly edit Hacknet Node values through NetscriptJS (hopefully)
" + + "* Bug Fix: Bladeburners is no longer accessible in BN-8
" + + "* Bug Fix: getBitNodeMultipliers() Netscript function now returns a copy rather than the original object
" } @@ -4199,6 +4188,7 @@ function displayLocationContent() { securityJob.style.display = "block"; agentJob.style.display = "block"; if (_Player_js__WEBPACK_IMPORTED_MODULE_8__["Player"].bitNodeN === 6 || _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_7__["hasBladeburnerSF"] === true) { + if (_Player_js__WEBPACK_IMPORTED_MODULE_8__["Player"].bitNodeN === 8) {break;} if (_Player_js__WEBPACK_IMPORTED_MODULE_8__["Player"].bladeburner instanceof _Bladeburner_js__WEBPACK_IMPORTED_MODULE_0__["Bladeburner"]) { //Note: Can't infiltrate NSA when part of bladeburner nsaBladeburner.innerText = "Enter Bladeburner Headquarters"; @@ -6349,6 +6339,7 @@ let Engine = { //Generic Locations (common to every city): // World Stock Exchange // Corporation (if applicable) + // Bladeburner HQ (if applicable); var genericLocationsList = document.getElementById("generic-locations-list"); genericLocationsList.style.display = "inline"; Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["removeChildrenFromElement"])(genericLocationsList); @@ -6375,6 +6366,18 @@ let Engine = { })); genericLocationsList.appendChild(li); } + + if (_Player_js__WEBPACK_IMPORTED_MODULE_26__["Player"].bladeburner instanceof _Bladeburner_js__WEBPACK_IMPORTED_MODULE_9__["Bladeburner"]) { + var li = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("li"); + li.appendChild(Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_2__["createElement"])("a", { + innerText:"Bladeburner Headquarters", class:"a-link-button", + clickListener:()=>{ + Engine.loadBladeburnerContent(); + return false; + } + })); + genericLocationsList.appendChild(li); + } }, displayFactionsInfo: function() { @@ -6437,9 +6440,9 @@ let Engine = { clickListener:()=>{ Object(_Faction_js__WEBPACK_IMPORTED_MODULE_15__["joinFaction"])(_Faction_js__WEBPACK_IMPORTED_MODULE_15__["Factions"][factionName]); for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_26__["Player"].factionInvitations.length; ++i) { - if (_Player_js__WEBPACK_IMPORTED_MODULE_26__["Player"].factionInvitations[i] == factionName) { + if (_Player_js__WEBPACK_IMPORTED_MODULE_26__["Player"].factionInvitations[i] == factionName || _Faction_js__WEBPACK_IMPORTED_MODULE_15__["Factions"][_Player_js__WEBPACK_IMPORTED_MODULE_26__["Player"].factionInvitations[i]].isBanned) { _Player_js__WEBPACK_IMPORTED_MODULE_26__["Player"].factionInvitations.splice(i, 1); - break; + i--; } } Engine.displayFactionsInfo(); @@ -18856,6 +18859,9 @@ function displayStockMarketContent() { wseAccountButton.innerText = "Buy WSE Account - $" + Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_10__["formatNumber"])(_Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].WSEAccountCost, 2).toString(); if (!_Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].hasWseAccount && _Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].money.gte(_Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].WSEAccountCost)) { wseAccountButton.setAttribute("class", "a-link-button"); + } else if (_Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].hasWseAccount){ + wseAccountButton.innerText = "WSE Account - Purchased"; + wseAccountButton.setAttribute("class", "a-link-button-bought"); } else { wseAccountButton.setAttribute("class", "a-link-button-inactive"); } @@ -18874,6 +18880,9 @@ function displayStockMarketContent() { Object(_utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_10__["formatNumber"])(_Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].TIXAPICost, 2).toString(); if (!_Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].hasTixApiAccess && _Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].money.gte(_Constants_js__WEBPACK_IMPORTED_MODULE_0__["CONSTANTS"].TIXAPICost)) { tixApiAccessButton.setAttribute("class", "a-link-button"); + } else if(_Player_js__WEBPACK_IMPORTED_MODULE_5__["Player"].hasTixApiAccess) { + tixApiAccessButton.innerText = "Trade Information eXchange (TIX) API Access - Purchased" + tixApiAccessButton.setAttribute("class", "a-link-button-bought"); } else { tixApiAccessButton.setAttribute("class", "a-link-button-inactive"); } @@ -19625,4807 +19634,4795 @@ function setSettingsLabels() { /***/ }), /* 24 */ -/*!**************************!*\ - !*** ./utils/decimal.js ***! - \**************************/ -/***/ (function(module, exports, __webpack_require__) { - -var __WEBPACK_AMD_DEFINE_RESULT__;/*! decimal.js v7.2.3 https://github.com/MikeMcl/decimal.js/LICENCE */ -;(function (globalScope) { - 'use strict'; - +/*!************************************************!*\ + !*** ./node_modules/decimal.js/decimal.es6.js ***! + \************************************************/ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - /* - * decimal.js v7.2.3 - * An arbitrary-precision Decimal type for JavaScript. - * https://github.com/MikeMcl/decimal.js - * Copyright (c) 2017 Michael Mclaughlin - * MIT Licence - */ +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* + * + * decimal.js v7.2.3 + * An arbitrary-precision Decimal type for JavaScript. + * https://github.com/MikeMcl/decimal.js + * Copyright (c) 2017 Michael Mclaughlin + * MIT Licence + * https://github.com/MikeMcl/decimal.js/LICENCE + * + */ - // ----------------------------------- EDITABLE DEFAULTS ------------------------------------ // +// ----------------------------------- EDITABLE DEFAULTS ------------------------------------ // - // The maximum exponent magnitude. - // The limit on the value of `toExpNeg`, `toExpPos`, `minE` and `maxE`. - var EXP_LIMIT = 9e15, // 0 to 9e15 + // The maximum exponent magnitude. + // The limit on the value of `toExpNeg`, `toExpPos`, `minE` and `maxE`. +var EXP_LIMIT = 9e15, // 0 to 9e15 - // The limit on the value of `precision`, and on the value of the first argument to - // `toDecimalPlaces`, `toExponential`, `toFixed`, `toPrecision` and `toSignificantDigits`. - MAX_DIGITS = 1e9, // 0 to 1e9 + // The limit on the value of `precision`, and on the value of the first argument to + // `toDecimalPlaces`, `toExponential`, `toFixed`, `toPrecision` and `toSignificantDigits`. + MAX_DIGITS = 1e9, // 0 to 1e9 - // Base conversion alphabet. - NUMERALS = '0123456789abcdef', - // The natural logarithm of 10 (1025 digits). - LN10 = '2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840422862486334095254650828067566662873690987816894829072083255546808437998948262331985283935053089653777326288461633662222876982198867465436674744042432743651550489343149393914796194044002221051017141748003688084012647080685567743216228355220114804663715659121373450747856947683463616792101806445070648000277502684916746550586856935673420670581136429224554405758925724208241314695689016758940256776311356919292033376587141660230105703089634572075440370847469940168269282808481184289314848524948644871927809676271275775397027668605952496716674183485704422507197965004714951050492214776567636938662976979522110718264549734772662425709429322582798502585509785265383207606726317164309505995087807523710333101197857547331541421808427543863591778117054309827482385045648019095610299291824318237525357709750539565187697510374970888692180205189339507238539205144634197265287286965110862571492198849978748873771345686209167058', + // Base conversion alphabet. + NUMERALS = '0123456789abcdef', - // Pi (1025 digits). - PI = '3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632789', + // The natural logarithm of 10 (1025 digits). + ln10 = '2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840422862486334095254650828067566662873690987816894829072083255546808437998948262331985283935053089653777326288461633662222876982198867465436674744042432743651550489343149393914796194044002221051017141748003688084012647080685567743216228355220114804663715659121373450747856947683463616792101806445070648000277502684916746550586856935673420670581136429224554405758925724208241314695689016758940256776311356919292033376587141660230105703089634572075440370847469940168269282808481184289314848524948644871927809676271275775397027668605952496716674183485704422507197965004714951050492214776567636938662976979522110718264549734772662425709429322582798502585509785265383207606726317164309505995087807523710333101197857547331541421808427543863591778117054309827482385045648019095610299291824318237525357709750539565187697510374970888692180205189339507238539205144634197265287286965110862571492198849978748873771345686209167058', + // Pi (1025 digits). + pi = '3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632789', - // The initial configuration properties of the Decimal constructor. - Decimal = { - // These values must be integers within the stated ranges (inclusive). - // Most of these values can be changed at run-time using the `Decimal.config` method. + // The initial configuration properties of the Decimal constructor. + defaults = { - // The maximum number of significant digits of the result of a calculation or base conversion. - // E.g. `Decimal.config({ precision: 20 });` - precision: 20, // 1 to MAX_DIGITS + // These values must be integers within the stated ranges (inclusive). + // Most of these values can be changed at run-time using the `Decimal.config` method. - // The rounding mode used when rounding to `precision`. - // - // ROUND_UP 0 Away from zero. - // ROUND_DOWN 1 Towards zero. - // ROUND_CEIL 2 Towards +Infinity. - // ROUND_FLOOR 3 Towards -Infinity. - // ROUND_HALF_UP 4 Towards nearest neighbour. If equidistant, up. - // ROUND_HALF_DOWN 5 Towards nearest neighbour. If equidistant, down. - // ROUND_HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour. - // ROUND_HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity. - // ROUND_HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity. - // - // E.g. - // `Decimal.rounding = 4;` - // `Decimal.rounding = Decimal.ROUND_HALF_UP;` - rounding: 4, // 0 to 8 - - // The modulo mode used when calculating the modulus: a mod n. - // The quotient (q = a / n) is calculated according to the corresponding rounding mode. - // The remainder (r) is calculated as: r = a - n * q. - // - // UP 0 The remainder is positive if the dividend is negative, else is negative. - // DOWN 1 The remainder has the same sign as the dividend (JavaScript %). - // FLOOR 3 The remainder has the same sign as the divisor (Python %). - // HALF_EVEN 6 The IEEE 754 remainder function. - // EUCLID 9 Euclidian division. q = sign(n) * floor(a / abs(n)). Always positive. - // - // Truncated division (1), floored division (3), the IEEE 754 remainder (6), and Euclidian - // division (9) are commonly used for the modulus operation. The other rounding modes can also - // be used, but they may not give useful results. - modulo: 1, // 0 to 9 + // The maximum number of significant digits of the result of a calculation or base conversion. + // E.g. `Decimal.config({ precision: 20 });` + precision: 20, // 1 to MAX_DIGITS - // The exponent value at and beneath which `toString` returns exponential notation. - // JavaScript numbers: -7 - toExpNeg: -7, // 0 to -EXP_LIMIT + // The rounding mode used when rounding to `precision`. + // + // ROUND_UP 0 Away from zero. + // ROUND_DOWN 1 Towards zero. + // ROUND_CEIL 2 Towards +Infinity. + // ROUND_FLOOR 3 Towards -Infinity. + // ROUND_HALF_UP 4 Towards nearest neighbour. If equidistant, up. + // ROUND_HALF_DOWN 5 Towards nearest neighbour. If equidistant, down. + // ROUND_HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour. + // ROUND_HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity. + // ROUND_HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity. + // + // E.g. + // `Decimal.rounding = 4;` + // `Decimal.rounding = Decimal.ROUND_HALF_UP;` + rounding: 4, // 0 to 8 + + // The modulo mode used when calculating the modulus: a mod n. + // The quotient (q = a / n) is calculated according to the corresponding rounding mode. + // The remainder (r) is calculated as: r = a - n * q. + // + // UP 0 The remainder is positive if the dividend is negative, else is negative. + // DOWN 1 The remainder has the same sign as the dividend (JavaScript %). + // FLOOR 3 The remainder has the same sign as the divisor (Python %). + // HALF_EVEN 6 The IEEE 754 remainder function. + // EUCLID 9 Euclidian division. q = sign(n) * floor(a / abs(n)). Always positive. + // + // Truncated division (1), floored division (3), the IEEE 754 remainder (6), and Euclidian + // division (9) are commonly used for the modulus operation. The other rounding modes can also + // be used, but they may not give useful results. + modulo: 1, // 0 to 9 - // The exponent value at and above which `toString` returns exponential notation. - // JavaScript numbers: 21 - toExpPos: 21, // 0 to EXP_LIMIT + // The exponent value at and beneath which `toString` returns exponential notation. + // JavaScript numbers: -7 + toExpNeg: -7, // 0 to -EXP_LIMIT - // The minimum exponent value, beneath which underflow to zero occurs. - // JavaScript numbers: -324 (5e-324) - minE: -EXP_LIMIT, // -1 to -EXP_LIMIT + // The exponent value at and above which `toString` returns exponential notation. + // JavaScript numbers: 21 + toExpPos: 21, // 0 to EXP_LIMIT - // The maximum exponent value, above which overflow to Infinity occurs. - // JavaScript numbers: 308 (1.7976931348623157e+308) - maxE: EXP_LIMIT, // 1 to EXP_LIMIT + // The minimum exponent value, beneath which underflow to zero occurs. + // JavaScript numbers: -324 (5e-324) + minE: -EXP_LIMIT, // -1 to -EXP_LIMIT - // Whether to use cryptographically-secure random number generation, if available. - crypto: false // true/false - }, + // The maximum exponent value, above which overflow to Infinity occurs. + // JavaScript numbers: 308 (1.7976931348623157e+308) + maxE: EXP_LIMIT, // 1 to EXP_LIMIT + // Whether to use cryptographically-secure random number generation, if available. + crypto: false // true/false + }, - // ----------------------------------- END OF EDITABLE DEFAULTS ------------------------------- // +// ----------------------------------- END OF EDITABLE DEFAULTS ------------------------------- // - inexact, noConflict, quadrant, - external = true, - decimalError = '[DecimalError] ', - invalidArgument = decimalError + 'Invalid argument: ', - precisionLimitExceeded = decimalError + 'Precision limit exceeded', - cryptoUnavailable = decimalError + 'crypto unavailable', + Decimal, LN10, PI, inexact, quadrant, + external = true, - mathfloor = Math.floor, - mathpow = Math.pow, + decimalError = '[DecimalError] ', + invalidArgument = decimalError + 'Invalid argument: ', + precisionLimitExceeded = decimalError + 'Precision limit exceeded', + cryptoUnavailable = decimalError + 'crypto unavailable', - isBinary = /^0b([01]+(\.[01]*)?|\.[01]+)(p[+-]?\d+)?$/i, - isHex = /^0x([0-9a-f]+(\.[0-9a-f]*)?|\.[0-9a-f]+)(p[+-]?\d+)?$/i, - isOctal = /^0o([0-7]+(\.[0-7]*)?|\.[0-7]+)(p[+-]?\d+)?$/i, - isDecimal = /^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i, + mathfloor = Math.floor, + mathpow = Math.pow, - BASE = 1e7, - LOG_BASE = 7, - MAX_SAFE_INTEGER = 9007199254740991, + isBinary = /^0b([01]+(\.[01]*)?|\.[01]+)(p[+-]?\d+)?$/i, + isHex = /^0x([0-9a-f]+(\.[0-9a-f]*)?|\.[0-9a-f]+)(p[+-]?\d+)?$/i, + isOctal = /^0o([0-7]+(\.[0-7]*)?|\.[0-7]+)(p[+-]?\d+)?$/i, + isDecimal = /^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i, - LN10_PRECISION = LN10.length - 1, - PI_PRECISION = PI.length - 1, + BASE = 1e7, + LOG_BASE = 7, + MAX_SAFE_INTEGER = 9007199254740991, - // Decimal.prototype object - P = {}; + LN10_PRECISION = ln10.length - 1, + PI_PRECISION = pi.length - 1, + // Decimal.prototype object + P = {}; - // Decimal prototype methods +// Decimal prototype methods - /* - * absoluteValue abs - * ceil - * comparedTo cmp - * cosine cos - * cubeRoot cbrt - * decimalPlaces dp - * dividedBy div - * dividedToIntegerBy divToInt - * equals eq - * floor - * greaterThan gt - * greaterThanOrEqualTo gte - * hyperbolicCosine cosh - * hyperbolicSine sinh - * hyperbolicTangent tanh - * inverseCosine acos - * inverseHyperbolicCosine acosh - * inverseHyperbolicSine asinh - * inverseHyperbolicTangent atanh - * inverseSine asin - * inverseTangent atan - * isFinite - * isInteger isInt - * isNaN - * isNegative isNeg - * isPositive isPos - * isZero - * lessThan lt - * lessThanOrEqualTo lte - * logarithm log - * [maximum] [max] - * [minimum] [min] - * minus sub - * modulo mod - * naturalExponential exp - * naturalLogarithm ln - * negated neg - * plus add - * precision sd - * round - * sine sin - * squareRoot sqrt - * tangent tan - * times mul - * toBinary - * toDecimalPlaces toDP - * toExponential - * toFixed - * toFraction - * toHexadecimal toHex - * toNearest - * toNumber - * toOctal - * toPower pow - * toPrecision - * toSignificantDigits toSD - * toString - * truncated trunc - * valueOf toJSON - */ +/* + * absoluteValue abs + * ceil + * comparedTo cmp + * cosine cos + * cubeRoot cbrt + * decimalPlaces dp + * dividedBy div + * dividedToIntegerBy divToInt + * equals eq + * floor + * greaterThan gt + * greaterThanOrEqualTo gte + * hyperbolicCosine cosh + * hyperbolicSine sinh + * hyperbolicTangent tanh + * inverseCosine acos + * inverseHyperbolicCosine acosh + * inverseHyperbolicSine asinh + * inverseHyperbolicTangent atanh + * inverseSine asin + * inverseTangent atan + * isFinite + * isInteger isInt + * isNaN + * isNegative isNeg + * isPositive isPos + * isZero + * lessThan lt + * lessThanOrEqualTo lte + * logarithm log + * [maximum] [max] + * [minimum] [min] + * minus sub + * modulo mod + * naturalExponential exp + * naturalLogarithm ln + * negated neg + * plus add + * precision sd + * round + * sine sin + * squareRoot sqrt + * tangent tan + * times mul + * toBinary + * toDecimalPlaces toDP + * toExponential + * toFixed + * toFraction + * toHexadecimal toHex + * toNearest + * toNumber + * toOctal + * toPower pow + * toPrecision + * toSignificantDigits toSD + * toString + * truncated trunc + * valueOf toJSON + */ - /* - * Return a new Decimal whose value is the absolute value of this Decimal. - * - */ - P.absoluteValue = P.abs = function () { - var x = new this.constructor(this); - if (x.s < 0) x.s = 1; - return finalise(x); - }; +/* + * Return a new Decimal whose value is the absolute value of this Decimal. + * + */ +P.absoluteValue = P.abs = function () { + var x = new this.constructor(this); + if (x.s < 0) x.s = 1; + return finalise(x); +}; - /* - * Return a new Decimal whose value is the value of this Decimal rounded to a whole number in the - * direction of positive Infinity. - * - */ - P.ceil = function () { - return finalise(new this.constructor(this), this.e + 1, 2); - }; +/* + * Return a new Decimal whose value is the value of this Decimal rounded to a whole number in the + * direction of positive Infinity. + * + */ +P.ceil = function () { + return finalise(new this.constructor(this), this.e + 1, 2); +}; - /* - * Return - * 1 if the value of this Decimal is greater than the value of `y`, - * -1 if the value of this Decimal is less than the value of `y`, - * 0 if they have the same value, - * NaN if the value of either Decimal is NaN. - * - */ - P.comparedTo = P.cmp = function (y) { - var i, j, xdL, ydL, - x = this, - xd = x.d, - yd = (y = new x.constructor(y)).d, - xs = x.s, - ys = y.s; - // Either NaN or ±Infinity? - if (!xd || !yd) { - return !xs || !ys ? NaN : xs !== ys ? xs : xd === yd ? 0 : !xd ^ xs < 0 ? 1 : -1; - } +/* + * Return + * 1 if the value of this Decimal is greater than the value of `y`, + * -1 if the value of this Decimal is less than the value of `y`, + * 0 if they have the same value, + * NaN if the value of either Decimal is NaN. + * + */ +P.comparedTo = P.cmp = function (y) { + var i, j, xdL, ydL, + x = this, + xd = x.d, + yd = (y = new x.constructor(y)).d, + xs = x.s, + ys = y.s; - // Either zero? - if (!xd[0] || !yd[0]) return xd[0] ? xs : yd[0] ? -ys : 0; + // Either NaN or ±Infinity? + if (!xd || !yd) { + return !xs || !ys ? NaN : xs !== ys ? xs : xd === yd ? 0 : !xd ^ xs < 0 ? 1 : -1; + } - // Signs differ? - if (xs !== ys) return xs; + // Either zero? + if (!xd[0] || !yd[0]) return xd[0] ? xs : yd[0] ? -ys : 0; - // Compare exponents. - if (x.e !== y.e) return x.e > y.e ^ xs < 0 ? 1 : -1; + // Signs differ? + if (xs !== ys) return xs; - xdL = xd.length; - ydL = yd.length; + // Compare exponents. + if (x.e !== y.e) return x.e > y.e ^ xs < 0 ? 1 : -1; - // Compare digit by digit. - for (i = 0, j = xdL < ydL ? xdL : ydL; i < j; ++i) { - if (xd[i] !== yd[i]) return xd[i] > yd[i] ^ xs < 0 ? 1 : -1; - } + xdL = xd.length; + ydL = yd.length; - // Compare lengths. - return xdL === ydL ? 0 : xdL > ydL ^ xs < 0 ? 1 : -1; - }; + // Compare digit by digit. + for (i = 0, j = xdL < ydL ? xdL : ydL; i < j; ++i) { + if (xd[i] !== yd[i]) return xd[i] > yd[i] ^ xs < 0 ? 1 : -1; + } + // Compare lengths. + return xdL === ydL ? 0 : xdL > ydL ^ xs < 0 ? 1 : -1; +}; - /* - * Return a new Decimal whose value is the cosine of the value in radians of this Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-1, 1] - * - * cos(0) = 1 - * cos(-0) = 1 - * cos(Infinity) = NaN - * cos(-Infinity) = NaN - * cos(NaN) = NaN - * - */ - P.cosine = P.cos = function () { - var pr, rm, - x = this, - Ctor = x.constructor; - if (!x.d) return new Ctor(NaN); +/* + * Return a new Decimal whose value is the cosine of the value in radians of this Decimal. + * + * Domain: [-Infinity, Infinity] + * Range: [-1, 1] + * + * cos(0) = 1 + * cos(-0) = 1 + * cos(Infinity) = NaN + * cos(-Infinity) = NaN + * cos(NaN) = NaN + * + */ +P.cosine = P.cos = function () { + var pr, rm, + x = this, + Ctor = x.constructor; - // cos(0) = cos(-0) = 1 - if (!x.d[0]) return new Ctor(1); + if (!x.d) return new Ctor(NaN); - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + Math.max(x.e, x.sd()) + LOG_BASE; - Ctor.rounding = 1; + // cos(0) = cos(-0) = 1 + if (!x.d[0]) return new Ctor(1); - x = cosine(Ctor, toLessThanHalfPi(Ctor, x)); + pr = Ctor.precision; + rm = Ctor.rounding; + Ctor.precision = pr + Math.max(x.e, x.sd()) + LOG_BASE; + Ctor.rounding = 1; - Ctor.precision = pr; - Ctor.rounding = rm; + x = cosine(Ctor, toLessThanHalfPi(Ctor, x)); - return finalise(quadrant == 2 || quadrant == 3 ? x.neg() : x, pr, rm, true); - }; + Ctor.precision = pr; + Ctor.rounding = rm; + return finalise(quadrant == 2 || quadrant == 3 ? x.neg() : x, pr, rm, true); +}; - /* - * - * Return a new Decimal whose value is the cube root of the value of this Decimal, rounded to - * `precision` significant digits using rounding mode `rounding`. - * - * cbrt(0) = 0 - * cbrt(-0) = -0 - * cbrt(1) = 1 - * cbrt(-1) = -1 - * cbrt(N) = N - * cbrt(-I) = -I - * cbrt(I) = I - * - * Math.cbrt(x) = (x < 0 ? -Math.pow(-x, 1/3) : Math.pow(x, 1/3)) - * - */ - P.cubeRoot = P.cbrt = function () { - var e, m, n, r, rep, s, sd, t, t3, t3plusx, - x = this, - Ctor = x.constructor; - if (!x.isFinite() || x.isZero()) return new Ctor(x); - external = false; +/* + * + * Return a new Decimal whose value is the cube root of the value of this Decimal, rounded to + * `precision` significant digits using rounding mode `rounding`. + * + * cbrt(0) = 0 + * cbrt(-0) = -0 + * cbrt(1) = 1 + * cbrt(-1) = -1 + * cbrt(N) = N + * cbrt(-I) = -I + * cbrt(I) = I + * + * Math.cbrt(x) = (x < 0 ? -Math.pow(-x, 1/3) : Math.pow(x, 1/3)) + * + */ +P.cubeRoot = P.cbrt = function () { + var e, m, n, r, rep, s, sd, t, t3, t3plusx, + x = this, + Ctor = x.constructor; - // Initial estimate. - s = x.s * Math.pow(x.s * x, 1 / 3); + if (!x.isFinite() || x.isZero()) return new Ctor(x); + external = false; - // Math.cbrt underflow/overflow? - // Pass x to Math.pow as integer, then adjust the exponent of the result. - if (!s || Math.abs(s) == 1 / 0) { - n = digitsToString(x.d); - e = x.e; + // Initial estimate. + s = x.s * Math.pow(x.s * x, 1 / 3); - // Adjust n exponent so it is a multiple of 3 away from x exponent. - if (s = (e - n.length + 1) % 3) n += (s == 1 || s == -2 ? '0' : '00'); - s = Math.pow(n, 1 / 3); + // Math.cbrt underflow/overflow? + // Pass x to Math.pow as integer, then adjust the exponent of the result. + if (!s || Math.abs(s) == 1 / 0) { + n = digitsToString(x.d); + e = x.e; - // Rarely, e may be one less than the result exponent value. - e = mathfloor((e + 1) / 3) - (e % 3 == (e < 0 ? -1 : 2)); + // Adjust n exponent so it is a multiple of 3 away from x exponent. + if (s = (e - n.length + 1) % 3) n += (s == 1 || s == -2 ? '0' : '00'); + s = Math.pow(n, 1 / 3); - if (s == 1 / 0) { - n = '5e' + e; - } else { - n = s.toExponential(); - n = n.slice(0, n.indexOf('e') + 1) + e; - } + // Rarely, e may be one less than the result exponent value. + e = mathfloor((e + 1) / 3) - (e % 3 == (e < 0 ? -1 : 2)); - r = new Ctor(n); - r.s = x.s; + if (s == 1 / 0) { + n = '5e' + e; } else { - r = new Ctor(s.toString()); + n = s.toExponential(); + n = n.slice(0, n.indexOf('e') + 1) + e; } - sd = (e = Ctor.precision) + 3; - - // Halley's method. - // TODO? Compare Newton's method. - for (;;) { - t = r; - t3 = t.times(t).times(t); - t3plusx = t3.plus(x); - r = divide(t3plusx.plus(x).times(t), t3plusx.plus(t3), sd + 2, 1); - - // TODO? Replace with for-loop and checkRoundingDigits. - if (digitsToString(t.d).slice(0, sd) === (n = digitsToString(r.d)).slice(0, sd)) { - n = n.slice(sd - 3, sd + 1); - - // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or 4999 - // , i.e. approaching a rounding boundary, continue the iteration. - if (n == '9999' || !rep && n == '4999') { + r = new Ctor(n); + r.s = x.s; + } else { + r = new Ctor(s.toString()); + } - // On the first iteration only, check to see if rounding up gives the exact result as the - // nines may infinitely repeat. - if (!rep) { - finalise(t, e + 1, 0); + sd = (e = Ctor.precision) + 3; - if (t.times(t).times(t).eq(x)) { - r = t; - break; - } + // Halley's method. + // TODO? Compare Newton's method. + for (;;) { + t = r; + t3 = t.times(t).times(t); + t3plusx = t3.plus(x); + r = divide(t3plusx.plus(x).times(t), t3plusx.plus(t3), sd + 2, 1); + + // TODO? Replace with for-loop and checkRoundingDigits. + if (digitsToString(t.d).slice(0, sd) === (n = digitsToString(r.d)).slice(0, sd)) { + n = n.slice(sd - 3, sd + 1); + + // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or 4999 + // , i.e. approaching a rounding boundary, continue the iteration. + if (n == '9999' || !rep && n == '4999') { + + // On the first iteration only, check to see if rounding up gives the exact result as the + // nines may infinitely repeat. + if (!rep) { + finalise(t, e + 1, 0); + + if (t.times(t).times(t).eq(x)) { + r = t; + break; } + } - sd += 4; - rep = 1; - } else { - - // If the rounding digits are null, 0{0,4} or 50{0,3}, check for an exact result. - // If not, then there are further digits and m will be truthy. - if (!+n || !+n.slice(1) && n.charAt(0) == '5') { + sd += 4; + rep = 1; + } else { - // Truncate to the first rounding digit. - finalise(r, e + 1, 1); - m = !r.times(r).times(r).eq(x); - } + // If the rounding digits are null, 0{0,4} or 50{0,3}, check for an exact result. + // If not, then there are further digits and m will be truthy. + if (!+n || !+n.slice(1) && n.charAt(0) == '5') { - break; + // Truncate to the first rounding digit. + finalise(r, e + 1, 1); + m = !r.times(r).times(r).eq(x); } + + break; } } + } - external = true; - - return finalise(r, e, Ctor.rounding, m); - }; - - - /* - * Return the number of decimal places of the value of this Decimal. - * - */ - P.decimalPlaces = P.dp = function () { - var w, - d = this.d, - n = NaN; - - if (d) { - w = d.length - 1; - n = (w - mathfloor(this.e / LOG_BASE)) * LOG_BASE; + external = true; - // Subtract the number of trailing zeros of the last word. - w = d[w]; - if (w) for (; w % 10 == 0; w /= 10) n--; - if (n < 0) n = 0; - } + return finalise(r, e, Ctor.rounding, m); +}; - return n; - }; +/* + * Return the number of decimal places of the value of this Decimal. + * + */ +P.decimalPlaces = P.dp = function () { + var w, + d = this.d, + n = NaN; - /* - * n / 0 = I - * n / N = N - * n / I = 0 - * 0 / n = 0 - * 0 / 0 = N - * 0 / N = N - * 0 / I = 0 - * N / n = N - * N / 0 = N - * N / N = N - * N / I = N - * I / n = I - * I / 0 = I - * I / N = N - * I / I = N - * - * Return a new Decimal whose value is the value of this Decimal divided by `y`, rounded to - * `precision` significant digits using rounding mode `rounding`. - * - */ - P.dividedBy = P.div = function (y) { - return divide(this, new this.constructor(y)); - }; + if (d) { + w = d.length - 1; + n = (w - mathfloor(this.e / LOG_BASE)) * LOG_BASE; + // Subtract the number of trailing zeros of the last word. + w = d[w]; + if (w) for (; w % 10 == 0; w /= 10) n--; + if (n < 0) n = 0; + } - /* - * Return a new Decimal whose value is the integer part of dividing the value of this Decimal - * by the value of `y`, rounded to `precision` significant digits using rounding mode `rounding`. - * - */ - P.dividedToIntegerBy = P.divToInt = function (y) { - var x = this, - Ctor = x.constructor; - return finalise(divide(x, new Ctor(y), 0, 1, 1), Ctor.precision, Ctor.rounding); - }; + return n; +}; - /* - * Return true if the value of this Decimal is equal to the value of `y`, otherwise return false. - * - */ - P.equals = P.eq = function (y) { - return this.cmp(y) === 0; - }; +/* + * n / 0 = I + * n / N = N + * n / I = 0 + * 0 / n = 0 + * 0 / 0 = N + * 0 / N = N + * 0 / I = 0 + * N / n = N + * N / 0 = N + * N / N = N + * N / I = N + * I / n = I + * I / 0 = I + * I / N = N + * I / I = N + * + * Return a new Decimal whose value is the value of this Decimal divided by `y`, rounded to + * `precision` significant digits using rounding mode `rounding`. + * + */ +P.dividedBy = P.div = function (y) { + return divide(this, new this.constructor(y)); +}; - /* - * Return a new Decimal whose value is the value of this Decimal rounded to a whole number in the - * direction of negative Infinity. - * - */ - P.floor = function () { - return finalise(new this.constructor(this), this.e + 1, 3); - }; +/* + * Return a new Decimal whose value is the integer part of dividing the value of this Decimal + * by the value of `y`, rounded to `precision` significant digits using rounding mode `rounding`. + * + */ +P.dividedToIntegerBy = P.divToInt = function (y) { + var x = this, + Ctor = x.constructor; + return finalise(divide(x, new Ctor(y), 0, 1, 1), Ctor.precision, Ctor.rounding); +}; - /* - * Return true if the value of this Decimal is greater than the value of `y`, otherwise return - * false. - * - */ - P.greaterThan = P.gt = function (y) { - return this.cmp(y) > 0; - }; +/* + * Return true if the value of this Decimal is equal to the value of `y`, otherwise return false. + * + */ +P.equals = P.eq = function (y) { + return this.cmp(y) === 0; +}; - /* - * Return true if the value of this Decimal is greater than or equal to the value of `y`, - * otherwise return false. - * - */ - P.greaterThanOrEqualTo = P.gte = function (y) { - var k = this.cmp(y); - return k == 1 || k === 0; - }; +/* + * Return a new Decimal whose value is the value of this Decimal rounded to a whole number in the + * direction of negative Infinity. + * + */ +P.floor = function () { + return finalise(new this.constructor(this), this.e + 1, 3); +}; - /* - * Return a new Decimal whose value is the hyperbolic cosine of the value in radians of this - * Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [1, Infinity] - * - * cosh(x) = 1 + x^2/2! + x^4/4! + x^6/6! + ... - * - * cosh(0) = 1 - * cosh(-0) = 1 - * cosh(Infinity) = Infinity - * cosh(-Infinity) = Infinity - * cosh(NaN) = NaN - * - * x time taken (ms) result - * 1000 9 9.8503555700852349694e+433 - * 10000 25 4.4034091128314607936e+4342 - * 100000 171 1.4033316802130615897e+43429 - * 1000000 3817 1.5166076984010437725e+434294 - * 10000000 abandoned after 2 minute wait - * - * TODO? Compare performance of cosh(x) = 0.5 * (exp(x) + exp(-x)) - * - */ - P.hyperbolicCosine = P.cosh = function () { - var k, n, pr, rm, len, - x = this, - Ctor = x.constructor, - one = new Ctor(1); +/* + * Return true if the value of this Decimal is greater than the value of `y`, otherwise return + * false. + * + */ +P.greaterThan = P.gt = function (y) { + return this.cmp(y) > 0; +}; - if (!x.isFinite()) return new Ctor(x.s ? 1 / 0 : NaN); - if (x.isZero()) return one; - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + Math.max(x.e, x.sd()) + 4; - Ctor.rounding = 1; - len = x.d.length; +/* + * Return true if the value of this Decimal is greater than or equal to the value of `y`, + * otherwise return false. + * + */ +P.greaterThanOrEqualTo = P.gte = function (y) { + var k = this.cmp(y); + return k == 1 || k === 0; +}; - // Argument reduction: cos(4x) = 1 - 8cos^2(x) + 8cos^4(x) + 1 - // i.e. cos(x) = 1 - cos^2(x/4)(8 - 8cos^2(x/4)) - // Estimate the optimum number of times to use the argument reduction. - // TODO? Estimation reused from cosine() and may not be optimal here. - if (len < 32) { - k = Math.ceil(len / 3); - n = Math.pow(4, -k).toString(); - } else { - k = 16; - n = '2.3283064365386962890625e-10'; - } +/* + * Return a new Decimal whose value is the hyperbolic cosine of the value in radians of this + * Decimal. + * + * Domain: [-Infinity, Infinity] + * Range: [1, Infinity] + * + * cosh(x) = 1 + x^2/2! + x^4/4! + x^6/6! + ... + * + * cosh(0) = 1 + * cosh(-0) = 1 + * cosh(Infinity) = Infinity + * cosh(-Infinity) = Infinity + * cosh(NaN) = NaN + * + * x time taken (ms) result + * 1000 9 9.8503555700852349694e+433 + * 10000 25 4.4034091128314607936e+4342 + * 100000 171 1.4033316802130615897e+43429 + * 1000000 3817 1.5166076984010437725e+434294 + * 10000000 abandoned after 2 minute wait + * + * TODO? Compare performance of cosh(x) = 0.5 * (exp(x) + exp(-x)) + * + */ +P.hyperbolicCosine = P.cosh = function () { + var k, n, pr, rm, len, + x = this, + Ctor = x.constructor, + one = new Ctor(1); + + if (!x.isFinite()) return new Ctor(x.s ? 1 / 0 : NaN); + if (x.isZero()) return one; + + pr = Ctor.precision; + rm = Ctor.rounding; + Ctor.precision = pr + Math.max(x.e, x.sd()) + 4; + Ctor.rounding = 1; + len = x.d.length; + + // Argument reduction: cos(4x) = 1 - 8cos^2(x) + 8cos^4(x) + 1 + // i.e. cos(x) = 1 - cos^2(x/4)(8 - 8cos^2(x/4)) + + // Estimate the optimum number of times to use the argument reduction. + // TODO? Estimation reused from cosine() and may not be optimal here. + if (len < 32) { + k = Math.ceil(len / 3); + n = Math.pow(4, -k).toString(); + } else { + k = 16; + n = '2.3283064365386962890625e-10'; + } - x = taylorSeries(Ctor, 1, x.times(n), new Ctor(1), true); + x = taylorSeries(Ctor, 1, x.times(n), new Ctor(1), true); - // Reverse argument reduction - var cosh2_x, - i = k, - d8 = new Ctor(8); - for (; i--;) { - cosh2_x = x.times(x); - x = one.minus(cosh2_x.times(d8.minus(cosh2_x.times(d8)))); - } + // Reverse argument reduction + var cosh2_x, + i = k, + d8 = new Ctor(8); + for (; i--;) { + cosh2_x = x.times(x); + x = one.minus(cosh2_x.times(d8.minus(cosh2_x.times(d8)))); + } - return finalise(x, Ctor.precision = pr, Ctor.rounding = rm, true); - }; + return finalise(x, Ctor.precision = pr, Ctor.rounding = rm, true); +}; - /* - * Return a new Decimal whose value is the hyperbolic sine of the value in radians of this - * Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-Infinity, Infinity] - * - * sinh(x) = x + x^3/3! + x^5/5! + x^7/7! + ... - * - * sinh(0) = 0 - * sinh(-0) = -0 - * sinh(Infinity) = Infinity - * sinh(-Infinity) = -Infinity - * sinh(NaN) = NaN - * - * x time taken (ms) - * 10 2 ms - * 100 5 ms - * 1000 14 ms - * 10000 82 ms - * 100000 886 ms 1.4033316802130615897e+43429 - * 200000 2613 ms - * 300000 5407 ms - * 400000 8824 ms - * 500000 13026 ms 8.7080643612718084129e+217146 - * 1000000 48543 ms - * - * TODO? Compare performance of sinh(x) = 0.5 * (exp(x) - exp(-x)) - * - */ - P.hyperbolicSine = P.sinh = function () { - var k, pr, rm, len, - x = this, - Ctor = x.constructor; +/* + * Return a new Decimal whose value is the hyperbolic sine of the value in radians of this + * Decimal. + * + * Domain: [-Infinity, Infinity] + * Range: [-Infinity, Infinity] + * + * sinh(x) = x + x^3/3! + x^5/5! + x^7/7! + ... + * + * sinh(0) = 0 + * sinh(-0) = -0 + * sinh(Infinity) = Infinity + * sinh(-Infinity) = -Infinity + * sinh(NaN) = NaN + * + * x time taken (ms) + * 10 2 ms + * 100 5 ms + * 1000 14 ms + * 10000 82 ms + * 100000 886 ms 1.4033316802130615897e+43429 + * 200000 2613 ms + * 300000 5407 ms + * 400000 8824 ms + * 500000 13026 ms 8.7080643612718084129e+217146 + * 1000000 48543 ms + * + * TODO? Compare performance of sinh(x) = 0.5 * (exp(x) - exp(-x)) + * + */ +P.hyperbolicSine = P.sinh = function () { + var k, pr, rm, len, + x = this, + Ctor = x.constructor; - if (!x.isFinite() || x.isZero()) return new Ctor(x); + if (!x.isFinite() || x.isZero()) return new Ctor(x); - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + Math.max(x.e, x.sd()) + 4; - Ctor.rounding = 1; - len = x.d.length; + pr = Ctor.precision; + rm = Ctor.rounding; + Ctor.precision = pr + Math.max(x.e, x.sd()) + 4; + Ctor.rounding = 1; + len = x.d.length; - if (len < 3) { - x = taylorSeries(Ctor, 2, x, x, true); - } else { + if (len < 3) { + x = taylorSeries(Ctor, 2, x, x, true); + } else { - // Alternative argument reduction: sinh(3x) = sinh(x)(3 + 4sinh^2(x)) - // i.e. sinh(x) = sinh(x/3)(3 + 4sinh^2(x/3)) - // 3 multiplications and 1 addition + // Alternative argument reduction: sinh(3x) = sinh(x)(3 + 4sinh^2(x)) + // i.e. sinh(x) = sinh(x/3)(3 + 4sinh^2(x/3)) + // 3 multiplications and 1 addition - // Argument reduction: sinh(5x) = sinh(x)(5 + sinh^2(x)(20 + 16sinh^2(x))) - // i.e. sinh(x) = sinh(x/5)(5 + sinh^2(x/5)(20 + 16sinh^2(x/5))) - // 4 multiplications and 2 additions + // Argument reduction: sinh(5x) = sinh(x)(5 + sinh^2(x)(20 + 16sinh^2(x))) + // i.e. sinh(x) = sinh(x/5)(5 + sinh^2(x/5)(20 + 16sinh^2(x/5))) + // 4 multiplications and 2 additions - // Estimate the optimum number of times to use the argument reduction. - k = 1.4 * Math.sqrt(len); - k = k > 16 ? 16 : k | 0; + // Estimate the optimum number of times to use the argument reduction. + k = 1.4 * Math.sqrt(len); + k = k > 16 ? 16 : k | 0; - x = x.times(Math.pow(5, -k)); + x = x.times(Math.pow(5, -k)); - x = taylorSeries(Ctor, 2, x, x, true); + x = taylorSeries(Ctor, 2, x, x, true); - // Reverse argument reduction - var sinh2_x, - d5 = new Ctor(5), - d16 = new Ctor(16), - d20 = new Ctor(20); - for (; k--;) { - sinh2_x = x.times(x); - x = x.times(d5.plus(sinh2_x.times(d16.times(sinh2_x).plus(d20)))); - } + // Reverse argument reduction + var sinh2_x, + d5 = new Ctor(5), + d16 = new Ctor(16), + d20 = new Ctor(20); + for (; k--;) { + sinh2_x = x.times(x); + x = x.times(d5.plus(sinh2_x.times(d16.times(sinh2_x).plus(d20)))); } + } - Ctor.precision = pr; - Ctor.rounding = rm; - - return finalise(x, pr, rm, true); - }; + Ctor.precision = pr; + Ctor.rounding = rm; + return finalise(x, pr, rm, true); +}; - /* - * Return a new Decimal whose value is the hyperbolic tangent of the value in radians of this - * Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-1, 1] - * - * tanh(x) = sinh(x) / cosh(x) - * - * tanh(0) = 0 - * tanh(-0) = -0 - * tanh(Infinity) = 1 - * tanh(-Infinity) = -1 - * tanh(NaN) = NaN - * - */ - P.hyperbolicTangent = P.tanh = function () { - var pr, rm, - x = this, - Ctor = x.constructor; - if (!x.isFinite()) return new Ctor(x.s); - if (x.isZero()) return new Ctor(x); +/* + * Return a new Decimal whose value is the hyperbolic tangent of the value in radians of this + * Decimal. + * + * Domain: [-Infinity, Infinity] + * Range: [-1, 1] + * + * tanh(x) = sinh(x) / cosh(x) + * + * tanh(0) = 0 + * tanh(-0) = -0 + * tanh(Infinity) = 1 + * tanh(-Infinity) = -1 + * tanh(NaN) = NaN + * + */ +P.hyperbolicTangent = P.tanh = function () { + var pr, rm, + x = this, + Ctor = x.constructor; - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + 7; - Ctor.rounding = 1; + if (!x.isFinite()) return new Ctor(x.s); + if (x.isZero()) return new Ctor(x); - return divide(x.sinh(), x.cosh(), Ctor.precision = pr, Ctor.rounding = rm); - }; + pr = Ctor.precision; + rm = Ctor.rounding; + Ctor.precision = pr + 7; + Ctor.rounding = 1; + return divide(x.sinh(), x.cosh(), Ctor.precision = pr, Ctor.rounding = rm); +}; - /* - * Return a new Decimal whose value is the arccosine (inverse cosine) in radians of the value of - * this Decimal. - * - * Domain: [-1, 1] - * Range: [0, pi] - * - * acos(x) = pi/2 - asin(x) - * - * acos(0) = pi/2 - * acos(-0) = pi/2 - * acos(1) = 0 - * acos(-1) = pi - * acos(1/2) = pi/3 - * acos(-1/2) = 2*pi/3 - * acos(|x| > 1) = NaN - * acos(NaN) = NaN - * - */ - P.inverseCosine = P.acos = function () { - var halfPi, - x = this, - Ctor = x.constructor, - k = x.abs().cmp(1), - pr = Ctor.precision, - rm = Ctor.rounding; - if (k !== -1) { - return k === 0 - // |x| is 1 - ? x.isNeg() ? getPi(Ctor, pr, rm) : new Ctor(0) - // |x| > 1 or x is NaN - : new Ctor(NaN); - } +/* + * Return a new Decimal whose value is the arccosine (inverse cosine) in radians of the value of + * this Decimal. + * + * Domain: [-1, 1] + * Range: [0, pi] + * + * acos(x) = pi/2 - asin(x) + * + * acos(0) = pi/2 + * acos(-0) = pi/2 + * acos(1) = 0 + * acos(-1) = pi + * acos(1/2) = pi/3 + * acos(-1/2) = 2*pi/3 + * acos(|x| > 1) = NaN + * acos(NaN) = NaN + * + */ +P.inverseCosine = P.acos = function () { + var halfPi, + x = this, + Ctor = x.constructor, + k = x.abs().cmp(1), + pr = Ctor.precision, + rm = Ctor.rounding; - if (x.isZero()) return getPi(Ctor, pr + 4, rm).times(0.5); + if (k !== -1) { + return k === 0 + // |x| is 1 + ? x.isNeg() ? getPi(Ctor, pr, rm) : new Ctor(0) + // |x| > 1 or x is NaN + : new Ctor(NaN); + } - // TODO? Special case acos(0.5) = pi/3 and acos(-0.5) = 2*pi/3 + if (x.isZero()) return getPi(Ctor, pr + 4, rm).times(0.5); - Ctor.precision = pr + 6; - Ctor.rounding = 1; + // TODO? Special case acos(0.5) = pi/3 and acos(-0.5) = 2*pi/3 - x = x.asin(); - halfPi = getPi(Ctor, pr + 4, rm).times(0.5); + Ctor.precision = pr + 6; + Ctor.rounding = 1; - Ctor.precision = pr; - Ctor.rounding = rm; + x = x.asin(); + halfPi = getPi(Ctor, pr + 4, rm).times(0.5); - return halfPi.minus(x); - }; + Ctor.precision = pr; + Ctor.rounding = rm; + return halfPi.minus(x); +}; - /* - * Return a new Decimal whose value is the inverse of the hyperbolic cosine in radians of the - * value of this Decimal. - * - * Domain: [1, Infinity] - * Range: [0, Infinity] - * - * acosh(x) = ln(x + sqrt(x^2 - 1)) - * - * acosh(x < 1) = NaN - * acosh(NaN) = NaN - * acosh(Infinity) = Infinity - * acosh(-Infinity) = NaN - * acosh(0) = NaN - * acosh(-0) = NaN - * acosh(1) = 0 - * acosh(-1) = NaN - * - */ - P.inverseHyperbolicCosine = P.acosh = function () { - var pr, rm, - x = this, - Ctor = x.constructor; - if (x.lte(1)) return new Ctor(x.eq(1) ? 0 : NaN); - if (!x.isFinite()) return new Ctor(x); +/* + * Return a new Decimal whose value is the inverse of the hyperbolic cosine in radians of the + * value of this Decimal. + * + * Domain: [1, Infinity] + * Range: [0, Infinity] + * + * acosh(x) = ln(x + sqrt(x^2 - 1)) + * + * acosh(x < 1) = NaN + * acosh(NaN) = NaN + * acosh(Infinity) = Infinity + * acosh(-Infinity) = NaN + * acosh(0) = NaN + * acosh(-0) = NaN + * acosh(1) = 0 + * acosh(-1) = NaN + * + */ +P.inverseHyperbolicCosine = P.acosh = function () { + var pr, rm, + x = this, + Ctor = x.constructor; - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + Math.max(Math.abs(x.e), x.sd()) + 4; - Ctor.rounding = 1; - external = false; + if (x.lte(1)) return new Ctor(x.eq(1) ? 0 : NaN); + if (!x.isFinite()) return new Ctor(x); - x = x.times(x).minus(1).sqrt().plus(x); + pr = Ctor.precision; + rm = Ctor.rounding; + Ctor.precision = pr + Math.max(Math.abs(x.e), x.sd()) + 4; + Ctor.rounding = 1; + external = false; - external = true; - Ctor.precision = pr; - Ctor.rounding = rm; + x = x.times(x).minus(1).sqrt().plus(x); - return x.ln(); - }; + external = true; + Ctor.precision = pr; + Ctor.rounding = rm; + return x.ln(); +}; - /* - * Return a new Decimal whose value is the inverse of the hyperbolic sine in radians of the value - * of this Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-Infinity, Infinity] - * - * asinh(x) = ln(x + sqrt(x^2 + 1)) - * - * asinh(NaN) = NaN - * asinh(Infinity) = Infinity - * asinh(-Infinity) = -Infinity - * asinh(0) = 0 - * asinh(-0) = -0 - * - */ - P.inverseHyperbolicSine = P.asinh = function () { - var pr, rm, - x = this, - Ctor = x.constructor; - if (!x.isFinite() || x.isZero()) return new Ctor(x); +/* + * Return a new Decimal whose value is the inverse of the hyperbolic sine in radians of the value + * of this Decimal. + * + * Domain: [-Infinity, Infinity] + * Range: [-Infinity, Infinity] + * + * asinh(x) = ln(x + sqrt(x^2 + 1)) + * + * asinh(NaN) = NaN + * asinh(Infinity) = Infinity + * asinh(-Infinity) = -Infinity + * asinh(0) = 0 + * asinh(-0) = -0 + * + */ +P.inverseHyperbolicSine = P.asinh = function () { + var pr, rm, + x = this, + Ctor = x.constructor; - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + 2 * Math.max(Math.abs(x.e), x.sd()) + 6; - Ctor.rounding = 1; - external = false; + if (!x.isFinite() || x.isZero()) return new Ctor(x); - x = x.times(x).plus(1).sqrt().plus(x); + pr = Ctor.precision; + rm = Ctor.rounding; + Ctor.precision = pr + 2 * Math.max(Math.abs(x.e), x.sd()) + 6; + Ctor.rounding = 1; + external = false; - external = true; - Ctor.precision = pr; - Ctor.rounding = rm; + x = x.times(x).plus(1).sqrt().plus(x); - return x.ln(); - }; + external = true; + Ctor.precision = pr; + Ctor.rounding = rm; + return x.ln(); +}; - /* - * Return a new Decimal whose value is the inverse of the hyperbolic tangent in radians of the - * value of this Decimal. - * - * Domain: [-1, 1] - * Range: [-Infinity, Infinity] - * - * atanh(x) = 0.5 * ln((1 + x) / (1 - x)) - * - * atanh(|x| > 1) = NaN - * atanh(NaN) = NaN - * atanh(Infinity) = NaN - * atanh(-Infinity) = NaN - * atanh(0) = 0 - * atanh(-0) = -0 - * atanh(1) = Infinity - * atanh(-1) = -Infinity - * - */ - P.inverseHyperbolicTangent = P.atanh = function () { - var pr, rm, wpr, xsd, - x = this, - Ctor = x.constructor; - if (!x.isFinite()) return new Ctor(NaN); - if (x.e >= 0) return new Ctor(x.abs().eq(1) ? x.s / 0 : x.isZero() ? x : NaN); +/* + * Return a new Decimal whose value is the inverse of the hyperbolic tangent in radians of the + * value of this Decimal. + * + * Domain: [-1, 1] + * Range: [-Infinity, Infinity] + * + * atanh(x) = 0.5 * ln((1 + x) / (1 - x)) + * + * atanh(|x| > 1) = NaN + * atanh(NaN) = NaN + * atanh(Infinity) = NaN + * atanh(-Infinity) = NaN + * atanh(0) = 0 + * atanh(-0) = -0 + * atanh(1) = Infinity + * atanh(-1) = -Infinity + * + */ +P.inverseHyperbolicTangent = P.atanh = function () { + var pr, rm, wpr, xsd, + x = this, + Ctor = x.constructor; - pr = Ctor.precision; - rm = Ctor.rounding; - xsd = x.sd(); + if (!x.isFinite()) return new Ctor(NaN); + if (x.e >= 0) return new Ctor(x.abs().eq(1) ? x.s / 0 : x.isZero() ? x : NaN); - if (Math.max(xsd, pr) < 2 * -x.e - 1) return finalise(new Ctor(x), pr, rm, true); + pr = Ctor.precision; + rm = Ctor.rounding; + xsd = x.sd(); - Ctor.precision = wpr = xsd - x.e; + if (Math.max(xsd, pr) < 2 * -x.e - 1) return finalise(new Ctor(x), pr, rm, true); - x = divide(x.plus(1), new Ctor(1).minus(x), wpr + pr, 1); + Ctor.precision = wpr = xsd - x.e; - Ctor.precision = pr + 4; - Ctor.rounding = 1; + x = divide(x.plus(1), new Ctor(1).minus(x), wpr + pr, 1); - x = x.ln(); + Ctor.precision = pr + 4; + Ctor.rounding = 1; - Ctor.precision = pr; - Ctor.rounding = rm; + x = x.ln(); - return x.times(0.5); - }; + Ctor.precision = pr; + Ctor.rounding = rm; + return x.times(0.5); +}; - /* - * Return a new Decimal whose value is the arcsine (inverse sine) in radians of the value of this - * Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-pi/2, pi/2] - * - * asin(x) = 2*atan(x/(1 + sqrt(1 - x^2))) - * - * asin(0) = 0 - * asin(-0) = -0 - * asin(1/2) = pi/6 - * asin(-1/2) = -pi/6 - * asin(1) = pi/2 - * asin(-1) = -pi/2 - * asin(|x| > 1) = NaN - * asin(NaN) = NaN - * - * TODO? Compare performance of Taylor series. - * - */ - P.inverseSine = P.asin = function () { - var halfPi, k, - pr, rm, - x = this, - Ctor = x.constructor; - if (x.isZero()) return new Ctor(x); +/* + * Return a new Decimal whose value is the arcsine (inverse sine) in radians of the value of this + * Decimal. + * + * Domain: [-Infinity, Infinity] + * Range: [-pi/2, pi/2] + * + * asin(x) = 2*atan(x/(1 + sqrt(1 - x^2))) + * + * asin(0) = 0 + * asin(-0) = -0 + * asin(1/2) = pi/6 + * asin(-1/2) = -pi/6 + * asin(1) = pi/2 + * asin(-1) = -pi/2 + * asin(|x| > 1) = NaN + * asin(NaN) = NaN + * + * TODO? Compare performance of Taylor series. + * + */ +P.inverseSine = P.asin = function () { + var halfPi, k, + pr, rm, + x = this, + Ctor = x.constructor; - k = x.abs().cmp(1); - pr = Ctor.precision; - rm = Ctor.rounding; + if (x.isZero()) return new Ctor(x); - if (k !== -1) { + k = x.abs().cmp(1); + pr = Ctor.precision; + rm = Ctor.rounding; - // |x| is 1 - if (k === 0) { - halfPi = getPi(Ctor, pr + 4, rm).times(0.5); - halfPi.s = x.s; - return halfPi; - } + if (k !== -1) { - // |x| > 1 or x is NaN - return new Ctor(NaN); + // |x| is 1 + if (k === 0) { + halfPi = getPi(Ctor, pr + 4, rm).times(0.5); + halfPi.s = x.s; + return halfPi; } - // TODO? Special case asin(1/2) = pi/6 and asin(-1/2) = -pi/6 + // |x| > 1 or x is NaN + return new Ctor(NaN); + } - Ctor.precision = pr + 6; - Ctor.rounding = 1; + // TODO? Special case asin(1/2) = pi/6 and asin(-1/2) = -pi/6 - x = x.div(new Ctor(1).minus(x.times(x)).sqrt().plus(1)).atan(); + Ctor.precision = pr + 6; + Ctor.rounding = 1; - Ctor.precision = pr; - Ctor.rounding = rm; + x = x.div(new Ctor(1).minus(x.times(x)).sqrt().plus(1)).atan(); - return x.times(2); - }; + Ctor.precision = pr; + Ctor.rounding = rm; + return x.times(2); +}; - /* - * Return a new Decimal whose value is the arctangent (inverse tangent) in radians of the value - * of this Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-pi/2, pi/2] - * - * atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... - * - * atan(0) = 0 - * atan(-0) = -0 - * atan(1) = pi/4 - * atan(-1) = -pi/4 - * atan(Infinity) = pi/2 - * atan(-Infinity) = -pi/2 - * atan(NaN) = NaN - * - */ - P.inverseTangent = P.atan = function () { - var i, j, k, n, px, t, r, wpr, x2, - x = this, - Ctor = x.constructor, - pr = Ctor.precision, - rm = Ctor.rounding; - if (!x.isFinite()) { - if (!x.s) return new Ctor(NaN); - if (pr + 4 <= PI_PRECISION) { - r = getPi(Ctor, pr + 4, rm).times(0.5); - r.s = x.s; - return r; - } - } else if (x.isZero()) { - return new Ctor(x); - } else if (x.abs().eq(1) && pr + 4 <= PI_PRECISION) { - r = getPi(Ctor, pr + 4, rm).times(0.25); +/* + * Return a new Decimal whose value is the arctangent (inverse tangent) in radians of the value + * of this Decimal. + * + * Domain: [-Infinity, Infinity] + * Range: [-pi/2, pi/2] + * + * atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... + * + * atan(0) = 0 + * atan(-0) = -0 + * atan(1) = pi/4 + * atan(-1) = -pi/4 + * atan(Infinity) = pi/2 + * atan(-Infinity) = -pi/2 + * atan(NaN) = NaN + * + */ +P.inverseTangent = P.atan = function () { + var i, j, k, n, px, t, r, wpr, x2, + x = this, + Ctor = x.constructor, + pr = Ctor.precision, + rm = Ctor.rounding; + + if (!x.isFinite()) { + if (!x.s) return new Ctor(NaN); + if (pr + 4 <= PI_PRECISION) { + r = getPi(Ctor, pr + 4, rm).times(0.5); r.s = x.s; return r; } + } else if (x.isZero()) { + return new Ctor(x); + } else if (x.abs().eq(1) && pr + 4 <= PI_PRECISION) { + r = getPi(Ctor, pr + 4, rm).times(0.25); + r.s = x.s; + return r; + } - Ctor.precision = wpr = pr + 10; - Ctor.rounding = 1; + Ctor.precision = wpr = pr + 10; + Ctor.rounding = 1; - // TODO? if (x >= 1 && pr <= PI_PRECISION) atan(x) = halfPi * x.s - atan(1 / x); + // TODO? if (x >= 1 && pr <= PI_PRECISION) atan(x) = halfPi * x.s - atan(1 / x); - // Argument reduction - // Ensure |x| < 0.42 - // atan(x) = 2 * atan(x / (1 + sqrt(1 + x^2))) + // Argument reduction + // Ensure |x| < 0.42 + // atan(x) = 2 * atan(x / (1 + sqrt(1 + x^2))) - k = Math.min(28, wpr / LOG_BASE + 2 | 0); + k = Math.min(28, wpr / LOG_BASE + 2 | 0); - for (i = k; i; --i) x = x.div(x.times(x).plus(1).sqrt().plus(1)); + for (i = k; i; --i) x = x.div(x.times(x).plus(1).sqrt().plus(1)); - external = false; + external = false; - j = Math.ceil(wpr / LOG_BASE); - n = 1; - x2 = x.times(x); - r = new Ctor(x); - px = x; + j = Math.ceil(wpr / LOG_BASE); + n = 1; + x2 = x.times(x); + r = new Ctor(x); + px = x; - // atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... - for (; i !== -1;) { - px = px.times(x2); - t = r.minus(px.div(n += 2)); + // atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... + for (; i !== -1;) { + px = px.times(x2); + t = r.minus(px.div(n += 2)); - px = px.times(x2); - r = t.plus(px.div(n += 2)); + px = px.times(x2); + r = t.plus(px.div(n += 2)); - if (r.d[j] !== void 0) for (i = j; r.d[i] === t.d[i] && i--;); - } + if (r.d[j] !== void 0) for (i = j; r.d[i] === t.d[i] && i--;); + } - if (k) r = r.times(2 << (k - 1)); + if (k) r = r.times(2 << (k - 1)); - external = true; + external = true; - return finalise(r, Ctor.precision = pr, Ctor.rounding = rm, true); - }; + return finalise(r, Ctor.precision = pr, Ctor.rounding = rm, true); +}; - /* - * Return true if the value of this Decimal is a finite number, otherwise return false. - * - */ - P.isFinite = function () { - return !!this.d; - }; +/* + * Return true if the value of this Decimal is a finite number, otherwise return false. + * + */ +P.isFinite = function () { + return !!this.d; +}; - /* - * Return true if the value of this Decimal is an integer, otherwise return false. - * - */ - P.isInteger = P.isInt = function () { - return !!this.d && mathfloor(this.e / LOG_BASE) > this.d.length - 2; - }; +/* + * Return true if the value of this Decimal is an integer, otherwise return false. + * + */ +P.isInteger = P.isInt = function () { + return !!this.d && mathfloor(this.e / LOG_BASE) > this.d.length - 2; +}; - /* - * Return true if the value of this Decimal is NaN, otherwise return false. - * - */ - P.isNaN = function () { - return !this.s; - }; +/* + * Return true if the value of this Decimal is NaN, otherwise return false. + * + */ +P.isNaN = function () { + return !this.s; +}; - /* - * Return true if the value of this Decimal is negative, otherwise return false. - * - */ - P.isNegative = P.isNeg = function () { - return this.s < 0; - }; +/* + * Return true if the value of this Decimal is negative, otherwise return false. + * + */ +P.isNegative = P.isNeg = function () { + return this.s < 0; +}; - /* - * Return true if the value of this Decimal is positive, otherwise return false. - * - */ - P.isPositive = P.isPos = function () { - return this.s > 0; - }; +/* + * Return true if the value of this Decimal is positive, otherwise return false. + * + */ +P.isPositive = P.isPos = function () { + return this.s > 0; +}; - /* - * Return true if the value of this Decimal is 0 or -0, otherwise return false. - * - */ - P.isZero = function () { - return !!this.d && this.d[0] === 0; - }; +/* + * Return true if the value of this Decimal is 0 or -0, otherwise return false. + * + */ +P.isZero = function () { + return !!this.d && this.d[0] === 0; +}; - /* - * Return true if the value of this Decimal is less than `y`, otherwise return false. - * - */ - P.lessThan = P.lt = function (y) { - return this.cmp(y) < 0; - }; +/* + * Return true if the value of this Decimal is less than `y`, otherwise return false. + * + */ +P.lessThan = P.lt = function (y) { + return this.cmp(y) < 0; +}; - /* - * Return true if the value of this Decimal is less than or equal to `y`, otherwise return false. - * - */ - P.lessThanOrEqualTo = P.lte = function (y) { - return this.cmp(y) < 1; - }; +/* + * Return true if the value of this Decimal is less than or equal to `y`, otherwise return false. + * + */ +P.lessThanOrEqualTo = P.lte = function (y) { + return this.cmp(y) < 1; +}; - /* - * Return the logarithm of the value of this Decimal to the specified base, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * If no base is specified, return log[10](arg). - * - * log[base](arg) = ln(arg) / ln(base) - * - * The result will always be correctly rounded if the base of the log is 10, and 'almost always' - * otherwise: - * - * Depending on the rounding mode, the result may be incorrectly rounded if the first fifteen - * rounding digits are [49]99999999999999 or [50]00000000000000. In that case, the maximum error - * between the result and the correctly rounded result will be one ulp (unit in the last place). - * - * log[-b](a) = NaN - * log[0](a) = NaN - * log[1](a) = NaN - * log[NaN](a) = NaN - * log[Infinity](a) = NaN - * log[b](0) = -Infinity - * log[b](-0) = -Infinity - * log[b](-a) = NaN - * log[b](1) = 0 - * log[b](Infinity) = Infinity - * log[b](NaN) = NaN - * - * [base] {number|string|Decimal} The base of the logarithm. - * - */ - P.logarithm = P.log = function (base) { - var isBase10, d, denominator, k, inf, num, sd, r, - arg = this, - Ctor = arg.constructor, - pr = Ctor.precision, - rm = Ctor.rounding, - guard = 5; - - // Default base is 10. - if (base == null) { - base = new Ctor(10); - isBase10 = true; - } else { - base = new Ctor(base); - d = base.d; +/* + * Return the logarithm of the value of this Decimal to the specified base, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * If no base is specified, return log[10](arg). + * + * log[base](arg) = ln(arg) / ln(base) + * + * The result will always be correctly rounded if the base of the log is 10, and 'almost always' + * otherwise: + * + * Depending on the rounding mode, the result may be incorrectly rounded if the first fifteen + * rounding digits are [49]99999999999999 or [50]00000000000000. In that case, the maximum error + * between the result and the correctly rounded result will be one ulp (unit in the last place). + * + * log[-b](a) = NaN + * log[0](a) = NaN + * log[1](a) = NaN + * log[NaN](a) = NaN + * log[Infinity](a) = NaN + * log[b](0) = -Infinity + * log[b](-0) = -Infinity + * log[b](-a) = NaN + * log[b](1) = 0 + * log[b](Infinity) = Infinity + * log[b](NaN) = NaN + * + * [base] {number|string|Decimal} The base of the logarithm. + * + */ +P.logarithm = P.log = function (base) { + var isBase10, d, denominator, k, inf, num, sd, r, + arg = this, + Ctor = arg.constructor, + pr = Ctor.precision, + rm = Ctor.rounding, + guard = 5; + + // Default base is 10. + if (base == null) { + base = new Ctor(10); + isBase10 = true; + } else { + base = new Ctor(base); + d = base.d; - // Return NaN if base is negative, or non-finite, or is 0 or 1. - if (base.s < 0 || !d || !d[0] || base.eq(1)) return new Ctor(NaN); + // Return NaN if base is negative, or non-finite, or is 0 or 1. + if (base.s < 0 || !d || !d[0] || base.eq(1)) return new Ctor(NaN); - isBase10 = base.eq(10); - } + isBase10 = base.eq(10); + } - d = arg.d; + d = arg.d; - // Is arg negative, non-finite, 0 or 1? - if (arg.s < 0 || !d || !d[0] || arg.eq(1)) { - return new Ctor(d && !d[0] ? -1 / 0 : arg.s != 1 ? NaN : d ? 0 : 1 / 0); - } + // Is arg negative, non-finite, 0 or 1? + if (arg.s < 0 || !d || !d[0] || arg.eq(1)) { + return new Ctor(d && !d[0] ? -1 / 0 : arg.s != 1 ? NaN : d ? 0 : 1 / 0); + } - // The result will have a non-terminating decimal expansion if base is 10 and arg is not an - // integer power of 10. - if (isBase10) { - if (d.length > 1) { - inf = true; - } else { - for (k = d[0]; k % 10 === 0;) k /= 10; - inf = k !== 1; - } + // The result will have a non-terminating decimal expansion if base is 10 and arg is not an + // integer power of 10. + if (isBase10) { + if (d.length > 1) { + inf = true; + } else { + for (k = d[0]; k % 10 === 0;) k /= 10; + inf = k !== 1; } + } - external = false; - sd = pr + guard; - num = naturalLogarithm(arg, sd); - denominator = isBase10 ? getLn10(Ctor, sd + 10) : naturalLogarithm(base, sd); - - // The result will have 5 rounding digits. - r = divide(num, denominator, sd, 1); + external = false; + sd = pr + guard; + num = naturalLogarithm(arg, sd); + denominator = isBase10 ? getLn10(Ctor, sd + 10) : naturalLogarithm(base, sd); - // If at a rounding boundary, i.e. the result's rounding digits are [49]9999 or [50]0000, - // calculate 10 further digits. - // - // If the result is known to have an infinite decimal expansion, repeat this until it is clear - // that the result is above or below the boundary. Otherwise, if after calculating the 10 - // further digits, the last 14 are nines, round up and assume the result is exact. - // Also assume the result is exact if the last 14 are zero. - // - // Example of a result that will be incorrectly rounded: - // log[1048576](4503599627370502) = 2.60000000000000009610279511444746... - // The above result correctly rounded using ROUND_CEIL to 1 decimal place should be 2.7, but it - // will be given as 2.6 as there are 15 zeros immediately after the requested decimal place, so - // the exact result would be assumed to be 2.6, which rounded using ROUND_CEIL to 1 decimal - // place is still 2.6. - if (checkRoundingDigits(r.d, k = pr, rm)) { + // The result will have 5 rounding digits. + r = divide(num, denominator, sd, 1); - do { - sd += 10; - num = naturalLogarithm(arg, sd); - denominator = isBase10 ? getLn10(Ctor, sd + 10) : naturalLogarithm(base, sd); - r = divide(num, denominator, sd, 1); + // If at a rounding boundary, i.e. the result's rounding digits are [49]9999 or [50]0000, + // calculate 10 further digits. + // + // If the result is known to have an infinite decimal expansion, repeat this until it is clear + // that the result is above or below the boundary. Otherwise, if after calculating the 10 + // further digits, the last 14 are nines, round up and assume the result is exact. + // Also assume the result is exact if the last 14 are zero. + // + // Example of a result that will be incorrectly rounded: + // log[1048576](4503599627370502) = 2.60000000000000009610279511444746... + // The above result correctly rounded using ROUND_CEIL to 1 decimal place should be 2.7, but it + // will be given as 2.6 as there are 15 zeros immediately after the requested decimal place, so + // the exact result would be assumed to be 2.6, which rounded using ROUND_CEIL to 1 decimal + // place is still 2.6. + if (checkRoundingDigits(r.d, k = pr, rm)) { - if (!inf) { + do { + sd += 10; + num = naturalLogarithm(arg, sd); + denominator = isBase10 ? getLn10(Ctor, sd + 10) : naturalLogarithm(base, sd); + r = divide(num, denominator, sd, 1); - // Check for 14 nines from the 2nd rounding digit, as the first may be 4. - if (+digitsToString(r.d).slice(k + 1, k + 15) + 1 == 1e14) { - r = finalise(r, pr + 1, 0); - } + if (!inf) { - break; + // Check for 14 nines from the 2nd rounding digit, as the first may be 4. + if (+digitsToString(r.d).slice(k + 1, k + 15) + 1 == 1e14) { + r = finalise(r, pr + 1, 0); } - } while (checkRoundingDigits(r.d, k += 10, rm)); - } - external = true; + break; + } + } while (checkRoundingDigits(r.d, k += 10, rm)); + } - return finalise(r, pr, rm); - }; + external = true; + return finalise(r, pr, rm); +}; - /* - * Return a new Decimal whose value is the maximum of the arguments and the value of this Decimal. - * - * arguments {number|string|Decimal} - * - P.max = function () { - Array.prototype.push.call(arguments, this); - return maxOrMin(this.constructor, arguments, 'lt'); - }; - */ +/* + * Return a new Decimal whose value is the maximum of the arguments and the value of this Decimal. + * + * arguments {number|string|Decimal} + * +P.max = function () { + Array.prototype.push.call(arguments, this); + return maxOrMin(this.constructor, arguments, 'lt'); +}; + */ - /* - * Return a new Decimal whose value is the minimum of the arguments and the value of this Decimal. - * - * arguments {number|string|Decimal} - * - P.min = function () { - Array.prototype.push.call(arguments, this); - return maxOrMin(this.constructor, arguments, 'gt'); - }; - */ +/* + * Return a new Decimal whose value is the minimum of the arguments and the value of this Decimal. + * + * arguments {number|string|Decimal} + * +P.min = function () { + Array.prototype.push.call(arguments, this); + return maxOrMin(this.constructor, arguments, 'gt'); +}; + */ - /* - * n - 0 = n - * n - N = N - * n - I = -I - * 0 - n = -n - * 0 - 0 = 0 - * 0 - N = N - * 0 - I = -I - * N - n = N - * N - 0 = N - * N - N = N - * N - I = N - * I - n = I - * I - 0 = I - * I - N = N - * I - I = N - * - * Return a new Decimal whose value is the value of this Decimal minus `y`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - */ - P.minus = P.sub = function (y) { - var d, e, i, j, k, len, pr, rm, xd, xe, xLTy, yd, - x = this, - Ctor = x.constructor; - y = new Ctor(y); +/* + * n - 0 = n + * n - N = N + * n - I = -I + * 0 - n = -n + * 0 - 0 = 0 + * 0 - N = N + * 0 - I = -I + * N - n = N + * N - 0 = N + * N - N = N + * N - I = N + * I - n = I + * I - 0 = I + * I - N = N + * I - I = N + * + * Return a new Decimal whose value is the value of this Decimal minus `y`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + */ +P.minus = P.sub = function (y) { + var d, e, i, j, k, len, pr, rm, xd, xe, xLTy, yd, + x = this, + Ctor = x.constructor; - // If either is not finite... - if (!x.d || !y.d) { + y = new Ctor(y); - // Return NaN if either is NaN. - if (!x.s || !y.s) y = new Ctor(NaN); + // If either is not finite... + if (!x.d || !y.d) { - // Return y negated if x is finite and y is ±Infinity. - else if (x.d) y.s = -y.s; + // Return NaN if either is NaN. + if (!x.s || !y.s) y = new Ctor(NaN); - // Return x if y is finite and x is ±Infinity. - // Return x if both are ±Infinity with different signs. - // Return NaN if both are ±Infinity with the same sign. - else y = new Ctor(y.d || x.s !== y.s ? x : NaN); + // Return y negated if x is finite and y is ±Infinity. + else if (x.d) y.s = -y.s; - return y; - } + // Return x if y is finite and x is ±Infinity. + // Return x if both are ±Infinity with different signs. + // Return NaN if both are ±Infinity with the same sign. + else y = new Ctor(y.d || x.s !== y.s ? x : NaN); - // If signs differ... - if (x.s != y.s) { - y.s = -y.s; - return x.plus(y); - } + return y; + } - xd = x.d; - yd = y.d; - pr = Ctor.precision; - rm = Ctor.rounding; + // If signs differ... + if (x.s != y.s) { + y.s = -y.s; + return x.plus(y); + } - // If either is zero... - if (!xd[0] || !yd[0]) { + xd = x.d; + yd = y.d; + pr = Ctor.precision; + rm = Ctor.rounding; - // Return y negated if x is zero and y is non-zero. - if (yd[0]) y.s = -y.s; + // If either is zero... + if (!xd[0] || !yd[0]) { - // Return x if y is zero and x is non-zero. - else if (xd[0]) y = new Ctor(x); + // Return y negated if x is zero and y is non-zero. + if (yd[0]) y.s = -y.s; - // Return zero if both are zero. - // From IEEE 754 (2008) 6.3: 0 - 0 = -0 - -0 = -0 when rounding to -Infinity. - else return new Ctor(rm === 3 ? -0 : 0); + // Return x if y is zero and x is non-zero. + else if (xd[0]) y = new Ctor(x); - return external ? finalise(y, pr, rm) : y; - } + // Return zero if both are zero. + // From IEEE 754 (2008) 6.3: 0 - 0 = -0 - -0 = -0 when rounding to -Infinity. + else return new Ctor(rm === 3 ? -0 : 0); - // x and y are finite, non-zero numbers with the same sign. + return external ? finalise(y, pr, rm) : y; + } - // Calculate base 1e7 exponents. - e = mathfloor(y.e / LOG_BASE); - xe = mathfloor(x.e / LOG_BASE); + // x and y are finite, non-zero numbers with the same sign. - xd = xd.slice(); - k = xe - e; + // Calculate base 1e7 exponents. + e = mathfloor(y.e / LOG_BASE); + xe = mathfloor(x.e / LOG_BASE); - // If base 1e7 exponents differ... - if (k) { - xLTy = k < 0; + xd = xd.slice(); + k = xe - e; - if (xLTy) { - d = xd; - k = -k; - len = yd.length; - } else { - d = yd; - e = xe; - len = xd.length; - } + // If base 1e7 exponents differ... + if (k) { + xLTy = k < 0; - // Numbers with massively different exponents would result in a very high number of - // zeros needing to be prepended, but this can be avoided while still ensuring correct - // rounding by limiting the number of zeros to `Math.ceil(pr / LOG_BASE) + 2`. - i = Math.max(Math.ceil(pr / LOG_BASE), len) + 2; + if (xLTy) { + d = xd; + k = -k; + len = yd.length; + } else { + d = yd; + e = xe; + len = xd.length; + } - if (k > i) { - k = i; - d.length = 1; - } + // Numbers with massively different exponents would result in a very high number of + // zeros needing to be prepended, but this can be avoided while still ensuring correct + // rounding by limiting the number of zeros to `Math.ceil(pr / LOG_BASE) + 2`. + i = Math.max(Math.ceil(pr / LOG_BASE), len) + 2; - // Prepend zeros to equalise exponents. - d.reverse(); - for (i = k; i--;) d.push(0); - d.reverse(); + if (k > i) { + k = i; + d.length = 1; + } - // Base 1e7 exponents equal. - } else { + // Prepend zeros to equalise exponents. + d.reverse(); + for (i = k; i--;) d.push(0); + d.reverse(); - // Check digits to determine which is the bigger number. + // Base 1e7 exponents equal. + } else { - i = xd.length; - len = yd.length; - xLTy = i < len; - if (xLTy) len = i; + // Check digits to determine which is the bigger number. - for (i = 0; i < len; i++) { - if (xd[i] != yd[i]) { - xLTy = xd[i] < yd[i]; - break; - } - } + i = xd.length; + len = yd.length; + xLTy = i < len; + if (xLTy) len = i; - k = 0; + for (i = 0; i < len; i++) { + if (xd[i] != yd[i]) { + xLTy = xd[i] < yd[i]; + break; + } } - if (xLTy) { - d = xd; - xd = yd; - yd = d; - y.s = -y.s; - } + k = 0; + } - len = xd.length; + if (xLTy) { + d = xd; + xd = yd; + yd = d; + y.s = -y.s; + } - // Append zeros to `xd` if shorter. - // Don't add zeros to `yd` if shorter as subtraction only needs to start at `yd` length. - for (i = yd.length - len; i > 0; --i) xd[len++] = 0; + len = xd.length; - // Subtract yd from xd. - for (i = yd.length; i > k;) { + // Append zeros to `xd` if shorter. + // Don't add zeros to `yd` if shorter as subtraction only needs to start at `yd` length. + for (i = yd.length - len; i > 0; --i) xd[len++] = 0; - if (xd[--i] < yd[i]) { - for (j = i; j && xd[--j] === 0;) xd[j] = BASE - 1; - --xd[j]; - xd[i] += BASE; - } + // Subtract yd from xd. + for (i = yd.length; i > k;) { - xd[i] -= yd[i]; + if (xd[--i] < yd[i]) { + for (j = i; j && xd[--j] === 0;) xd[j] = BASE - 1; + --xd[j]; + xd[i] += BASE; } - // Remove trailing zeros. - for (; xd[--len] === 0;) xd.pop(); - - // Remove leading zeros and adjust exponent accordingly. - for (; xd[0] === 0; xd.shift()) --e; + xd[i] -= yd[i]; + } - // Zero? - if (!xd[0]) return new Ctor(rm === 3 ? -0 : 0); + // Remove trailing zeros. + for (; xd[--len] === 0;) xd.pop(); - y.d = xd; - y.e = getBase10Exponent(xd, e); + // Remove leading zeros and adjust exponent accordingly. + for (; xd[0] === 0; xd.shift()) --e; - return external ? finalise(y, pr, rm) : y; - }; + // Zero? + if (!xd[0]) return new Ctor(rm === 3 ? -0 : 0); + y.d = xd; + y.e = getBase10Exponent(xd, e); - /* - * n % 0 = N - * n % N = N - * n % I = n - * 0 % n = 0 - * -0 % n = -0 - * 0 % 0 = N - * 0 % N = N - * 0 % I = 0 - * N % n = N - * N % 0 = N - * N % N = N - * N % I = N - * I % n = N - * I % 0 = N - * I % N = N - * I % I = N - * - * Return a new Decimal whose value is the value of this Decimal modulo `y`, rounded to - * `precision` significant digits using rounding mode `rounding`. - * - * The result depends on the modulo mode. - * - */ - P.modulo = P.mod = function (y) { - var q, - x = this, - Ctor = x.constructor; + return external ? finalise(y, pr, rm) : y; +}; - y = new Ctor(y); - // Return NaN if x is ±Infinity or NaN, or y is NaN or ±0. - if (!x.d || !y.s || y.d && !y.d[0]) return new Ctor(NaN); +/* + * n % 0 = N + * n % N = N + * n % I = n + * 0 % n = 0 + * -0 % n = -0 + * 0 % 0 = N + * 0 % N = N + * 0 % I = 0 + * N % n = N + * N % 0 = N + * N % N = N + * N % I = N + * I % n = N + * I % 0 = N + * I % N = N + * I % I = N + * + * Return a new Decimal whose value is the value of this Decimal modulo `y`, rounded to + * `precision` significant digits using rounding mode `rounding`. + * + * The result depends on the modulo mode. + * + */ +P.modulo = P.mod = function (y) { + var q, + x = this, + Ctor = x.constructor; - // Return x if y is ±Infinity or x is ±0. - if (!y.d || x.d && !x.d[0]) { - return finalise(new Ctor(x), Ctor.precision, Ctor.rounding); - } + y = new Ctor(y); - // Prevent rounding of intermediate calculations. - external = false; + // Return NaN if x is ±Infinity or NaN, or y is NaN or ±0. + if (!x.d || !y.s || y.d && !y.d[0]) return new Ctor(NaN); - if (Ctor.modulo == 9) { + // Return x if y is ±Infinity or x is ±0. + if (!y.d || x.d && !x.d[0]) { + return finalise(new Ctor(x), Ctor.precision, Ctor.rounding); + } - // Euclidian division: q = sign(y) * floor(x / abs(y)) - // result = x - q * y where 0 <= result < abs(y) - q = divide(x, y.abs(), 0, 3, 1); - q.s *= y.s; - } else { - q = divide(x, y, 0, Ctor.modulo, 1); - } + // Prevent rounding of intermediate calculations. + external = false; - q = q.times(y); + if (Ctor.modulo == 9) { - external = true; + // Euclidian division: q = sign(y) * floor(x / abs(y)) + // result = x - q * y where 0 <= result < abs(y) + q = divide(x, y.abs(), 0, 3, 1); + q.s *= y.s; + } else { + q = divide(x, y, 0, Ctor.modulo, 1); + } - return x.minus(q); - }; + q = q.times(y); + external = true; - /* - * Return a new Decimal whose value is the natural exponential of the value of this Decimal, - * i.e. the base e raised to the power the value of this Decimal, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - */ - P.naturalExponential = P.exp = function () { - return naturalExponential(this); - }; - + return x.minus(q); +}; - /* - * Return a new Decimal whose value is the natural logarithm of the value of this Decimal, - * rounded to `precision` significant digits using rounding mode `rounding`. - * - */ - P.naturalLogarithm = P.ln = function () { - return naturalLogarithm(this); - }; +/* + * Return a new Decimal whose value is the natural exponential of the value of this Decimal, + * i.e. the base e raised to the power the value of this Decimal, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + */ +P.naturalExponential = P.exp = function () { + return naturalExponential(this); +}; - /* - * Return a new Decimal whose value is the value of this Decimal negated, i.e. as if multiplied by - * -1. - * - */ - P.negated = P.neg = function () { - var x = new this.constructor(this); - x.s = -x.s; - return finalise(x); - }; +/* + * Return a new Decimal whose value is the natural logarithm of the value of this Decimal, + * rounded to `precision` significant digits using rounding mode `rounding`. + * + */ +P.naturalLogarithm = P.ln = function () { + return naturalLogarithm(this); +}; - /* - * n + 0 = n - * n + N = N - * n + I = I - * 0 + n = n - * 0 + 0 = 0 - * 0 + N = N - * 0 + I = I - * N + n = N - * N + 0 = N - * N + N = N - * N + I = N - * I + n = I - * I + 0 = I - * I + N = N - * I + I = I - * - * Return a new Decimal whose value is the value of this Decimal plus `y`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - */ - P.plus = P.add = function (y) { - var carry, d, e, i, k, len, pr, rm, xd, yd, - x = this, - Ctor = x.constructor; - y = new Ctor(y); +/* + * Return a new Decimal whose value is the value of this Decimal negated, i.e. as if multiplied by + * -1. + * + */ +P.negated = P.neg = function () { + var x = new this.constructor(this); + x.s = -x.s; + return finalise(x); +}; - // If either is not finite... - if (!x.d || !y.d) { - // Return NaN if either is NaN. - if (!x.s || !y.s) y = new Ctor(NaN); +/* + * n + 0 = n + * n + N = N + * n + I = I + * 0 + n = n + * 0 + 0 = 0 + * 0 + N = N + * 0 + I = I + * N + n = N + * N + 0 = N + * N + N = N + * N + I = N + * I + n = I + * I + 0 = I + * I + N = N + * I + I = I + * + * Return a new Decimal whose value is the value of this Decimal plus `y`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + */ +P.plus = P.add = function (y) { + var carry, d, e, i, k, len, pr, rm, xd, yd, + x = this, + Ctor = x.constructor; - // Return x if y is finite and x is ±Infinity. - // Return x if both are ±Infinity with the same sign. - // Return NaN if both are ±Infinity with different signs. - // Return y if x is finite and y is ±Infinity. - else if (!x.d) y = new Ctor(y.d || x.s === y.s ? x : NaN); + y = new Ctor(y); - return y; - } + // If either is not finite... + if (!x.d || !y.d) { - // If signs differ... - if (x.s != y.s) { - y.s = -y.s; - return x.minus(y); - } + // Return NaN if either is NaN. + if (!x.s || !y.s) y = new Ctor(NaN); - xd = x.d; - yd = y.d; - pr = Ctor.precision; - rm = Ctor.rounding; + // Return x if y is finite and x is ±Infinity. + // Return x if both are ±Infinity with the same sign. + // Return NaN if both are ±Infinity with different signs. + // Return y if x is finite and y is ±Infinity. + else if (!x.d) y = new Ctor(y.d || x.s === y.s ? x : NaN); - // If either is zero... - if (!xd[0] || !yd[0]) { + return y; + } - // Return x if y is zero. - // Return y if y is non-zero. - if (!yd[0]) y = new Ctor(x); + // If signs differ... + if (x.s != y.s) { + y.s = -y.s; + return x.minus(y); + } - return external ? finalise(y, pr, rm) : y; - } + xd = x.d; + yd = y.d; + pr = Ctor.precision; + rm = Ctor.rounding; - // x and y are finite, non-zero numbers with the same sign. + // If either is zero... + if (!xd[0] || !yd[0]) { - // Calculate base 1e7 exponents. - k = mathfloor(x.e / LOG_BASE); - e = mathfloor(y.e / LOG_BASE); + // Return x if y is zero. + // Return y if y is non-zero. + if (!yd[0]) y = new Ctor(x); - xd = xd.slice(); - i = k - e; + return external ? finalise(y, pr, rm) : y; + } - // If base 1e7 exponents differ... - if (i) { + // x and y are finite, non-zero numbers with the same sign. - if (i < 0) { - d = xd; - i = -i; - len = yd.length; - } else { - d = yd; - e = k; - len = xd.length; - } + // Calculate base 1e7 exponents. + k = mathfloor(x.e / LOG_BASE); + e = mathfloor(y.e / LOG_BASE); - // Limit number of zeros prepended to max(ceil(pr / LOG_BASE), len) + 1. - k = Math.ceil(pr / LOG_BASE); - len = k > len ? k + 1 : len + 1; + xd = xd.slice(); + i = k - e; - if (i > len) { - i = len; - d.length = 1; - } + // If base 1e7 exponents differ... + if (i) { - // Prepend zeros to equalise exponents. Note: Faster to use reverse then do unshifts. - d.reverse(); - for (; i--;) d.push(0); - d.reverse(); + if (i < 0) { + d = xd; + i = -i; + len = yd.length; + } else { + d = yd; + e = k; + len = xd.length; } - len = xd.length; - i = yd.length; + // Limit number of zeros prepended to max(ceil(pr / LOG_BASE), len) + 1. + k = Math.ceil(pr / LOG_BASE); + len = k > len ? k + 1 : len + 1; - // If yd is longer than xd, swap xd and yd so xd points to the longer array. - if (len - i < 0) { + if (i > len) { i = len; - d = yd; - yd = xd; - xd = d; + d.length = 1; } - // Only start adding at yd.length - 1 as the further digits of xd can be left as they are. - for (carry = 0; i;) { - carry = (xd[--i] = xd[i] + yd[i] + carry) / BASE | 0; - xd[i] %= BASE; - } + // Prepend zeros to equalise exponents. Note: Faster to use reverse then do unshifts. + d.reverse(); + for (; i--;) d.push(0); + d.reverse(); + } - if (carry) { - xd.unshift(carry); - ++e; - } + len = xd.length; + i = yd.length; - // Remove trailing zeros. - // No need to check for zero, as +x + +y != 0 && -x + -y != 0 - for (len = xd.length; xd[--len] == 0;) xd.pop(); + // If yd is longer than xd, swap xd and yd so xd points to the longer array. + if (len - i < 0) { + i = len; + d = yd; + yd = xd; + xd = d; + } - y.d = xd; - y.e = getBase10Exponent(xd, e); + // Only start adding at yd.length - 1 as the further digits of xd can be left as they are. + for (carry = 0; i;) { + carry = (xd[--i] = xd[i] + yd[i] + carry) / BASE | 0; + xd[i] %= BASE; + } - return external ? finalise(y, pr, rm) : y; - }; + if (carry) { + xd.unshift(carry); + ++e; + } + // Remove trailing zeros. + // No need to check for zero, as +x + +y != 0 && -x + -y != 0 + for (len = xd.length; xd[--len] == 0;) xd.pop(); - /* - * Return the number of significant digits of the value of this Decimal. - * - * [z] {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0. - * - */ - P.precision = P.sd = function (z) { - var k, - x = this; + y.d = xd; + y.e = getBase10Exponent(xd, e); - if (z !== void 0 && z !== !!z && z !== 1 && z !== 0) throw Error(invalidArgument + z); + return external ? finalise(y, pr, rm) : y; +}; - if (x.d) { - k = getPrecision(x.d); - if (z && x.e + 1 > k) k = x.e + 1; - } else { - k = NaN; - } - return k; - }; +/* + * Return the number of significant digits of the value of this Decimal. + * + * [z] {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0. + * + */ +P.precision = P.sd = function (z) { + var k, + x = this; + if (z !== void 0 && z !== !!z && z !== 1 && z !== 0) throw Error(invalidArgument + z); - /* - * Return a new Decimal whose value is the value of this Decimal rounded to a whole number using - * rounding mode `rounding`. - * - */ - P.round = function () { - var x = this, - Ctor = x.constructor; + if (x.d) { + k = getPrecision(x.d); + if (z && x.e + 1 > k) k = x.e + 1; + } else { + k = NaN; + } - return finalise(new Ctor(x), x.e + 1, Ctor.rounding); - }; + return k; +}; - /* - * Return a new Decimal whose value is the sine of the value in radians of this Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-1, 1] - * - * sin(x) = x - x^3/3! + x^5/5! - ... - * - * sin(0) = 0 - * sin(-0) = -0 - * sin(Infinity) = NaN - * sin(-Infinity) = NaN - * sin(NaN) = NaN - * - */ - P.sine = P.sin = function () { - var pr, rm, - x = this, - Ctor = x.constructor; +/* + * Return a new Decimal whose value is the value of this Decimal rounded to a whole number using + * rounding mode `rounding`. + * + */ +P.round = function () { + var x = this, + Ctor = x.constructor; + + return finalise(new Ctor(x), x.e + 1, Ctor.rounding); +}; - if (!x.isFinite()) return new Ctor(NaN); - if (x.isZero()) return new Ctor(x); - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + Math.max(x.e, x.sd()) + LOG_BASE; - Ctor.rounding = 1; +/* + * Return a new Decimal whose value is the sine of the value in radians of this Decimal. + * + * Domain: [-Infinity, Infinity] + * Range: [-1, 1] + * + * sin(x) = x - x^3/3! + x^5/5! - ... + * + * sin(0) = 0 + * sin(-0) = -0 + * sin(Infinity) = NaN + * sin(-Infinity) = NaN + * sin(NaN) = NaN + * + */ +P.sine = P.sin = function () { + var pr, rm, + x = this, + Ctor = x.constructor; - x = sine(Ctor, toLessThanHalfPi(Ctor, x)); + if (!x.isFinite()) return new Ctor(NaN); + if (x.isZero()) return new Ctor(x); - Ctor.precision = pr; - Ctor.rounding = rm; + pr = Ctor.precision; + rm = Ctor.rounding; + Ctor.precision = pr + Math.max(x.e, x.sd()) + LOG_BASE; + Ctor.rounding = 1; - return finalise(quadrant > 2 ? x.neg() : x, pr, rm, true); - }; + x = sine(Ctor, toLessThanHalfPi(Ctor, x)); + Ctor.precision = pr; + Ctor.rounding = rm; - /* - * Return a new Decimal whose value is the square root of this Decimal, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * sqrt(-n) = N - * sqrt(N) = N - * sqrt(-I) = N - * sqrt(I) = I - * sqrt(0) = 0 - * sqrt(-0) = -0 - * - */ - P.squareRoot = P.sqrt = function () { - var m, n, sd, r, rep, t, - x = this, - d = x.d, - e = x.e, - s = x.s, - Ctor = x.constructor; + return finalise(quadrant > 2 ? x.neg() : x, pr, rm, true); +}; - // Negative/NaN/Infinity/zero? - if (s !== 1 || !d || !d[0]) { - return new Ctor(!s || s < 0 && (!d || d[0]) ? NaN : d ? x : 1 / 0); - } - external = false; +/* + * Return a new Decimal whose value is the square root of this Decimal, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * sqrt(-n) = N + * sqrt(N) = N + * sqrt(-I) = N + * sqrt(I) = I + * sqrt(0) = 0 + * sqrt(-0) = -0 + * + */ +P.squareRoot = P.sqrt = function () { + var m, n, sd, r, rep, t, + x = this, + d = x.d, + e = x.e, + s = x.s, + Ctor = x.constructor; - // Initial estimate. - s = Math.sqrt(+x); + // Negative/NaN/Infinity/zero? + if (s !== 1 || !d || !d[0]) { + return new Ctor(!s || s < 0 && (!d || d[0]) ? NaN : d ? x : 1 / 0); + } - // Math.sqrt underflow/overflow? - // Pass x to Math.sqrt as integer, then adjust the exponent of the result. - if (s == 0 || s == 1 / 0) { - n = digitsToString(d); + external = false; - if ((n.length + e) % 2 == 0) n += '0'; - s = Math.sqrt(n); - e = mathfloor((e + 1) / 2) - (e < 0 || e % 2); + // Initial estimate. + s = Math.sqrt(+x); - if (s == 1 / 0) { - n = '1e' + e; - } else { - n = s.toExponential(); - n = n.slice(0, n.indexOf('e') + 1) + e; - } + // Math.sqrt underflow/overflow? + // Pass x to Math.sqrt as integer, then adjust the exponent of the result. + if (s == 0 || s == 1 / 0) { + n = digitsToString(d); + + if ((n.length + e) % 2 == 0) n += '0'; + s = Math.sqrt(n); + e = mathfloor((e + 1) / 2) - (e < 0 || e % 2); - r = new Ctor(n); + if (s == 1 / 0) { + n = '1e' + e; } else { - r = new Ctor(s.toString()); + n = s.toExponential(); + n = n.slice(0, n.indexOf('e') + 1) + e; } - sd = (e = Ctor.precision) + 3; + r = new Ctor(n); + } else { + r = new Ctor(s.toString()); + } - // Newton-Raphson iteration. - for (;;) { - t = r; - r = t.plus(divide(x, t, sd + 2, 1)).times(0.5); + sd = (e = Ctor.precision) + 3; - // TODO? Replace with for-loop and checkRoundingDigits. - if (digitsToString(t.d).slice(0, sd) === (n = digitsToString(r.d)).slice(0, sd)) { - n = n.slice(sd - 3, sd + 1); + // Newton-Raphson iteration. + for (;;) { + t = r; + r = t.plus(divide(x, t, sd + 2, 1)).times(0.5); - // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or - // 4999, i.e. approaching a rounding boundary, continue the iteration. - if (n == '9999' || !rep && n == '4999') { + // TODO? Replace with for-loop and checkRoundingDigits. + if (digitsToString(t.d).slice(0, sd) === (n = digitsToString(r.d)).slice(0, sd)) { + n = n.slice(sd - 3, sd + 1); - // On the first iteration only, check to see if rounding up gives the exact result as the - // nines may infinitely repeat. - if (!rep) { - finalise(t, e + 1, 0); + // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or + // 4999, i.e. approaching a rounding boundary, continue the iteration. + if (n == '9999' || !rep && n == '4999') { - if (t.times(t).eq(x)) { - r = t; - break; - } - } + // On the first iteration only, check to see if rounding up gives the exact result as the + // nines may infinitely repeat. + if (!rep) { + finalise(t, e + 1, 0); - sd += 4; - rep = 1; - } else { + if (t.times(t).eq(x)) { + r = t; + break; + } + } - // If the rounding digits are null, 0{0,4} or 50{0,3}, check for an exact result. - // If not, then there are further digits and m will be truthy. - if (!+n || !+n.slice(1) && n.charAt(0) == '5') { + sd += 4; + rep = 1; + } else { - // Truncate to the first rounding digit. - finalise(r, e + 1, 1); - m = !r.times(r).eq(x); - } + // If the rounding digits are null, 0{0,4} or 50{0,3}, check for an exact result. + // If not, then there are further digits and m will be truthy. + if (!+n || !+n.slice(1) && n.charAt(0) == '5') { - break; + // Truncate to the first rounding digit. + finalise(r, e + 1, 1); + m = !r.times(r).eq(x); } + + break; } } + } - external = true; + external = true; - return finalise(r, e, Ctor.rounding, m); - }; + return finalise(r, e, Ctor.rounding, m); +}; - /* - * Return a new Decimal whose value is the tangent of the value in radians of this Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-Infinity, Infinity] - * - * tan(0) = 0 - * tan(-0) = -0 - * tan(Infinity) = NaN - * tan(-Infinity) = NaN - * tan(NaN) = NaN - * - */ - P.tangent = P.tan = function () { - var pr, rm, - x = this, - Ctor = x.constructor; - - if (!x.isFinite()) return new Ctor(NaN); - if (x.isZero()) return new Ctor(x); +/* + * Return a new Decimal whose value is the tangent of the value in radians of this Decimal. + * + * Domain: [-Infinity, Infinity] + * Range: [-Infinity, Infinity] + * + * tan(0) = 0 + * tan(-0) = -0 + * tan(Infinity) = NaN + * tan(-Infinity) = NaN + * tan(NaN) = NaN + * + */ +P.tangent = P.tan = function () { + var pr, rm, + x = this, + Ctor = x.constructor; - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + 10; - Ctor.rounding = 1; + if (!x.isFinite()) return new Ctor(NaN); + if (x.isZero()) return new Ctor(x); - x = x.sin(); - x.s = 1; - x = divide(x, new Ctor(1).minus(x.times(x)).sqrt(), pr + 10, 0); + pr = Ctor.precision; + rm = Ctor.rounding; + Ctor.precision = pr + 10; + Ctor.rounding = 1; - Ctor.precision = pr; - Ctor.rounding = rm; + x = x.sin(); + x.s = 1; + x = divide(x, new Ctor(1).minus(x.times(x)).sqrt(), pr + 10, 0); - return finalise(quadrant == 2 || quadrant == 4 ? x.neg() : x, pr, rm, true); - }; + Ctor.precision = pr; + Ctor.rounding = rm; + return finalise(quadrant == 2 || quadrant == 4 ? x.neg() : x, pr, rm, true); +}; - /* - * n * 0 = 0 - * n * N = N - * n * I = I - * 0 * n = 0 - * 0 * 0 = 0 - * 0 * N = N - * 0 * I = N - * N * n = N - * N * 0 = N - * N * N = N - * N * I = N - * I * n = I - * I * 0 = N - * I * N = N - * I * I = I - * - * Return a new Decimal whose value is this Decimal times `y`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - */ - P.times = P.mul = function (y) { - var carry, e, i, k, r, rL, t, xdL, ydL, - x = this, - Ctor = x.constructor, - xd = x.d, - yd = (y = new Ctor(y)).d; - y.s *= x.s; +/* + * n * 0 = 0 + * n * N = N + * n * I = I + * 0 * n = 0 + * 0 * 0 = 0 + * 0 * N = N + * 0 * I = N + * N * n = N + * N * 0 = N + * N * N = N + * N * I = N + * I * n = I + * I * 0 = N + * I * N = N + * I * I = I + * + * Return a new Decimal whose value is this Decimal times `y`, rounded to `precision` significant + * digits using rounding mode `rounding`. + * + */ +P.times = P.mul = function (y) { + var carry, e, i, k, r, rL, t, xdL, ydL, + x = this, + Ctor = x.constructor, + xd = x.d, + yd = (y = new Ctor(y)).d; - // If either is NaN, ±Infinity or ±0... - if (!xd || !xd[0] || !yd || !yd[0]) { + y.s *= x.s; - return new Ctor(!y.s || xd && !xd[0] && !yd || yd && !yd[0] && !xd + // If either is NaN, ±Infinity or ±0... + if (!xd || !xd[0] || !yd || !yd[0]) { - // Return NaN if either is NaN. - // Return NaN if x is ±0 and y is ±Infinity, or y is ±0 and x is ±Infinity. - ? NaN + return new Ctor(!y.s || xd && !xd[0] && !yd || yd && !yd[0] && !xd - // Return ±Infinity if either is ±Infinity. - // Return ±0 if either is ±0. - : !xd || !yd ? y.s / 0 : y.s * 0); - } + // Return NaN if either is NaN. + // Return NaN if x is ±0 and y is ±Infinity, or y is ±0 and x is ±Infinity. + ? NaN - e = mathfloor(x.e / LOG_BASE) + mathfloor(y.e / LOG_BASE); - xdL = xd.length; - ydL = yd.length; + // Return ±Infinity if either is ±Infinity. + // Return ±0 if either is ±0. + : !xd || !yd ? y.s / 0 : y.s * 0); + } - // Ensure xd points to the longer array. - if (xdL < ydL) { - r = xd; - xd = yd; - yd = r; - rL = xdL; - xdL = ydL; - ydL = rL; - } + e = mathfloor(x.e / LOG_BASE) + mathfloor(y.e / LOG_BASE); + xdL = xd.length; + ydL = yd.length; - // Initialise the result array with zeros. - r = []; - rL = xdL + ydL; - for (i = rL; i--;) r.push(0); + // Ensure xd points to the longer array. + if (xdL < ydL) { + r = xd; + xd = yd; + yd = r; + rL = xdL; + xdL = ydL; + ydL = rL; + } - // Multiply! - for (i = ydL; --i >= 0;) { - carry = 0; - for (k = xdL + i; k > i;) { - t = r[k] + yd[i] * xd[k - i - 1] + carry; - r[k--] = t % BASE | 0; - carry = t / BASE | 0; - } + // Initialise the result array with zeros. + r = []; + rL = xdL + ydL; + for (i = rL; i--;) r.push(0); - r[k] = (r[k] + carry) % BASE | 0; + // Multiply! + for (i = ydL; --i >= 0;) { + carry = 0; + for (k = xdL + i; k > i;) { + t = r[k] + yd[i] * xd[k - i - 1] + carry; + r[k--] = t % BASE | 0; + carry = t / BASE | 0; } - // Remove trailing zeros. - for (; !r[--rL];) r.pop(); - - if (carry) ++e; - else r.shift(); + r[k] = (r[k] + carry) % BASE | 0; + } - y.d = r; - y.e = getBase10Exponent(r, e); + // Remove trailing zeros. + for (; !r[--rL];) r.pop(); - return external ? finalise(y, Ctor.precision, Ctor.rounding) : y; - }; + if (carry) ++e; + else r.shift(); + y.d = r; + y.e = getBase10Exponent(r, e); - /* - * Return a string representing the value of this Decimal in base 2, round to `sd` significant - * digits using rounding mode `rm`. - * - * If the optional `sd` argument is present then return binary exponential notation. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ - P.toBinary = function (sd, rm) { - return toStringBinary(this, 2, sd, rm); - }; + return external ? finalise(y, Ctor.precision, Ctor.rounding) : y; +}; - /* - * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `dp` - * decimal places using rounding mode `rm` or `rounding` if `rm` is omitted. - * - * If `dp` is omitted, return a new Decimal whose value is the value of this Decimal. - * - * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ - P.toDecimalPlaces = P.toDP = function (dp, rm) { - var x = this, - Ctor = x.constructor; +/* + * Return a string representing the value of this Decimal in base 2, round to `sd` significant + * digits using rounding mode `rm`. + * + * If the optional `sd` argument is present then return binary exponential notation. + * + * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toBinary = function (sd, rm) { + return toStringBinary(this, 2, sd, rm); +}; - x = new Ctor(x); - if (dp === void 0) return x; - checkInt32(dp, 0, MAX_DIGITS); +/* + * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `dp` + * decimal places using rounding mode `rm` or `rounding` if `rm` is omitted. + * + * If `dp` is omitted, return a new Decimal whose value is the value of this Decimal. + * + * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toDecimalPlaces = P.toDP = function (dp, rm) { + var x = this, + Ctor = x.constructor; - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); + x = new Ctor(x); + if (dp === void 0) return x; - return finalise(x, dp + x.e + 1, rm); - }; + checkInt32(dp, 0, MAX_DIGITS); + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); - /* - * Return a string representing the value of this Decimal in exponential notation rounded to - * `dp` fixed decimal places using rounding mode `rounding`. - * - * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ - P.toExponential = function (dp, rm) { - var str, - x = this, - Ctor = x.constructor; + return finalise(x, dp + x.e + 1, rm); +}; - if (dp === void 0) { - str = finiteToString(x, true); - } else { - checkInt32(dp, 0, MAX_DIGITS); - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); +/* + * Return a string representing the value of this Decimal in exponential notation rounded to + * `dp` fixed decimal places using rounding mode `rounding`. + * + * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toExponential = function (dp, rm) { + var str, + x = this, + Ctor = x.constructor; - x = finalise(new Ctor(x), dp + 1, rm); - str = finiteToString(x, true, dp + 1); - } + if (dp === void 0) { + str = finiteToString(x, true); + } else { + checkInt32(dp, 0, MAX_DIGITS); - return x.isNeg() && !x.isZero() ? '-' + str : str; - }; + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); + x = finalise(new Ctor(x), dp + 1, rm); + str = finiteToString(x, true, dp + 1); + } - /* - * Return a string representing the value of this Decimal in normal (fixed-point) notation to - * `dp` fixed decimal places and rounded using rounding mode `rm` or `rounding` if `rm` is - * omitted. - * - * As with JavaScript numbers, (-0).toFixed(0) is '0', but e.g. (-0.00001).toFixed(0) is '-0'. - * - * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - * (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'. - * (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'. - * (-0).toFixed(3) is '0.000'. - * (-0.5).toFixed(0) is '-0'. - * - */ - P.toFixed = function (dp, rm) { - var str, y, - x = this, - Ctor = x.constructor; + return x.isNeg() && !x.isZero() ? '-' + str : str; +}; - if (dp === void 0) { - str = finiteToString(x); - } else { - checkInt32(dp, 0, MAX_DIGITS); - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); +/* + * Return a string representing the value of this Decimal in normal (fixed-point) notation to + * `dp` fixed decimal places and rounded using rounding mode `rm` or `rounding` if `rm` is + * omitted. + * + * As with JavaScript numbers, (-0).toFixed(0) is '0', but e.g. (-0.00001).toFixed(0) is '-0'. + * + * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'. + * (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'. + * (-0).toFixed(3) is '0.000'. + * (-0.5).toFixed(0) is '-0'. + * + */ +P.toFixed = function (dp, rm) { + var str, y, + x = this, + Ctor = x.constructor; - y = finalise(new Ctor(x), dp + x.e + 1, rm); - str = finiteToString(y, false, dp + y.e + 1); - } + if (dp === void 0) { + str = finiteToString(x); + } else { + checkInt32(dp, 0, MAX_DIGITS); - // To determine whether to add the minus sign look at the value before it was rounded, - // i.e. look at `x` rather than `y`. - return x.isNeg() && !x.isZero() ? '-' + str : str; - }; + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); + y = finalise(new Ctor(x), dp + x.e + 1, rm); + str = finiteToString(y, false, dp + y.e + 1); + } - /* - * Return an array representing the value of this Decimal as a simple fraction with an integer - * numerator and an integer denominator. - * - * The denominator will be a positive non-zero value less than or equal to the specified maximum - * denominator. If a maximum denominator is not specified, the denominator will be the lowest - * value necessary to represent the number exactly. - * - * [maxD] {number|string|Decimal} Maximum denominator. Integer >= 1 and < Infinity. - * - */ - P.toFraction = function (maxD) { - var d, d0, d1, d2, e, k, n, n0, n1, pr, q, r, - x = this, - xd = x.d, - Ctor = x.constructor; + // To determine whether to add the minus sign look at the value before it was rounded, + // i.e. look at `x` rather than `y`. + return x.isNeg() && !x.isZero() ? '-' + str : str; +}; - if (!xd) return new Ctor(x); - n1 = d0 = new Ctor(1); - d1 = n0 = new Ctor(0); +/* + * Return an array representing the value of this Decimal as a simple fraction with an integer + * numerator and an integer denominator. + * + * The denominator will be a positive non-zero value less than or equal to the specified maximum + * denominator. If a maximum denominator is not specified, the denominator will be the lowest + * value necessary to represent the number exactly. + * + * [maxD] {number|string|Decimal} Maximum denominator. Integer >= 1 and < Infinity. + * + */ +P.toFraction = function (maxD) { + var d, d0, d1, d2, e, k, n, n0, n1, pr, q, r, + x = this, + xd = x.d, + Ctor = x.constructor; - d = new Ctor(d1); - e = d.e = getPrecision(xd) - x.e - 1; - k = e % LOG_BASE; - d.d[0] = mathpow(10, k < 0 ? LOG_BASE + k : k); + if (!xd) return new Ctor(x); - if (maxD == null) { + n1 = d0 = new Ctor(1); + d1 = n0 = new Ctor(0); - // d is 10**e, the minimum max-denominator needed. - maxD = e > 0 ? d : n1; - } else { - n = new Ctor(maxD); - if (!n.isInt() || n.lt(n1)) throw Error(invalidArgument + n); - maxD = n.gt(d) ? (e > 0 ? d : n1) : n; - } + d = new Ctor(d1); + e = d.e = getPrecision(xd) - x.e - 1; + k = e % LOG_BASE; + d.d[0] = mathpow(10, k < 0 ? LOG_BASE + k : k); - external = false; - n = new Ctor(digitsToString(xd)); - pr = Ctor.precision; - Ctor.precision = e = xd.length * LOG_BASE * 2; - - for (;;) { - q = divide(n, d, 0, 1, 1); - d2 = d0.plus(q.times(d1)); - if (d2.cmp(maxD) == 1) break; - d0 = d1; - d1 = d2; - d2 = n1; - n1 = n0.plus(q.times(d2)); - n0 = d2; - d2 = d; - d = n.minus(q.times(d2)); - n = d2; - } - - d2 = divide(maxD.minus(d0), d1, 0, 1, 1); - n0 = n0.plus(d2.times(n1)); - d0 = d0.plus(d2.times(d1)); - n0.s = n1.s = x.s; - - // Determine which fraction is closer to x, n0/d0 or n1/d1? - r = divide(n1, d1, e, 1).minus(x).abs().cmp(divide(n0, d0, e, 1).minus(x).abs()) < 1 - ? [n1, d1] : [n0, d0]; + if (maxD == null) { - Ctor.precision = pr; - external = true; + // d is 10**e, the minimum max-denominator needed. + maxD = e > 0 ? d : n1; + } else { + n = new Ctor(maxD); + if (!n.isInt() || n.lt(n1)) throw Error(invalidArgument + n); + maxD = n.gt(d) ? (e > 0 ? d : n1) : n; + } + + external = false; + n = new Ctor(digitsToString(xd)); + pr = Ctor.precision; + Ctor.precision = e = xd.length * LOG_BASE * 2; + + for (;;) { + q = divide(n, d, 0, 1, 1); + d2 = d0.plus(q.times(d1)); + if (d2.cmp(maxD) == 1) break; + d0 = d1; + d1 = d2; + d2 = n1; + n1 = n0.plus(q.times(d2)); + n0 = d2; + d2 = d; + d = n.minus(q.times(d2)); + n = d2; + } + + d2 = divide(maxD.minus(d0), d1, 0, 1, 1); + n0 = n0.plus(d2.times(n1)); + d0 = d0.plus(d2.times(d1)); + n0.s = n1.s = x.s; + + // Determine which fraction is closer to x, n0/d0 or n1/d1? + r = divide(n1, d1, e, 1).minus(x).abs().cmp(divide(n0, d0, e, 1).minus(x).abs()) < 1 + ? [n1, d1] : [n0, d0]; + + Ctor.precision = pr; + external = true; - return r; - }; + return r; +}; - /* - * Return a string representing the value of this Decimal in base 16, round to `sd` significant - * digits using rounding mode `rm`. - * - * If the optional `sd` argument is present then return binary exponential notation. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ - P.toHexadecimal = P.toHex = function (sd, rm) { - return toStringBinary(this, 16, sd, rm); - }; +/* + * Return a string representing the value of this Decimal in base 16, round to `sd` significant + * digits using rounding mode `rm`. + * + * If the optional `sd` argument is present then return binary exponential notation. + * + * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toHexadecimal = P.toHex = function (sd, rm) { + return toStringBinary(this, 16, sd, rm); +}; - /* - * Returns a new Decimal whose value is the nearest multiple of the magnitude of `y` to the value - * of this Decimal. - * - * If the value of this Decimal is equidistant from two multiples of `y`, the rounding mode `rm`, - * or `Decimal.rounding` if `rm` is omitted, determines the direction of the nearest multiple. - * - * In the context of this method, rounding mode 4 (ROUND_HALF_UP) is the same as rounding mode 0 - * (ROUND_UP), and so on. - * - * The return value will always have the same sign as this Decimal, unless either this Decimal - * or `y` is NaN, in which case the return value will be also be NaN. - * - * The return value is not affected by the value of `precision`. - * - * y {number|string|Decimal} The magnitude to round to a multiple of. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - * 'toNearest() rounding mode not an integer: {rm}' - * 'toNearest() rounding mode out of range: {rm}' - * - */ - P.toNearest = function (y, rm) { - var x = this, - Ctor = x.constructor; +/* + * Returns a new Decimal whose value is the nearest multiple of the magnitude of `y` to the value + * of this Decimal. + * + * If the value of this Decimal is equidistant from two multiples of `y`, the rounding mode `rm`, + * or `Decimal.rounding` if `rm` is omitted, determines the direction of the nearest multiple. + * + * In the context of this method, rounding mode 4 (ROUND_HALF_UP) is the same as rounding mode 0 + * (ROUND_UP), and so on. + * + * The return value will always have the same sign as this Decimal, unless either this Decimal + * or `y` is NaN, in which case the return value will be also be NaN. + * + * The return value is not affected by the value of `precision`. + * + * y {number|string|Decimal} The magnitude to round to a multiple of. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * 'toNearest() rounding mode not an integer: {rm}' + * 'toNearest() rounding mode out of range: {rm}' + * + */ +P.toNearest = function (y, rm) { + var x = this, + Ctor = x.constructor; - x = new Ctor(x); + x = new Ctor(x); - if (y == null) { + if (y == null) { - // If x is not finite, return x. - if (!x.d) return x; + // If x is not finite, return x. + if (!x.d) return x; - y = new Ctor(1); - rm = Ctor.rounding; - } else { - y = new Ctor(y); - if (rm !== void 0) checkInt32(rm, 0, 8); + y = new Ctor(1); + rm = Ctor.rounding; + } else { + y = new Ctor(y); + if (rm !== void 0) checkInt32(rm, 0, 8); - // If x is not finite, return x if y is not NaN, else NaN. - if (!x.d) return y.s ? x : y; + // If x is not finite, return x if y is not NaN, else NaN. + if (!x.d) return y.s ? x : y; - // If y is not finite, return Infinity with the sign of x if y is Infinity, else NaN. - if (!y.d) { - if (y.s) y.s = x.s; - return y; - } + // If y is not finite, return Infinity with the sign of x if y is Infinity, else NaN. + if (!y.d) { + if (y.s) y.s = x.s; + return y; } + } - // If y is not zero, calculate the nearest multiple of y to x. - if (y.d[0]) { - external = false; - if (rm < 4) rm = [4, 5, 7, 8][rm]; - x = divide(x, y, 0, rm, 1).times(y); - external = true; - finalise(x); + // If y is not zero, calculate the nearest multiple of y to x. + if (y.d[0]) { + external = false; + if (rm < 4) rm = [4, 5, 7, 8][rm]; + x = divide(x, y, 0, rm, 1).times(y); + external = true; + finalise(x); - // If y is zero, return zero with the sign of x. - } else { - y.s = x.s; - x = y; - } + // If y is zero, return zero with the sign of x. + } else { + y.s = x.s; + x = y; + } - return x; - }; + return x; +}; - /* - * Return the value of this Decimal converted to a number primitive. - * Zero keeps its sign. - * - */ - P.toNumber = function () { - return +this; - }; +/* + * Return the value of this Decimal converted to a number primitive. + * Zero keeps its sign. + * + */ +P.toNumber = function () { + return +this; +}; - /* - * Return a string representing the value of this Decimal in base 8, round to `sd` significant - * digits using rounding mode `rm`. - * - * If the optional `sd` argument is present then return binary exponential notation. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ - P.toOctal = function (sd, rm) { - return toStringBinary(this, 8, sd, rm); - }; +/* + * Return a string representing the value of this Decimal in base 8, round to `sd` significant + * digits using rounding mode `rm`. + * + * If the optional `sd` argument is present then return binary exponential notation. + * + * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toOctal = function (sd, rm) { + return toStringBinary(this, 8, sd, rm); +}; - /* - * Return a new Decimal whose value is the value of this Decimal raised to the power `y`, rounded - * to `precision` significant digits using rounding mode `rounding`. - * - * ECMAScript compliant. - * - * pow(x, NaN) = NaN - * pow(x, ±0) = 1 - - * pow(NaN, non-zero) = NaN - * pow(abs(x) > 1, +Infinity) = +Infinity - * pow(abs(x) > 1, -Infinity) = +0 - * pow(abs(x) == 1, ±Infinity) = NaN - * pow(abs(x) < 1, +Infinity) = +0 - * pow(abs(x) < 1, -Infinity) = +Infinity - * pow(+Infinity, y > 0) = +Infinity - * pow(+Infinity, y < 0) = +0 - * pow(-Infinity, odd integer > 0) = -Infinity - * pow(-Infinity, even integer > 0) = +Infinity - * pow(-Infinity, odd integer < 0) = -0 - * pow(-Infinity, even integer < 0) = +0 - * pow(+0, y > 0) = +0 - * pow(+0, y < 0) = +Infinity - * pow(-0, odd integer > 0) = -0 - * pow(-0, even integer > 0) = +0 - * pow(-0, odd integer < 0) = -Infinity - * pow(-0, even integer < 0) = +Infinity - * pow(finite x < 0, finite non-integer) = NaN - * - * For non-integer or very large exponents pow(x, y) is calculated using - * - * x^y = exp(y*ln(x)) - * - * Assuming the first 15 rounding digits are each equally likely to be any digit 0-9, the - * probability of an incorrectly rounded result - * P([49]9{14} | [50]0{14}) = 2 * 0.2 * 10^-14 = 4e-15 = 1/2.5e+14 - * i.e. 1 in 250,000,000,000,000 - * - * If a result is incorrectly rounded the maximum error will be 1 ulp (unit in last place). - * - * y {number|string|Decimal} The power to which to raise this Decimal. - * - */ - P.toPower = P.pow = function (y) { - var e, k, pr, r, rm, s, - x = this, - Ctor = x.constructor, - yn = +(y = new Ctor(y)); +/* + * Return a new Decimal whose value is the value of this Decimal raised to the power `y`, rounded + * to `precision` significant digits using rounding mode `rounding`. + * + * ECMAScript compliant. + * + * pow(x, NaN) = NaN + * pow(x, ±0) = 1 + + * pow(NaN, non-zero) = NaN + * pow(abs(x) > 1, +Infinity) = +Infinity + * pow(abs(x) > 1, -Infinity) = +0 + * pow(abs(x) == 1, ±Infinity) = NaN + * pow(abs(x) < 1, +Infinity) = +0 + * pow(abs(x) < 1, -Infinity) = +Infinity + * pow(+Infinity, y > 0) = +Infinity + * pow(+Infinity, y < 0) = +0 + * pow(-Infinity, odd integer > 0) = -Infinity + * pow(-Infinity, even integer > 0) = +Infinity + * pow(-Infinity, odd integer < 0) = -0 + * pow(-Infinity, even integer < 0) = +0 + * pow(+0, y > 0) = +0 + * pow(+0, y < 0) = +Infinity + * pow(-0, odd integer > 0) = -0 + * pow(-0, even integer > 0) = +0 + * pow(-0, odd integer < 0) = -Infinity + * pow(-0, even integer < 0) = +Infinity + * pow(finite x < 0, finite non-integer) = NaN + * + * For non-integer or very large exponents pow(x, y) is calculated using + * + * x^y = exp(y*ln(x)) + * + * Assuming the first 15 rounding digits are each equally likely to be any digit 0-9, the + * probability of an incorrectly rounded result + * P([49]9{14} | [50]0{14}) = 2 * 0.2 * 10^-14 = 4e-15 = 1/2.5e+14 + * i.e. 1 in 250,000,000,000,000 + * + * If a result is incorrectly rounded the maximum error will be 1 ulp (unit in last place). + * + * y {number|string|Decimal} The power to which to raise this Decimal. + * + */ +P.toPower = P.pow = function (y) { + var e, k, pr, r, rm, s, + x = this, + Ctor = x.constructor, + yn = +(y = new Ctor(y)); - // Either ±Infinity, NaN or ±0? - if (!x.d || !y.d || !x.d[0] || !y.d[0]) return new Ctor(mathpow(+x, yn)); + // Either ±Infinity, NaN or ±0? + if (!x.d || !y.d || !x.d[0] || !y.d[0]) return new Ctor(mathpow(+x, yn)); - x = new Ctor(x); + x = new Ctor(x); - if (x.eq(1)) return x; + if (x.eq(1)) return x; - pr = Ctor.precision; - rm = Ctor.rounding; + pr = Ctor.precision; + rm = Ctor.rounding; - if (y.eq(1)) return finalise(x, pr, rm); + if (y.eq(1)) return finalise(x, pr, rm); - // y exponent - e = mathfloor(y.e / LOG_BASE); + // y exponent + e = mathfloor(y.e / LOG_BASE); - // If y is a small integer use the 'exponentiation by squaring' algorithm. - if (e >= y.d.length - 1 && (k = yn < 0 ? -yn : yn) <= MAX_SAFE_INTEGER) { - r = intPow(Ctor, x, k, pr); - return y.s < 0 ? new Ctor(1).div(r) : finalise(r, pr, rm); - } + // If y is a small integer use the 'exponentiation by squaring' algorithm. + if (e >= y.d.length - 1 && (k = yn < 0 ? -yn : yn) <= MAX_SAFE_INTEGER) { + r = intPow(Ctor, x, k, pr); + return y.s < 0 ? new Ctor(1).div(r) : finalise(r, pr, rm); + } - s = x.s; + s = x.s; - // if x is negative - if (s < 0) { + // if x is negative + if (s < 0) { - // if y is not an integer - if (e < y.d.length - 1) return new Ctor(NaN); + // if y is not an integer + if (e < y.d.length - 1) return new Ctor(NaN); - // Result is positive if x is negative and the last digit of integer y is even. - if ((y.d[e] & 1) == 0) s = 1; + // Result is positive if x is negative and the last digit of integer y is even. + if ((y.d[e] & 1) == 0) s = 1; - // if x.eq(-1) - if (x.e == 0 && x.d[0] == 1 && x.d.length == 1) { - x.s = s; - return x; - } + // if x.eq(-1) + if (x.e == 0 && x.d[0] == 1 && x.d.length == 1) { + x.s = s; + return x; } + } - // Estimate result exponent. - // x^y = 10^e, where e = y * log10(x) - // log10(x) = log10(x_significand) + x_exponent - // log10(x_significand) = ln(x_significand) / ln(10) - k = mathpow(+x, yn); - e = k == 0 || !isFinite(k) - ? mathfloor(yn * (Math.log('0.' + digitsToString(x.d)) / Math.LN10 + x.e + 1)) - : new Ctor(k + '').e; + // Estimate result exponent. + // x^y = 10^e, where e = y * log10(x) + // log10(x) = log10(x_significand) + x_exponent + // log10(x_significand) = ln(x_significand) / ln(10) + k = mathpow(+x, yn); + e = k == 0 || !isFinite(k) + ? mathfloor(yn * (Math.log('0.' + digitsToString(x.d)) / Math.LN10 + x.e + 1)) + : new Ctor(k + '').e; - // Exponent estimate may be incorrect e.g. x: 0.999999999999999999, y: 2.29, e: 0, r.e: -1. + // Exponent estimate may be incorrect e.g. x: 0.999999999999999999, y: 2.29, e: 0, r.e: -1. - // Overflow/underflow? - if (e > Ctor.maxE + 1 || e < Ctor.minE - 1) return new Ctor(e > 0 ? s / 0 : 0); + // Overflow/underflow? + if (e > Ctor.maxE + 1 || e < Ctor.minE - 1) return new Ctor(e > 0 ? s / 0 : 0); - external = false; - Ctor.rounding = x.s = 1; + external = false; + Ctor.rounding = x.s = 1; - // Estimate the extra guard digits needed to ensure five correct rounding digits from - // naturalLogarithm(x). Example of failure without these extra digits (precision: 10): - // new Decimal(2.32456).pow('2087987436534566.46411') - // should be 1.162377823e+764914905173815, but is 1.162355823e+764914905173815 - k = Math.min(12, (e + '').length); + // Estimate the extra guard digits needed to ensure five correct rounding digits from + // naturalLogarithm(x). Example of failure without these extra digits (precision: 10): + // new Decimal(2.32456).pow('2087987436534566.46411') + // should be 1.162377823e+764914905173815, but is 1.162355823e+764914905173815 + k = Math.min(12, (e + '').length); - // r = x^y = exp(y*ln(x)) - r = naturalExponential(y.times(naturalLogarithm(x, pr + k)), pr); + // r = x^y = exp(y*ln(x)) + r = naturalExponential(y.times(naturalLogarithm(x, pr + k)), pr); - // r may be Infinity, e.g. (0.9999999999999999).pow(-1e+40) - if (r.d) { + // r may be Infinity, e.g. (0.9999999999999999).pow(-1e+40) + if (r.d) { - // Truncate to the required precision plus five rounding digits. - r = finalise(r, pr + 5, 1); + // Truncate to the required precision plus five rounding digits. + r = finalise(r, pr + 5, 1); - // If the rounding digits are [49]9999 or [50]0000 increase the precision by 10 and recalculate - // the result. - if (checkRoundingDigits(r.d, pr, rm)) { - e = pr + 10; + // If the rounding digits are [49]9999 or [50]0000 increase the precision by 10 and recalculate + // the result. + if (checkRoundingDigits(r.d, pr, rm)) { + e = pr + 10; - // Truncate to the increased precision plus five rounding digits. - r = finalise(naturalExponential(y.times(naturalLogarithm(x, e + k)), e), e + 5, 1); + // Truncate to the increased precision plus five rounding digits. + r = finalise(naturalExponential(y.times(naturalLogarithm(x, e + k)), e), e + 5, 1); - // Check for 14 nines from the 2nd rounding digit (the first rounding digit may be 4 or 9). - if (+digitsToString(r.d).slice(pr + 1, pr + 15) + 1 == 1e14) { - r = finalise(r, pr + 1, 0); - } + // Check for 14 nines from the 2nd rounding digit (the first rounding digit may be 4 or 9). + if (+digitsToString(r.d).slice(pr + 1, pr + 15) + 1 == 1e14) { + r = finalise(r, pr + 1, 0); } } + } - r.s = s; - external = true; - Ctor.rounding = rm; - - return finalise(r, pr, rm); - }; + r.s = s; + external = true; + Ctor.rounding = rm; + return finalise(r, pr, rm); +}; - /* - * Return a string representing the value of this Decimal rounded to `sd` significant digits - * using rounding mode `rounding`. - * - * Return exponential notation if `sd` is less than the number of digits necessary to represent - * the integer part of the value in normal notation. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ - P.toPrecision = function (sd, rm) { - var str, - x = this, - Ctor = x.constructor; - if (sd === void 0) { - str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos); - } else { - checkInt32(sd, 1, MAX_DIGITS); +/* + * Return a string representing the value of this Decimal rounded to `sd` significant digits + * using rounding mode `rounding`. + * + * Return exponential notation if `sd` is less than the number of digits necessary to represent + * the integer part of the value in normal notation. + * + * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + */ +P.toPrecision = function (sd, rm) { + var str, + x = this, + Ctor = x.constructor; - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); + if (sd === void 0) { + str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos); + } else { + checkInt32(sd, 1, MAX_DIGITS); - x = finalise(new Ctor(x), sd, rm); - str = finiteToString(x, sd <= x.e || x.e <= Ctor.toExpNeg, sd); - } + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); - return x.isNeg() && !x.isZero() ? '-' + str : str; - }; + x = finalise(new Ctor(x), sd, rm); + str = finiteToString(x, sd <= x.e || x.e <= Ctor.toExpNeg, sd); + } + return x.isNeg() && !x.isZero() ? '-' + str : str; +}; - /* - * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `sd` - * significant digits using rounding mode `rm`, or to `precision` and `rounding` respectively if - * omitted. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - * 'toSD() digits out of range: {sd}' - * 'toSD() digits not an integer: {sd}' - * 'toSD() rounding mode not an integer: {rm}' - * 'toSD() rounding mode out of range: {rm}' - * - */ - P.toSignificantDigits = P.toSD = function (sd, rm) { - var x = this, - Ctor = x.constructor; - if (sd === void 0) { - sd = Ctor.precision; - rm = Ctor.rounding; - } else { - checkInt32(sd, 1, MAX_DIGITS); +/* + * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `sd` + * significant digits using rounding mode `rm`, or to `precision` and `rounding` respectively if + * omitted. + * + * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. + * + * 'toSD() digits out of range: {sd}' + * 'toSD() digits not an integer: {sd}' + * 'toSD() rounding mode not an integer: {rm}' + * 'toSD() rounding mode out of range: {rm}' + * + */ +P.toSignificantDigits = P.toSD = function (sd, rm) { + var x = this, + Ctor = x.constructor; - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); - } + if (sd === void 0) { + sd = Ctor.precision; + rm = Ctor.rounding; + } else { + checkInt32(sd, 1, MAX_DIGITS); - return finalise(new Ctor(x), sd, rm); - }; + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); + } + return finalise(new Ctor(x), sd, rm); +}; - /* - * Return a string representing the value of this Decimal. - * - * Return exponential notation if this Decimal has a positive exponent equal to or greater than - * `toExpPos`, or a negative exponent equal to or less than `toExpNeg`. - * - */ - P.toString = function () { - var x = this, - Ctor = x.constructor, - str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos); - return x.isNeg() && !x.isZero() ? '-' + str : str; - }; +/* + * Return a string representing the value of this Decimal. + * + * Return exponential notation if this Decimal has a positive exponent equal to or greater than + * `toExpPos`, or a negative exponent equal to or less than `toExpNeg`. + * + */ +P.toString = function () { + var x = this, + Ctor = x.constructor, + str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos); + return x.isNeg() && !x.isZero() ? '-' + str : str; +}; - /* - * Return a new Decimal whose value is the value of this Decimal truncated to a whole number. - * - */ - P.truncated = P.trunc = function () { - return finalise(new this.constructor(this), this.e + 1, 1); - }; +/* + * Return a new Decimal whose value is the value of this Decimal truncated to a whole number. + * + */ +P.truncated = P.trunc = function () { + return finalise(new this.constructor(this), this.e + 1, 1); +}; - /* - * Return a string representing the value of this Decimal. - * Unlike `toString`, negative zero will include the minus sign. - * - */ - P.valueOf = P.toJSON = function () { - var x = this, - Ctor = x.constructor, - str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos); - return x.isNeg() ? '-' + str : str; - }; +/* + * Return a string representing the value of this Decimal. + * Unlike `toString`, negative zero will include the minus sign. + * + */ +P.valueOf = P.toJSON = function () { + var x = this, + Ctor = x.constructor, + str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos); + return x.isNeg() ? '-' + str : str; +}; - /* - // Add aliases to match BigDecimal method names. - // P.add = P.plus; - P.subtract = P.minus; - P.multiply = P.times; - P.divide = P.div; - P.remainder = P.mod; - P.compareTo = P.cmp; - P.negate = P.neg; - */ +/* +// Add aliases to match BigDecimal method names. +// P.add = P.plus; +P.subtract = P.minus; +P.multiply = P.times; +P.divide = P.div; +P.remainder = P.mod; +P.compareTo = P.cmp; +P.negate = P.neg; + */ - // Helper functions for Decimal.prototype (P) and/or Decimal methods, and their callers. +// Helper functions for Decimal.prototype (P) and/or Decimal methods, and their callers. - /* - * digitsToString P.cubeRoot, P.logarithm, P.squareRoot, P.toFraction, P.toPower, - * finiteToString, naturalExponential, naturalLogarithm - * checkInt32 P.toDecimalPlaces, P.toExponential, P.toFixed, P.toNearest, - * P.toPrecision, P.toSignificantDigits, toStringBinary, random - * checkRoundingDigits P.logarithm, P.toPower, naturalExponential, naturalLogarithm - * convertBase toStringBinary, parseOther - * cos P.cos - * divide P.atanh, P.cubeRoot, P.dividedBy, P.dividedToIntegerBy, - * P.logarithm, P.modulo, P.squareRoot, P.tan, P.tanh, P.toFraction, - * P.toNearest, toStringBinary, naturalExponential, naturalLogarithm, - * taylorSeries, atan2, parseOther - * finalise P.absoluteValue, P.atan, P.atanh, P.ceil, P.cos, P.cosh, - * P.cubeRoot, P.dividedToIntegerBy, P.floor, P.logarithm, P.minus, - * P.modulo, P.negated, P.plus, P.round, P.sin, P.sinh, P.squareRoot, - * P.tan, P.times, P.toDecimalPlaces, P.toExponential, P.toFixed, - * P.toNearest, P.toPower, P.toPrecision, P.toSignificantDigits, - * P.truncated, divide, getLn10, getPi, naturalExponential, - * naturalLogarithm, ceil, floor, round, trunc - * finiteToString P.toExponential, P.toFixed, P.toPrecision, P.toString, P.valueOf, - * toStringBinary - * getBase10Exponent P.minus, P.plus, P.times, parseOther - * getLn10 P.logarithm, naturalLogarithm - * getPi P.acos, P.asin, P.atan, toLessThanHalfPi, atan2 - * getPrecision P.precision, P.toFraction - * getZeroString digitsToString, finiteToString - * intPow P.toPower, parseOther - * isOdd toLessThanHalfPi - * maxOrMin max, min - * naturalExponential P.naturalExponential, P.toPower - * naturalLogarithm P.acosh, P.asinh, P.atanh, P.logarithm, P.naturalLogarithm, - * P.toPower, naturalExponential - * nonFiniteToString finiteToString, toStringBinary - * parseDecimal Decimal - * parseOther Decimal - * sin P.sin - * taylorSeries P.cosh, P.sinh, cos, sin - * toLessThanHalfPi P.cos, P.sin - * toStringBinary P.toBinary, P.toHexadecimal, P.toOctal - * truncate intPow - * - * Throws: P.logarithm, P.precision, P.toFraction, checkInt32, getLn10, getPi, - * naturalLogarithm, config, parseOther, random, Decimal - */ +/* + * digitsToString P.cubeRoot, P.logarithm, P.squareRoot, P.toFraction, P.toPower, + * finiteToString, naturalExponential, naturalLogarithm + * checkInt32 P.toDecimalPlaces, P.toExponential, P.toFixed, P.toNearest, + * P.toPrecision, P.toSignificantDigits, toStringBinary, random + * checkRoundingDigits P.logarithm, P.toPower, naturalExponential, naturalLogarithm + * convertBase toStringBinary, parseOther + * cos P.cos + * divide P.atanh, P.cubeRoot, P.dividedBy, P.dividedToIntegerBy, + * P.logarithm, P.modulo, P.squareRoot, P.tan, P.tanh, P.toFraction, + * P.toNearest, toStringBinary, naturalExponential, naturalLogarithm, + * taylorSeries, atan2, parseOther + * finalise P.absoluteValue, P.atan, P.atanh, P.ceil, P.cos, P.cosh, + * P.cubeRoot, P.dividedToIntegerBy, P.floor, P.logarithm, P.minus, + * P.modulo, P.negated, P.plus, P.round, P.sin, P.sinh, P.squareRoot, + * P.tan, P.times, P.toDecimalPlaces, P.toExponential, P.toFixed, + * P.toNearest, P.toPower, P.toPrecision, P.toSignificantDigits, + * P.truncated, divide, getLn10, getPi, naturalExponential, + * naturalLogarithm, ceil, floor, round, trunc + * finiteToString P.toExponential, P.toFixed, P.toPrecision, P.toString, P.valueOf, + * toStringBinary + * getBase10Exponent P.minus, P.plus, P.times, parseOther + * getLn10 P.logarithm, naturalLogarithm + * getPi P.acos, P.asin, P.atan, toLessThanHalfPi, atan2 + * getPrecision P.precision, P.toFraction + * getZeroString digitsToString, finiteToString + * intPow P.toPower, parseOther + * isOdd toLessThanHalfPi + * maxOrMin max, min + * naturalExponential P.naturalExponential, P.toPower + * naturalLogarithm P.acosh, P.asinh, P.atanh, P.logarithm, P.naturalLogarithm, + * P.toPower, naturalExponential + * nonFiniteToString finiteToString, toStringBinary + * parseDecimal Decimal + * parseOther Decimal + * sin P.sin + * taylorSeries P.cosh, P.sinh, cos, sin + * toLessThanHalfPi P.cos, P.sin + * toStringBinary P.toBinary, P.toHexadecimal, P.toOctal + * truncate intPow + * + * Throws: P.logarithm, P.precision, P.toFraction, checkInt32, getLn10, getPi, + * naturalLogarithm, config, parseOther, random, Decimal + */ - function digitsToString(d) { - var i, k, ws, - indexOfLastWord = d.length - 1, - str = '', - w = d[0]; - if (indexOfLastWord > 0) { - str += w; - for (i = 1; i < indexOfLastWord; i++) { - ws = d[i] + ''; - k = LOG_BASE - ws.length; - if (k) str += getZeroString(k); - str += ws; - } +function digitsToString(d) { + var i, k, ws, + indexOfLastWord = d.length - 1, + str = '', + w = d[0]; - w = d[i]; - ws = w + ''; + if (indexOfLastWord > 0) { + str += w; + for (i = 1; i < indexOfLastWord; i++) { + ws = d[i] + ''; k = LOG_BASE - ws.length; if (k) str += getZeroString(k); - } else if (w === 0) { - return '0'; + str += ws; } - // Remove trailing zeros of last w. - for (; w % 10 === 0;) w /= 10; - - return str + w; + w = d[i]; + ws = w + ''; + k = LOG_BASE - ws.length; + if (k) str += getZeroString(k); + } else if (w === 0) { + return '0'; } + // Remove trailing zeros of last w. + for (; w % 10 === 0;) w /= 10; - function checkInt32(i, min, max) { - if (i !== ~~i || i < min || i > max) { - throw Error(invalidArgument + i); - } + return str + w; +} + + +function checkInt32(i, min, max) { + if (i !== ~~i || i < min || i > max) { + throw Error(invalidArgument + i); } +} - /* - * Check 5 rounding digits if `repeating` is null, 4 otherwise. - * `repeating == null` if caller is `log` or `pow`, - * `repeating != null` if caller is `naturalLogarithm` or `naturalExponential`. - */ - function checkRoundingDigits(d, i, rm, repeating) { - var di, k, r, rd; +/* + * Check 5 rounding digits if `repeating` is null, 4 otherwise. + * `repeating == null` if caller is `log` or `pow`, + * `repeating != null` if caller is `naturalLogarithm` or `naturalExponential`. + */ +function checkRoundingDigits(d, i, rm, repeating) { + var di, k, r, rd; - // Get the length of the first word of the array d. - for (k = d[0]; k >= 10; k /= 10) --i; + // Get the length of the first word of the array d. + for (k = d[0]; k >= 10; k /= 10) --i; - // Is the rounding digit in the first word of d? - if (--i < 0) { - i += LOG_BASE; - di = 0; - } else { - di = Math.ceil((i + 1) / LOG_BASE); - i %= LOG_BASE; - } + // Is the rounding digit in the first word of d? + if (--i < 0) { + i += LOG_BASE; + di = 0; + } else { + di = Math.ceil((i + 1) / LOG_BASE); + i %= LOG_BASE; + } - // i is the index (0 - 6) of the rounding digit. - // E.g. if within the word 3487563 the first rounding digit is 5, - // then i = 4, k = 1000, rd = 3487563 % 1000 = 563 - k = mathpow(10, LOG_BASE - i); - rd = d[di] % k | 0; + // i is the index (0 - 6) of the rounding digit. + // E.g. if within the word 3487563 the first rounding digit is 5, + // then i = 4, k = 1000, rd = 3487563 % 1000 = 563 + k = mathpow(10, LOG_BASE - i); + rd = d[di] % k | 0; - if (repeating == null) { - if (i < 3) { - if (i == 0) rd = rd / 100 | 0; - else if (i == 1) rd = rd / 10 | 0; - r = rm < 4 && rd == 99999 || rm > 3 && rd == 49999 || rd == 50000 || rd == 0; - } else { - r = (rm < 4 && rd + 1 == k || rm > 3 && rd + 1 == k / 2) && - (d[di + 1] / k / 100 | 0) == mathpow(10, i - 2) - 1 || - (rd == k / 2 || rd == 0) && (d[di + 1] / k / 100 | 0) == 0; - } + if (repeating == null) { + if (i < 3) { + if (i == 0) rd = rd / 100 | 0; + else if (i == 1) rd = rd / 10 | 0; + r = rm < 4 && rd == 99999 || rm > 3 && rd == 49999 || rd == 50000 || rd == 0; } else { - if (i < 4) { - if (i == 0) rd = rd / 1000 | 0; - else if (i == 1) rd = rd / 100 | 0; - else if (i == 2) rd = rd / 10 | 0; - r = (repeating || rm < 4) && rd == 9999 || !repeating && rm > 3 && rd == 4999; - } else { - r = ((repeating || rm < 4) && rd + 1 == k || - (!repeating && rm > 3) && rd + 1 == k / 2) && - (d[di + 1] / k / 1000 | 0) == mathpow(10, i - 3) - 1; - } + r = (rm < 4 && rd + 1 == k || rm > 3 && rd + 1 == k / 2) && + (d[di + 1] / k / 100 | 0) == mathpow(10, i - 2) - 1 || + (rd == k / 2 || rd == 0) && (d[di + 1] / k / 100 | 0) == 0; + } + } else { + if (i < 4) { + if (i == 0) rd = rd / 1000 | 0; + else if (i == 1) rd = rd / 100 | 0; + else if (i == 2) rd = rd / 10 | 0; + r = (repeating || rm < 4) && rd == 9999 || !repeating && rm > 3 && rd == 4999; + } else { + r = ((repeating || rm < 4) && rd + 1 == k || + (!repeating && rm > 3) && rd + 1 == k / 2) && + (d[di + 1] / k / 1000 | 0) == mathpow(10, i - 3) - 1; } - - return r; } + return r; +} - // Convert string of `baseIn` to an array of numbers of `baseOut`. - // Eg. convertBase('255', 10, 16) returns [15, 15]. - // Eg. convertBase('ff', 16, 10) returns [2, 5, 5]. - function convertBase(str, baseIn, baseOut) { - var j, - arr = [0], - arrL, - i = 0, - strL = str.length; - for (; i < strL;) { - for (arrL = arr.length; arrL--;) arr[arrL] *= baseIn; - arr[0] += NUMERALS.indexOf(str.charAt(i++)); - for (j = 0; j < arr.length; j++) { - if (arr[j] > baseOut - 1) { - if (arr[j + 1] === void 0) arr[j + 1] = 0; - arr[j + 1] += arr[j] / baseOut | 0; - arr[j] %= baseOut; - } +// Convert string of `baseIn` to an array of numbers of `baseOut`. +// Eg. convertBase('255', 10, 16) returns [15, 15]. +// Eg. convertBase('ff', 16, 10) returns [2, 5, 5]. +function convertBase(str, baseIn, baseOut) { + var j, + arr = [0], + arrL, + i = 0, + strL = str.length; + + for (; i < strL;) { + for (arrL = arr.length; arrL--;) arr[arrL] *= baseIn; + arr[0] += NUMERALS.indexOf(str.charAt(i++)); + for (j = 0; j < arr.length; j++) { + if (arr[j] > baseOut - 1) { + if (arr[j + 1] === void 0) arr[j + 1] = 0; + arr[j + 1] += arr[j] / baseOut | 0; + arr[j] %= baseOut; } } + } + + return arr.reverse(); +} + + +/* + * cos(x) = 1 - x^2/2! + x^4/4! - ... + * |x| < pi/2 + * + */ +function cosine(Ctor, x) { + var k, y, + len = x.d.length; + + // Argument reduction: cos(4x) = 8*(cos^4(x) - cos^2(x)) + 1 + // i.e. cos(x) = 8*(cos^4(x/4) - cos^2(x/4)) + 1 - return arr.reverse(); + // Estimate the optimum number of times to use the argument reduction. + if (len < 32) { + k = Math.ceil(len / 3); + y = Math.pow(4, -k).toString(); + } else { + k = 16; + y = '2.3283064365386962890625e-10'; } + Ctor.precision += k; - /* - * cos(x) = 1 - x^2/2! + x^4/4! - ... - * |x| < pi/2 - * - */ - function cosine(Ctor, x) { - var k, y, - len = x.d.length; + x = taylorSeries(Ctor, 1, x.times(y), new Ctor(1)); - // Argument reduction: cos(4x) = 8*(cos^4(x) - cos^2(x)) + 1 - // i.e. cos(x) = 8*(cos^4(x/4) - cos^2(x/4)) + 1 + // Reverse argument reduction + for (var i = k; i--;) { + var cos2x = x.times(x); + x = cos2x.times(cos2x).minus(cos2x).times(8).plus(1); + } - // Estimate the optimum number of times to use the argument reduction. - if (len < 32) { - k = Math.ceil(len / 3); - y = Math.pow(4, -k).toString(); - } else { - k = 16; - y = '2.3283064365386962890625e-10'; - } + Ctor.precision -= k; - Ctor.precision += k; + return x; +} - x = taylorSeries(Ctor, 1, x.times(y), new Ctor(1)); - // Reverse argument reduction - for (var i = k; i--;) { - var cos2x = x.times(x); - x = cos2x.times(cos2x).minus(cos2x).times(8).plus(1); +/* + * Perform division in the specified base. + */ +var divide = (function () { + + // Assumes non-zero x and k, and hence non-zero result. + function multiplyInteger(x, k, base) { + var temp, + carry = 0, + i = x.length; + + for (x = x.slice(); i--;) { + temp = x[i] * k + carry; + x[i] = temp % base | 0; + carry = temp / base | 0; } - Ctor.precision -= k; + if (carry) x.unshift(carry); return x; } + function compare(a, b, aL, bL) { + var i, r; - /* - * Perform division in the specified base. - */ - var divide = (function () { - - // Assumes non-zero x and k, and hence non-zero result. - function multiplyInteger(x, k, base) { - var temp, - carry = 0, - i = x.length; - - for (x = x.slice(); i--;) { - temp = x[i] * k + carry; - x[i] = temp % base | 0; - carry = temp / base | 0; + if (aL != bL) { + r = aL > bL ? 1 : -1; + } else { + for (i = r = 0; i < aL; i++) { + if (a[i] != b[i]) { + r = a[i] > b[i] ? 1 : -1; + break; + } } + } - if (carry) x.unshift(carry); + return r; + } - return x; + function subtract(a, b, aL, base) { + var i = 0; + + // Subtract b from a. + for (; aL--;) { + a[aL] -= i; + i = a[aL] < b[aL] ? 1 : 0; + a[aL] = i * base + a[aL] - b[aL]; } - function compare(a, b, aL, bL) { - var i, r; + // Remove leading zeros. + for (; !a[0] && a.length > 1;) a.shift(); + } - if (aL != bL) { - r = aL > bL ? 1 : -1; - } else { - for (i = r = 0; i < aL; i++) { - if (a[i] != b[i]) { - r = a[i] > b[i] ? 1 : -1; - break; - } - } - } + return function (x, y, pr, rm, dp, base) { + var cmp, e, i, k, logBase, more, prod, prodL, q, qd, rem, remL, rem0, sd, t, xi, xL, yd0, + yL, yz, + Ctor = x.constructor, + sign = x.s == y.s ? 1 : -1, + xd = x.d, + yd = y.d; - return r; - } + // Either NaN, Infinity or 0? + if (!xd || !xd[0] || !yd || !yd[0]) { - function subtract(a, b, aL, base) { - var i = 0; + return new Ctor(// Return NaN if either NaN, or both Infinity or 0. + !x.s || !y.s || (xd ? yd && xd[0] == yd[0] : !yd) ? NaN : - // Subtract b from a. - for (; aL--;) { - a[aL] -= i; - i = a[aL] < b[aL] ? 1 : 0; - a[aL] = i * base + a[aL] - b[aL]; - } + // Return ±0 if x is 0 or y is ±Infinity, or return ±Infinity as y is 0. + xd && xd[0] == 0 || !yd ? sign * 0 : sign / 0); + } - // Remove leading zeros. - for (; !a[0] && a.length > 1;) a.shift(); + if (base) { + logBase = 1; + e = x.e - y.e; + } else { + base = BASE; + logBase = LOG_BASE; + e = mathfloor(x.e / logBase) - mathfloor(y.e / logBase); } - return function (x, y, pr, rm, dp, base) { - var cmp, e, i, k, logBase, more, prod, prodL, q, qd, rem, remL, rem0, sd, t, xi, xL, yd0, - yL, yz, - Ctor = x.constructor, - sign = x.s == y.s ? 1 : -1, - xd = x.d, - yd = y.d; + yL = yd.length; + xL = xd.length; + q = new Ctor(sign); + qd = q.d = []; - // Either NaN, Infinity or 0? - if (!xd || !xd[0] || !yd || !yd[0]) { + // Result exponent may be one less than e. + // The digit array of a Decimal from toStringBinary may have trailing zeros. + for (i = 0; yd[i] == (xd[i] || 0); i++); - return new Ctor(// Return NaN if either NaN, or both Infinity or 0. - !x.s || !y.s || (xd ? yd && xd[0] == yd[0] : !yd) ? NaN : + if (yd[i] > (xd[i] || 0)) e--; - // Return ±0 if x is 0 or y is ±Infinity, or return ±Infinity as y is 0. - xd && xd[0] == 0 || !yd ? sign * 0 : sign / 0); - } + if (pr == null) { + sd = pr = Ctor.precision; + rm = Ctor.rounding; + } else if (dp) { + sd = pr + (x.e - y.e) + 1; + } else { + sd = pr; + } - if (base) { - logBase = 1; - e = x.e - y.e; - } else { - base = BASE; - logBase = LOG_BASE; - e = mathfloor(x.e / logBase) - mathfloor(y.e / logBase); - } + if (sd < 0) { + qd.push(1); + more = true; + } else { - yL = yd.length; - xL = xd.length; - q = new Ctor(sign); - qd = q.d = []; + // Convert precision in number of base 10 digits to base 1e7 digits. + sd = sd / logBase + 2 | 0; + i = 0; - // Result exponent may be one less than e. - // The digit array of a Decimal from toStringBinary may have trailing zeros. - for (i = 0; yd[i] == (xd[i] || 0); i++); + // divisor < 1e7 + if (yL == 1) { + k = 0; + yd = yd[0]; + sd++; - if (yd[i] > (xd[i] || 0)) e--; + // k is the carry. + for (; (i < xL || k) && sd--; i++) { + t = k * base + (xd[i] || 0); + qd[i] = t / yd | 0; + k = t % yd | 0; + } - if (pr == null) { - sd = pr = Ctor.precision; - rm = Ctor.rounding; - } else if (dp) { - sd = pr + (x.e - y.e) + 1; - } else { - sd = pr; - } + more = k || i < xL; - if (sd < 0) { - qd.push(1); - more = true; + // divisor >= 1e7 } else { - // Convert precision in number of base 10 digits to base 1e7 digits. - sd = sd / logBase + 2 | 0; - i = 0; + // Normalise xd and yd so highest order digit of yd is >= base/2 + k = base / (yd[0] + 1) | 0; - // divisor < 1e7 - if (yL == 1) { - k = 0; - yd = yd[0]; - sd++; - - // k is the carry. - for (; (i < xL || k) && sd--; i++) { - t = k * base + (xd[i] || 0); - qd[i] = t / yd | 0; - k = t % yd | 0; - } + if (k > 1) { + yd = multiplyInteger(yd, k, base); + xd = multiplyInteger(xd, k, base); + yL = yd.length; + xL = xd.length; + } - more = k || i < xL; + xi = yL; + rem = xd.slice(0, yL); + remL = rem.length; - // divisor >= 1e7 - } else { + // Add zeros to make remainder as long as divisor. + for (; remL < yL;) rem[remL++] = 0; - // Normalise xd and yd so highest order digit of yd is >= base/2 - k = base / (yd[0] + 1) | 0; + yz = yd.slice(); + yz.unshift(0); + yd0 = yd[0]; - if (k > 1) { - yd = multiplyInteger(yd, k, base); - xd = multiplyInteger(xd, k, base); - yL = yd.length; - xL = xd.length; - } + if (yd[1] >= base / 2) ++yd0; - xi = yL; - rem = xd.slice(0, yL); - remL = rem.length; + do { + k = 0; - // Add zeros to make remainder as long as divisor. - for (; remL < yL;) rem[remL++] = 0; + // Compare divisor and remainder. + cmp = compare(yd, rem, yL, remL); - yz = yd.slice(); - yz.unshift(0); - yd0 = yd[0]; + // If divisor < remainder. + if (cmp < 0) { - if (yd[1] >= base / 2) ++yd0; + // Calculate trial digit, k. + rem0 = rem[0]; + if (yL != remL) rem0 = rem0 * base + (rem[1] || 0); - do { - k = 0; + // k will be how many times the divisor goes into the current remainder. + k = rem0 / yd0 | 0; - // Compare divisor and remainder. - cmp = compare(yd, rem, yL, remL); + // Algorithm: + // 1. product = divisor * trial digit (k) + // 2. if product > remainder: product -= divisor, k-- + // 3. remainder -= product + // 4. if product was < remainder at 2: + // 5. compare new remainder and divisor + // 6. If remainder > divisor: remainder -= divisor, k++ - // If divisor < remainder. - if (cmp < 0) { + if (k > 1) { + if (k >= base) k = base - 1; - // Calculate trial digit, k. - rem0 = rem[0]; - if (yL != remL) rem0 = rem0 * base + (rem[1] || 0); + // product = divisor * trial digit. + prod = multiplyInteger(yd, k, base); + prodL = prod.length; + remL = rem.length; - // k will be how many times the divisor goes into the current remainder. - k = rem0 / yd0 | 0; + // Compare product and remainder. + cmp = compare(prod, rem, prodL, remL); - // Algorithm: - // 1. product = divisor * trial digit (k) - // 2. if product > remainder: product -= divisor, k-- - // 3. remainder -= product - // 4. if product was < remainder at 2: - // 5. compare new remainder and divisor - // 6. If remainder > divisor: remainder -= divisor, k++ + // product > remainder. + if (cmp == 1) { + k--; - if (k > 1) { - if (k >= base) k = base - 1; + // Subtract divisor from product. + subtract(prod, yL < prodL ? yz : yd, prodL, base); + } + } else { - // product = divisor * trial digit. - prod = multiplyInteger(yd, k, base); - prodL = prod.length; - remL = rem.length; + // cmp is -1. + // If k is 0, there is no need to compare yd and rem again below, so change cmp to 1 + // to avoid it. If k is 1 there is a need to compare yd and rem again below. + if (k == 0) cmp = k = 1; + prod = yd.slice(); + } - // Compare product and remainder. - cmp = compare(prod, rem, prodL, remL); + prodL = prod.length; + if (prodL < remL) prod.unshift(0); - // product > remainder. - if (cmp == 1) { - k--; + // Subtract product from remainder. + subtract(rem, prod, remL, base); - // Subtract divisor from product. - subtract(prod, yL < prodL ? yz : yd, prodL, base); - } - } else { + // If product was < previous remainder. + if (cmp == -1) { + remL = rem.length; - // cmp is -1. - // If k is 0, there is no need to compare yd and rem again below, so change cmp to 1 - // to avoid it. If k is 1 there is a need to compare yd and rem again below. - if (k == 0) cmp = k = 1; - prod = yd.slice(); - } + // Compare divisor and new remainder. + cmp = compare(yd, rem, yL, remL); - prodL = prod.length; - if (prodL < remL) prod.unshift(0); + // If divisor < new remainder, subtract divisor from remainder. + if (cmp < 1) { + k++; - // Subtract product from remainder. - subtract(rem, prod, remL, base); + // Subtract divisor from remainder. + subtract(rem, yL < remL ? yz : yd, remL, base); + } + } - // If product was < previous remainder. - if (cmp == -1) { - remL = rem.length; + remL = rem.length; + } else if (cmp === 0) { + k++; + rem = [0]; + } // if cmp === 1, k will be 0 - // Compare divisor and new remainder. - cmp = compare(yd, rem, yL, remL); + // Add the next digit, k, to the result array. + qd[i++] = k; - // If divisor < new remainder, subtract divisor from remainder. - if (cmp < 1) { - k++; + // Update the remainder. + if (cmp && rem[0]) { + rem[remL++] = xd[xi] || 0; + } else { + rem = [xd[xi]]; + remL = 1; + } - // Subtract divisor from remainder. - subtract(rem, yL < remL ? yz : yd, remL, base); - } - } + } while ((xi++ < xL || rem[0] !== void 0) && sd--); - remL = rem.length; - } else if (cmp === 0) { - k++; - rem = [0]; - } // if cmp === 1, k will be 0 + more = rem[0] !== void 0; + } - // Add the next digit, k, to the result array. - qd[i++] = k; + // Leading zero? + if (!qd[0]) qd.shift(); + } - // Update the remainder. - if (cmp && rem[0]) { - rem[remL++] = xd[xi] || 0; - } else { - rem = [xd[xi]]; - remL = 1; - } + // logBase is 1 when divide is being used for base conversion. + if (logBase == 1) { + q.e = e; + inexact = more; + } else { - } while ((xi++ < xL || rem[0] !== void 0) && sd--); + // To calculate q.e, first get the number of digits of qd[0]. + for (i = 1, k = qd[0]; k >= 10; k /= 10) i++; + q.e = i + e * logBase - 1; - more = rem[0] !== void 0; - } + finalise(q, dp ? pr + q.e + 1 : pr, rm, more); + } - // Leading zero? - if (!qd[0]) qd.shift(); - } + return q; + }; +})(); - // logBase is 1 when divide is being used for base conversion. - if (logBase == 1) { - q.e = e; - inexact = more; - } else { - // To calculate q.e, first get the number of digits of qd[0]. - for (i = 1, k = qd[0]; k >= 10; k /= 10) i++; - q.e = i + e * logBase - 1; +/* + * Round `x` to `sd` significant digits using rounding mode `rm`. + * Check for over/under-flow. + */ + function finalise(x, sd, rm, isTruncated) { + var digits, i, j, k, rd, roundUp, w, xd, xdi, + Ctor = x.constructor; - finalise(q, dp ? pr + q.e + 1 : pr, rm, more); - } + // Don't round if sd is null or undefined. + out: if (sd != null) { + xd = x.d; - return q; - }; - })(); + // Infinity/NaN. + if (!xd) return x; + // rd: the rounding digit, i.e. the digit after the digit that may be rounded up. + // w: the word of xd containing rd, a base 1e7 number. + // xdi: the index of w within xd. + // digits: the number of digits of w. + // i: what would be the index of rd within w if all the numbers were 7 digits long (i.e. if + // they had leading zeros) + // j: if > 0, the actual index of rd within w (if < 0, rd is a leading zero). - /* - * Round `x` to `sd` significant digits using rounding mode `rm`. - * Check for over/under-flow. - */ - function finalise(x, sd, rm, isTruncated) { - var digits, i, j, k, rd, roundUp, w, xd, xdi, - Ctor = x.constructor; - - // Don't round if sd is null or undefined. - out: if (sd != null) { - xd = x.d; - - // Infinity/NaN. - if (!xd) return x; - - // rd: the rounding digit, i.e. the digit after the digit that may be rounded up. - // w: the word of xd containing rd, a base 1e7 number. - // xdi: the index of w within xd. - // digits: the number of digits of w. - // i: what would be the index of rd within w if all the numbers were 7 digits long (i.e. if - // they had leading zeros) - // j: if > 0, the actual index of rd within w (if < 0, rd is a leading zero). - - // Get the length of the first word of the digits array xd. - for (digits = 1, k = xd[0]; k >= 10; k /= 10) digits++; - i = sd - digits; - - // Is the rounding digit in the first word of xd? - if (i < 0) { - i += LOG_BASE; - j = sd; - w = xd[xdi = 0]; + // Get the length of the first word of the digits array xd. + for (digits = 1, k = xd[0]; k >= 10; k /= 10) digits++; + i = sd - digits; - // Get the rounding digit at index j of w. - rd = w / mathpow(10, digits - j - 1) % 10 | 0; - } else { - xdi = Math.ceil((i + 1) / LOG_BASE); - k = xd.length; - if (xdi >= k) { - if (isTruncated) { - - // Needed by `naturalExponential`, `naturalLogarithm` and `squareRoot`. - for (; k++ <= xdi;) xd.push(0); - w = rd = 0; - digits = 1; - i %= LOG_BASE; - j = i - LOG_BASE + 1; - } else { - break out; - } + // Is the rounding digit in the first word of xd? + if (i < 0) { + i += LOG_BASE; + j = sd; + w = xd[xdi = 0]; + + // Get the rounding digit at index j of w. + rd = w / mathpow(10, digits - j - 1) % 10 | 0; + } else { + xdi = Math.ceil((i + 1) / LOG_BASE); + k = xd.length; + if (xdi >= k) { + if (isTruncated) { + + // Needed by `naturalExponential`, `naturalLogarithm` and `squareRoot`. + for (; k++ <= xdi;) xd.push(0); + w = rd = 0; + digits = 1; + i %= LOG_BASE; + j = i - LOG_BASE + 1; } else { - w = k = xd[xdi]; + break out; + } + } else { + w = k = xd[xdi]; - // Get the number of digits of w. - for (digits = 1; k >= 10; k /= 10) digits++; + // Get the number of digits of w. + for (digits = 1; k >= 10; k /= 10) digits++; - // Get the index of rd within w. - i %= LOG_BASE; + // Get the index of rd within w. + i %= LOG_BASE; - // Get the index of rd within w, adjusted for leading zeros. - // The number of leading zeros of w is given by LOG_BASE - digits. - j = i - LOG_BASE + digits; + // Get the index of rd within w, adjusted for leading zeros. + // The number of leading zeros of w is given by LOG_BASE - digits. + j = i - LOG_BASE + digits; - // Get the rounding digit at index j of w. - rd = j < 0 ? 0 : w / mathpow(10, digits - j - 1) % 10 | 0; - } + // Get the rounding digit at index j of w. + rd = j < 0 ? 0 : w / mathpow(10, digits - j - 1) % 10 | 0; } + } - // Are there any non-zero digits after the rounding digit? - isTruncated = isTruncated || sd < 0 || - xd[xdi + 1] !== void 0 || (j < 0 ? w : w % mathpow(10, digits - j - 1)); - - // The expression `w % mathpow(10, digits - j - 1)` returns all the digits of w to the right - // of the digit at (left-to-right) index j, e.g. if w is 908714 and j is 2, the expression - // will give 714. + // Are there any non-zero digits after the rounding digit? + isTruncated = isTruncated || sd < 0 || + xd[xdi + 1] !== void 0 || (j < 0 ? w : w % mathpow(10, digits - j - 1)); - roundUp = rm < 4 - ? (rd || isTruncated) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) - : rd > 5 || rd == 5 && (rm == 4 || isTruncated || rm == 6 && + // The expression `w % mathpow(10, digits - j - 1)` returns all the digits of w to the right + // of the digit at (left-to-right) index j, e.g. if w is 908714 and j is 2, the expression + // will give 714. - // Check whether the digit to the left of the rounding digit is odd. - ((i > 0 ? j > 0 ? w / mathpow(10, digits - j) : 0 : xd[xdi - 1]) % 10) & 1 || - rm == (x.s < 0 ? 8 : 7)); + roundUp = rm < 4 + ? (rd || isTruncated) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) + : rd > 5 || rd == 5 && (rm == 4 || isTruncated || rm == 6 && - if (sd < 1 || !xd[0]) { - xd.length = 0; - if (roundUp) { + // Check whether the digit to the left of the rounding digit is odd. + ((i > 0 ? j > 0 ? w / mathpow(10, digits - j) : 0 : xd[xdi - 1]) % 10) & 1 || + rm == (x.s < 0 ? 8 : 7)); - // Convert sd to decimal places. - sd -= x.e + 1; + if (sd < 1 || !xd[0]) { + xd.length = 0; + if (roundUp) { - // 1, 0.1, 0.01, 0.001, 0.0001 etc. - xd[0] = mathpow(10, (LOG_BASE - sd % LOG_BASE) % LOG_BASE); - x.e = -sd || 0; - } else { + // Convert sd to decimal places. + sd -= x.e + 1; - // Zero. - xd[0] = x.e = 0; - } + // 1, 0.1, 0.01, 0.001, 0.0001 etc. + xd[0] = mathpow(10, (LOG_BASE - sd % LOG_BASE) % LOG_BASE); + x.e = -sd || 0; + } else { - return x; + // Zero. + xd[0] = x.e = 0; } - // Remove excess digits. - if (i == 0) { - xd.length = xdi; - k = 1; - xdi--; - } else { - xd.length = xdi + 1; - k = mathpow(10, LOG_BASE - i); + return x; + } - // E.g. 56700 becomes 56000 if 7 is the rounding digit. - // j > 0 means i > number of leading zeros of w. - xd[xdi] = j > 0 ? (w / mathpow(10, digits - j) % mathpow(10, j) | 0) * k : 0; - } + // Remove excess digits. + if (i == 0) { + xd.length = xdi; + k = 1; + xdi--; + } else { + xd.length = xdi + 1; + k = mathpow(10, LOG_BASE - i); - if (roundUp) { - for (;;) { + // E.g. 56700 becomes 56000 if 7 is the rounding digit. + // j > 0 means i > number of leading zeros of w. + xd[xdi] = j > 0 ? (w / mathpow(10, digits - j) % mathpow(10, j) | 0) * k : 0; + } - // Is the digit to be rounded up in the first word of xd? - if (xdi == 0) { + if (roundUp) { + for (;;) { - // i will be the length of xd[0] before k is added. - for (i = 1, j = xd[0]; j >= 10; j /= 10) i++; - j = xd[0] += k; - for (k = 1; j >= 10; j /= 10) k++; + // Is the digit to be rounded up in the first word of xd? + if (xdi == 0) { - // if i != k the length has increased. - if (i != k) { - x.e++; - if (xd[0] == BASE) xd[0] = 1; - } + // i will be the length of xd[0] before k is added. + for (i = 1, j = xd[0]; j >= 10; j /= 10) i++; + j = xd[0] += k; + for (k = 1; j >= 10; j /= 10) k++; - break; - } else { - xd[xdi] += k; - if (xd[xdi] != BASE) break; - xd[xdi--] = 0; - k = 1; + // if i != k the length has increased. + if (i != k) { + x.e++; + if (xd[0] == BASE) xd[0] = 1; } + + break; + } else { + xd[xdi] += k; + if (xd[xdi] != BASE) break; + xd[xdi--] = 0; + k = 1; } } - - // Remove trailing zeros. - for (i = xd.length; xd[--i] === 0;) xd.pop(); } - if (external) { + // Remove trailing zeros. + for (i = xd.length; xd[--i] === 0;) xd.pop(); + } - // Overflow? - if (x.e > Ctor.maxE) { + if (external) { - // Infinity. - x.d = null; - x.e = NaN; + // Overflow? + if (x.e > Ctor.maxE) { - // Underflow? - } else if (x.e < Ctor.minE) { + // Infinity. + x.d = null; + x.e = NaN; - // Zero. - x.e = 0; - x.d = [0]; - // Ctor.underflow = true; - } // else Ctor.underflow = false; - } + // Underflow? + } else if (x.e < Ctor.minE) { - return x; + // Zero. + x.e = 0; + x.d = [0]; + // Ctor.underflow = true; + } // else Ctor.underflow = false; } + return x; +} - function finiteToString(x, isExp, sd) { - if (!x.isFinite()) return nonFiniteToString(x); - var k, - e = x.e, - str = digitsToString(x.d), - len = str.length; - if (isExp) { - if (sd && (k = sd - len) > 0) { - str = str.charAt(0) + '.' + str.slice(1) + getZeroString(k); - } else if (len > 1) { - str = str.charAt(0) + '.' + str.slice(1); - } +function finiteToString(x, isExp, sd) { + if (!x.isFinite()) return nonFiniteToString(x); + var k, + e = x.e, + str = digitsToString(x.d), + len = str.length; - str = str + (x.e < 0 ? 'e' : 'e+') + x.e; - } else if (e < 0) { - str = '0.' + getZeroString(-e - 1) + str; - if (sd && (k = sd - len) > 0) str += getZeroString(k); - } else if (e >= len) { - str += getZeroString(e + 1 - len); - if (sd && (k = sd - e - 1) > 0) str = str + '.' + getZeroString(k); - } else { - if ((k = e + 1) < len) str = str.slice(0, k) + '.' + str.slice(k); - if (sd && (k = sd - len) > 0) { - if (e + 1 === len) str += '.'; - str += getZeroString(k); - } + if (isExp) { + if (sd && (k = sd - len) > 0) { + str = str.charAt(0) + '.' + str.slice(1) + getZeroString(k); + } else if (len > 1) { + str = str.charAt(0) + '.' + str.slice(1); } - return str; + str = str + (x.e < 0 ? 'e' : 'e+') + x.e; + } else if (e < 0) { + str = '0.' + getZeroString(-e - 1) + str; + if (sd && (k = sd - len) > 0) str += getZeroString(k); + } else if (e >= len) { + str += getZeroString(e + 1 - len); + if (sd && (k = sd - e - 1) > 0) str = str + '.' + getZeroString(k); + } else { + if ((k = e + 1) < len) str = str.slice(0, k) + '.' + str.slice(k); + if (sd && (k = sd - len) > 0) { + if (e + 1 === len) str += '.'; + str += getZeroString(k); + } } + return str; +} - // Calculate the base 10 exponent from the base 1e7 exponent. - function getBase10Exponent(digits, e) { - var w = digits[0]; - - // Add the number of digits of the first word of the digits array. - for ( e *= LOG_BASE; w >= 10; w /= 10) e++; - return e; - } +// Calculate the base 10 exponent from the base 1e7 exponent. +function getBase10Exponent(digits, e) { + var w = digits[0]; - function getLn10(Ctor, sd, pr) { - if (sd > LN10_PRECISION) { + // Add the number of digits of the first word of the digits array. + for ( e *= LOG_BASE; w >= 10; w /= 10) e++; + return e; +} - // Reset global state in case the exception is caught. - external = true; - if (pr) Ctor.precision = pr; - throw Error(precisionLimitExceeded); - } - return finalise(new Ctor(LN10), sd, 1, true); - } +function getLn10(Ctor, sd, pr) { + if (sd > LN10_PRECISION) { - function getPi(Ctor, sd, rm) { - if (sd > PI_PRECISION) throw Error(precisionLimitExceeded); - return finalise(new Ctor(PI), sd, rm, true); + // Reset global state in case the exception is caught. + external = true; + if (pr) Ctor.precision = pr; + throw Error(precisionLimitExceeded); } + return finalise(new Ctor(LN10), sd, 1, true); +} - function getPrecision(digits) { - var w = digits.length - 1, - len = w * LOG_BASE + 1; - - w = digits[w]; +function getPi(Ctor, sd, rm) { + if (sd > PI_PRECISION) throw Error(precisionLimitExceeded); + return finalise(new Ctor(PI), sd, rm, true); +} - // If non-zero... - if (w) { - // Subtract the number of trailing zeros of the last word. - for (; w % 10 == 0; w /= 10) len--; +function getPrecision(digits) { + var w = digits.length - 1, + len = w * LOG_BASE + 1; - // Add the number of digits of the first word. - for (w = digits[0]; w >= 10; w /= 10) len++; - } + w = digits[w]; - return len; - } + // If non-zero... + if (w) { + // Subtract the number of trailing zeros of the last word. + for (; w % 10 == 0; w /= 10) len--; - function getZeroString(k) { - var zs = ''; - for (; k--;) zs += '0'; - return zs; + // Add the number of digits of the first word. + for (w = digits[0]; w >= 10; w /= 10) len++; } + return len; +} - /* - * Return a new Decimal whose value is the value of Decimal `x` to the power `n`, where `n` is an - * integer of type number. - * - * Implements 'exponentiation by squaring'. Called by `pow` and `parseOther`. - * - */ - function intPow(Ctor, x, n, pr) { - var isTruncated, - r = new Ctor(1), - // Max n of 9007199254740991 takes 53 loop iterations. - // Maximum digits array length; leaves [28, 34] guard digits. - k = Math.ceil(pr / LOG_BASE + 4); +function getZeroString(k) { + var zs = ''; + for (; k--;) zs += '0'; + return zs; +} - external = false; - for (;;) { - if (n % 2) { - r = r.times(x); - if (truncate(r.d, k)) isTruncated = true; - } +/* + * Return a new Decimal whose value is the value of Decimal `x` to the power `n`, where `n` is an + * integer of type number. + * + * Implements 'exponentiation by squaring'. Called by `pow` and `parseOther`. + * + */ +function intPow(Ctor, x, n, pr) { + var isTruncated, + r = new Ctor(1), - n = mathfloor(n / 2); - if (n === 0) { + // Max n of 9007199254740991 takes 53 loop iterations. + // Maximum digits array length; leaves [28, 34] guard digits. + k = Math.ceil(pr / LOG_BASE + 4); - // To ensure correct rounding when r.d is truncated, increment the last word if it is zero. - n = r.d.length - 1; - if (isTruncated && r.d[n] === 0) ++r.d[n]; - break; - } + external = false; - x = x.times(x); - truncate(x.d, k); + for (;;) { + if (n % 2) { + r = r.times(x); + if (truncate(r.d, k)) isTruncated = true; } - external = true; - - return r; - } + n = mathfloor(n / 2); + if (n === 0) { + // To ensure correct rounding when r.d is truncated, increment the last word if it is zero. + n = r.d.length - 1; + if (isTruncated && r.d[n] === 0) ++r.d[n]; + break; + } - function isOdd(n) { - return n.d[n.d.length - 1] & 1; + x = x.times(x); + truncate(x.d, k); } + external = true; - /* - * Handle `max` and `min`. `ltgt` is 'lt' or 'gt'. - */ - function maxOrMin(Ctor, args, ltgt) { - var y, - x = new Ctor(args[0]), - i = 0; - - for (; ++i < args.length;) { - y = new Ctor(args[i]); - if (!y.s) { - x = y; - break; - } else if (x[ltgt](y)) { - x = y; - } - } + return r; +} - return x; - } +function isOdd(n) { + return n.d[n.d.length - 1] & 1; +} - /* - * Return a new Decimal whose value is the natural exponential of `x` rounded to `sd` significant - * digits. - * - * Taylor/Maclaurin series. - * - * exp(x) = x^0/0! + x^1/1! + x^2/2! + x^3/3! + ... - * - * Argument reduction: - * Repeat x = x / 32, k += 5, until |x| < 0.1 - * exp(x) = exp(x / 2^k)^(2^k) - * - * Previously, the argument was initially reduced by - * exp(x) = exp(r) * 10^k where r = x - k * ln10, k = floor(x / ln10) - * to first put r in the range [0, ln10], before dividing by 32 until |x| < 0.1, but this was - * found to be slower than just dividing repeatedly by 32 as above. - * - * Max integer argument: exp('20723265836946413') = 6.3e+9000000000000000 - * Min integer argument: exp('-20723265836946411') = 1.2e-9000000000000000 - * (Math object integer min/max: Math.exp(709) = 8.2e+307, Math.exp(-745) = 5e-324) - * - * exp(Infinity) = Infinity - * exp(-Infinity) = 0 - * exp(NaN) = NaN - * exp(±0) = 1 - * - * exp(x) is non-terminating for any finite, non-zero x. - * - * The result will always be correctly rounded. - * - */ - function naturalExponential(x, sd) { - var denominator, guard, j, pow, sum, t, wpr, - rep = 0, - i = 0, - k = 0, - Ctor = x.constructor, - rm = Ctor.rounding, - pr = Ctor.precision; - // 0/NaN/Infinity? - if (!x.d || !x.d[0] || x.e > 17) { +/* + * Handle `max` and `min`. `ltgt` is 'lt' or 'gt'. + */ +function maxOrMin(Ctor, args, ltgt) { + var y, + x = new Ctor(args[0]), + i = 0; - return new Ctor(x.d - ? !x.d[0] ? 1 : x.s < 0 ? 0 : 1 / 0 - : x.s ? x.s < 0 ? 0 : x : 0 / 0); + for (; ++i < args.length;) { + y = new Ctor(args[i]); + if (!y.s) { + x = y; + break; + } else if (x[ltgt](y)) { + x = y; } + } - if (sd == null) { - external = false; - wpr = pr; - } else { - wpr = sd; - } + return x; +} + + +/* + * Return a new Decimal whose value is the natural exponential of `x` rounded to `sd` significant + * digits. + * + * Taylor/Maclaurin series. + * + * exp(x) = x^0/0! + x^1/1! + x^2/2! + x^3/3! + ... + * + * Argument reduction: + * Repeat x = x / 32, k += 5, until |x| < 0.1 + * exp(x) = exp(x / 2^k)^(2^k) + * + * Previously, the argument was initially reduced by + * exp(x) = exp(r) * 10^k where r = x - k * ln10, k = floor(x / ln10) + * to first put r in the range [0, ln10], before dividing by 32 until |x| < 0.1, but this was + * found to be slower than just dividing repeatedly by 32 as above. + * + * Max integer argument: exp('20723265836946413') = 6.3e+9000000000000000 + * Min integer argument: exp('-20723265836946411') = 1.2e-9000000000000000 + * (Math object integer min/max: Math.exp(709) = 8.2e+307, Math.exp(-745) = 5e-324) + * + * exp(Infinity) = Infinity + * exp(-Infinity) = 0 + * exp(NaN) = NaN + * exp(±0) = 1 + * + * exp(x) is non-terminating for any finite, non-zero x. + * + * The result will always be correctly rounded. + * + */ +function naturalExponential(x, sd) { + var denominator, guard, j, pow, sum, t, wpr, + rep = 0, + i = 0, + k = 0, + Ctor = x.constructor, + rm = Ctor.rounding, + pr = Ctor.precision; - t = new Ctor(0.03125); + // 0/NaN/Infinity? + if (!x.d || !x.d[0] || x.e > 17) { - // while abs(x) >= 0.1 - while (x.e > -2) { + return new Ctor(x.d + ? !x.d[0] ? 1 : x.s < 0 ? 0 : 1 / 0 + : x.s ? x.s < 0 ? 0 : x : 0 / 0); + } - // x = x / 2^5 - x = x.times(t); - k += 5; - } + if (sd == null) { + external = false; + wpr = pr; + } else { + wpr = sd; + } - // Use 2 * log10(2^k) + 5 (empirically derived) to estimate the increase in precision - // necessary to ensure the first 4 rounding digits are correct. - guard = Math.log(mathpow(2, k)) / Math.LN10 * 2 + 5 | 0; - wpr += guard; - denominator = pow = sum = new Ctor(1); - Ctor.precision = wpr; + t = new Ctor(0.03125); - for (;;) { - pow = finalise(pow.times(x), wpr, 1); - denominator = denominator.times(++i); - t = sum.plus(divide(pow, denominator, wpr, 1)); + // while abs(x) >= 0.1 + while (x.e > -2) { - if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { - j = k; - while (j--) sum = finalise(sum.times(sum), wpr, 1); + // x = x / 2^5 + x = x.times(t); + k += 5; + } - // Check to see if the first 4 rounding digits are [49]999. - // If so, repeat the summation with a higher precision, otherwise - // e.g. with precision: 18, rounding: 1 - // exp(18.404272462595034083567793919843761) = 98372560.1229999999 (should be 98372560.123) - // `wpr - guard` is the index of first rounding digit. - if (sd == null) { + // Use 2 * log10(2^k) + 5 (empirically derived) to estimate the increase in precision + // necessary to ensure the first 4 rounding digits are correct. + guard = Math.log(mathpow(2, k)) / Math.LN10 * 2 + 5 | 0; + wpr += guard; + denominator = pow = sum = new Ctor(1); + Ctor.precision = wpr; - if (rep < 3 && checkRoundingDigits(sum.d, wpr - guard, rm, rep)) { - Ctor.precision = wpr += 10; - denominator = pow = t = new Ctor(1); - i = 0; - rep++; - } else { - return finalise(sum, Ctor.precision = pr, rm, external = true); - } + for (;;) { + pow = finalise(pow.times(x), wpr, 1); + denominator = denominator.times(++i); + t = sum.plus(divide(pow, denominator, wpr, 1)); + + if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { + j = k; + while (j--) sum = finalise(sum.times(sum), wpr, 1); + + // Check to see if the first 4 rounding digits are [49]999. + // If so, repeat the summation with a higher precision, otherwise + // e.g. with precision: 18, rounding: 1 + // exp(18.404272462595034083567793919843761) = 98372560.1229999999 (should be 98372560.123) + // `wpr - guard` is the index of first rounding digit. + if (sd == null) { + + if (rep < 3 && checkRoundingDigits(sum.d, wpr - guard, rm, rep)) { + Ctor.precision = wpr += 10; + denominator = pow = t = new Ctor(1); + i = 0; + rep++; } else { - Ctor.precision = pr; - return sum; + return finalise(sum, Ctor.precision = pr, rm, external = true); } + } else { + Ctor.precision = pr; + return sum; } - - sum = t; } + + sum = t; } +} - /* - * Return a new Decimal whose value is the natural logarithm of `x` rounded to `sd` significant - * digits. - * - * ln(-n) = NaN - * ln(0) = -Infinity - * ln(-0) = -Infinity - * ln(1) = 0 - * ln(Infinity) = Infinity - * ln(-Infinity) = NaN - * ln(NaN) = NaN - * - * ln(n) (n != 1) is non-terminating. - * - */ - function naturalLogarithm(y, sd) { - var c, c0, denominator, e, numerator, rep, sum, t, wpr, x1, x2, - n = 1, - guard = 10, - x = y, - xd = x.d, - Ctor = x.constructor, - rm = Ctor.rounding, - pr = Ctor.precision; +/* + * Return a new Decimal whose value is the natural logarithm of `x` rounded to `sd` significant + * digits. + * + * ln(-n) = NaN + * ln(0) = -Infinity + * ln(-0) = -Infinity + * ln(1) = 0 + * ln(Infinity) = Infinity + * ln(-Infinity) = NaN + * ln(NaN) = NaN + * + * ln(n) (n != 1) is non-terminating. + * + */ +function naturalLogarithm(y, sd) { + var c, c0, denominator, e, numerator, rep, sum, t, wpr, x1, x2, + n = 1, + guard = 10, + x = y, + xd = x.d, + Ctor = x.constructor, + rm = Ctor.rounding, + pr = Ctor.precision; + + // Is x negative or Infinity, NaN, 0 or 1? + if (x.s < 0 || !xd || !xd[0] || !x.e && xd[0] == 1 && xd.length == 1) { + return new Ctor(xd && !xd[0] ? -1 / 0 : x.s != 1 ? NaN : xd ? 0 : x); + } + + if (sd == null) { + external = false; + wpr = pr; + } else { + wpr = sd; + } + + Ctor.precision = wpr += guard; + c = digitsToString(xd); + c0 = c.charAt(0); - // Is x negative or Infinity, NaN, 0 or 1? - if (x.s < 0 || !xd || !xd[0] || !x.e && xd[0] == 1 && xd.length == 1) { - return new Ctor(xd && !xd[0] ? -1 / 0 : x.s != 1 ? NaN : xd ? 0 : x); + if (Math.abs(e = x.e) < 1.5e15) { + + // Argument reduction. + // The series converges faster the closer the argument is to 1, so using + // ln(a^b) = b * ln(a), ln(a) = ln(a^b) / b + // multiply the argument by itself until the leading digits of the significand are 7, 8, 9, + // 10, 11, 12 or 13, recording the number of multiplications so the sum of the series can + // later be divided by this number, then separate out the power of 10 using + // ln(a*10^b) = ln(a) + b*ln(10). + + // max n is 21 (gives 0.9, 1.0 or 1.1) (9e15 / 21 = 4.2e14). + //while (c0 < 9 && c0 != 1 || c0 == 1 && c.charAt(1) > 1) { + // max n is 6 (gives 0.7 - 1.3) + while (c0 < 7 && c0 != 1 || c0 == 1 && c.charAt(1) > 3) { + x = x.times(y); + c = digitsToString(x.d); + c0 = c.charAt(0); + n++; } - if (sd == null) { - external = false; - wpr = pr; + e = x.e; + + if (c0 > 1) { + x = new Ctor('0.' + c); + e++; } else { - wpr = sd; - } - - Ctor.precision = wpr += guard; - c = digitsToString(xd); - c0 = c.charAt(0); - - if (Math.abs(e = x.e) < 1.5e15) { - - // Argument reduction. - // The series converges faster the closer the argument is to 1, so using - // ln(a^b) = b * ln(a), ln(a) = ln(a^b) / b - // multiply the argument by itself until the leading digits of the significand are 7, 8, 9, - // 10, 11, 12 or 13, recording the number of multiplications so the sum of the series can - // later be divided by this number, then separate out the power of 10 using - // ln(a*10^b) = ln(a) + b*ln(10). - - // max n is 21 (gives 0.9, 1.0 or 1.1) (9e15 / 21 = 4.2e14). - //while (c0 < 9 && c0 != 1 || c0 == 1 && c.charAt(1) > 1) { - // max n is 6 (gives 0.7 - 1.3) - while (c0 < 7 && c0 != 1 || c0 == 1 && c.charAt(1) > 3) { - x = x.times(y); - c = digitsToString(x.d); - c0 = c.charAt(0); - n++; - } + x = new Ctor(c0 + '.' + c.slice(1)); + } + } else { - e = x.e; + // The argument reduction method above may result in overflow if the argument y is a massive + // number with exponent >= 1500000000000000 (9e15 / 6 = 1.5e15), so instead recall this + // function using ln(x*10^e) = ln(x) + e*ln(10). + t = getLn10(Ctor, wpr + 2, pr).times(e + ''); + x = naturalLogarithm(new Ctor(c0 + '.' + c.slice(1)), wpr - guard).plus(t); + Ctor.precision = pr; - if (c0 > 1) { - x = new Ctor('0.' + c); - e++; - } else { - x = new Ctor(c0 + '.' + c.slice(1)); - } - } else { + return sd == null ? finalise(x, pr, rm, external = true) : x; + } - // The argument reduction method above may result in overflow if the argument y is a massive - // number with exponent >= 1500000000000000 (9e15 / 6 = 1.5e15), so instead recall this - // function using ln(x*10^e) = ln(x) + e*ln(10). - t = getLn10(Ctor, wpr + 2, pr).times(e + ''); - x = naturalLogarithm(new Ctor(c0 + '.' + c.slice(1)), wpr - guard).plus(t); - Ctor.precision = pr; - - return sd == null ? finalise(x, pr, rm, external = true) : x; - } - - // x1 is x reduced to a value near 1. - x1 = x; - - // Taylor series. - // ln(y) = ln((1 + x)/(1 - x)) = 2(x + x^3/3 + x^5/5 + x^7/7 + ...) - // where x = (y - 1)/(y + 1) (|x| < 1) - sum = numerator = x = divide(x.minus(1), x.plus(1), wpr, 1); - x2 = finalise(x.times(x), wpr, 1); - denominator = 3; - - for (;;) { - numerator = finalise(numerator.times(x2), wpr, 1); - t = sum.plus(divide(numerator, new Ctor(denominator), wpr, 1)); - - if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { - sum = sum.times(2); - - // Reverse the argument reduction. Check that e is not 0 because, besides preventing an - // unnecessary calculation, -0 + 0 = +0 and to ensure correct rounding -0 needs to stay -0. - if (e !== 0) sum = sum.plus(getLn10(Ctor, wpr + 2, pr).times(e + '')); - sum = divide(sum, new Ctor(n), wpr, 1); - - // Is rm > 3 and the first 4 rounding digits 4999, or rm < 4 (or the summation has - // been repeated previously) and the first 4 rounding digits 9999? - // If so, restart the summation with a higher precision, otherwise - // e.g. with precision: 12, rounding: 1 - // ln(135520028.6126091714265381533) = 18.7246299999 when it should be 18.72463. - // `wpr - guard` is the index of first rounding digit. - if (sd == null) { - if (checkRoundingDigits(sum.d, wpr - guard, rm, rep)) { - Ctor.precision = wpr += guard; - t = numerator = x = divide(x1.minus(1), x1.plus(1), wpr, 1); - x2 = finalise(x.times(x), wpr, 1); - denominator = rep = 1; - } else { - return finalise(sum, Ctor.precision = pr, rm, external = true); - } + // x1 is x reduced to a value near 1. + x1 = x; + + // Taylor series. + // ln(y) = ln((1 + x)/(1 - x)) = 2(x + x^3/3 + x^5/5 + x^7/7 + ...) + // where x = (y - 1)/(y + 1) (|x| < 1) + sum = numerator = x = divide(x.minus(1), x.plus(1), wpr, 1); + x2 = finalise(x.times(x), wpr, 1); + denominator = 3; + + for (;;) { + numerator = finalise(numerator.times(x2), wpr, 1); + t = sum.plus(divide(numerator, new Ctor(denominator), wpr, 1)); + + if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { + sum = sum.times(2); + + // Reverse the argument reduction. Check that e is not 0 because, besides preventing an + // unnecessary calculation, -0 + 0 = +0 and to ensure correct rounding -0 needs to stay -0. + if (e !== 0) sum = sum.plus(getLn10(Ctor, wpr + 2, pr).times(e + '')); + sum = divide(sum, new Ctor(n), wpr, 1); + + // Is rm > 3 and the first 4 rounding digits 4999, or rm < 4 (or the summation has + // been repeated previously) and the first 4 rounding digits 9999? + // If so, restart the summation with a higher precision, otherwise + // e.g. with precision: 12, rounding: 1 + // ln(135520028.6126091714265381533) = 18.7246299999 when it should be 18.72463. + // `wpr - guard` is the index of first rounding digit. + if (sd == null) { + if (checkRoundingDigits(sum.d, wpr - guard, rm, rep)) { + Ctor.precision = wpr += guard; + t = numerator = x = divide(x1.minus(1), x1.plus(1), wpr, 1); + x2 = finalise(x.times(x), wpr, 1); + denominator = rep = 1; } else { - Ctor.precision = pr; - return sum; + return finalise(sum, Ctor.precision = pr, rm, external = true); } + } else { + Ctor.precision = pr; + return sum; } - - sum = t; - denominator += 2; } + + sum = t; + denominator += 2; } +} + + +// ±Infinity, NaN. +function nonFiniteToString(x) { + // Unsigned. + return String(x.s * x.s / 0); +} - // ±Infinity, NaN. - function nonFiniteToString(x) { - // Unsigned. - return String(x.s * x.s / 0); +/* + * Parse the value of a new Decimal `x` from string `str`. + */ +function parseDecimal(x, str) { + var e, i, len; + + // Decimal point? + if ((e = str.indexOf('.')) > -1) str = str.replace('.', ''); + + // Exponential form? + if ((i = str.search(/e/i)) > 0) { + + // Determine exponent. + if (e < 0) e = i; + e += +str.slice(i + 1); + str = str.substring(0, i); + } else if (e < 0) { + + // Integer. + e = str.length; } + // Determine leading zeros. + for (i = 0; str.charCodeAt(i) === 48; i++); - /* - * Parse the value of a new Decimal `x` from string `str`. - */ - function parseDecimal(x, str) { - var e, i, len; + // Determine trailing zeros. + for (len = str.length; str.charCodeAt(len - 1) === 48; --len); + str = str.slice(i, len); - // Decimal point? - if ((e = str.indexOf('.')) > -1) str = str.replace('.', ''); + if (str) { + len -= i; + x.e = e = e - i - 1; + x.d = []; - // Exponential form? - if ((i = str.search(/e/i)) > 0) { + // Transform base - // Determine exponent. - if (e < 0) e = i; - e += +str.slice(i + 1); - str = str.substring(0, i); - } else if (e < 0) { + // e is the base 10 exponent. + // i is where to slice str to get the first word of the digits array. + i = (e + 1) % LOG_BASE; + if (e < 0) i += LOG_BASE; - // Integer. - e = str.length; + if (i < len) { + if (i) x.d.push(+str.slice(0, i)); + for (len -= LOG_BASE; i < len;) x.d.push(+str.slice(i, i += LOG_BASE)); + str = str.slice(i); + i = LOG_BASE - str.length; + } else { + i -= len; } - // Determine leading zeros. - for (i = 0; str.charCodeAt(i) === 48; i++); + for (; i--;) str += '0'; + x.d.push(+str); - // Determine trailing zeros. - for (len = str.length; str.charCodeAt(len - 1) === 48; --len); - str = str.slice(i, len); + if (external) { - if (str) { - len -= i; - x.e = e = e - i - 1; - x.d = []; + // Overflow? + if (x.e > x.constructor.maxE) { - // Transform base + // Infinity. + x.d = null; + x.e = NaN; - // e is the base 10 exponent. - // i is where to slice str to get the first word of the digits array. - i = (e + 1) % LOG_BASE; - if (e < 0) i += LOG_BASE; + // Underflow? + } else if (x.e < x.constructor.minE) { - if (i < len) { - if (i) x.d.push(+str.slice(0, i)); - for (len -= LOG_BASE; i < len;) x.d.push(+str.slice(i, i += LOG_BASE)); - str = str.slice(i); - i = LOG_BASE - str.length; - } else { - i -= len; - } + // Zero. + x.e = 0; + x.d = [0]; + // x.constructor.underflow = true; + } // else x.constructor.underflow = false; + } + } else { - for (; i--;) str += '0'; - x.d.push(+str); + // Zero. + x.e = 0; + x.d = [0]; + } - if (external) { + return x; +} - // Overflow? - if (x.e > x.constructor.maxE) { - // Infinity. - x.d = null; - x.e = NaN; +/* + * Parse the value of a new Decimal `x` from a string `str`, which is not a decimal value. + */ +function parseOther(x, str) { + var base, Ctor, divisor, i, isFloat, len, p, xd, xe; - // Underflow? - } else if (x.e < x.constructor.minE) { + if (str === 'Infinity' || str === 'NaN') { + if (!+str) x.s = NaN; + x.e = NaN; + x.d = null; + return x; + } - // Zero. - x.e = 0; - x.d = [0]; - // x.constructor.underflow = true; - } // else x.constructor.underflow = false; - } - } else { + if (isHex.test(str)) { + base = 16; + str = str.toLowerCase(); + } else if (isBinary.test(str)) { + base = 2; + } else if (isOctal.test(str)) { + base = 8; + } else { + throw Error(invalidArgument + str); + } - // Zero. - x.e = 0; - x.d = [0]; - } + // Is there a binary exponent part? + i = str.search(/p/i); - return x; + if (i > 0) { + p = +str.slice(i + 1); + str = str.substring(2, i); + } else { + str = str.slice(2); } + // Convert `str` as an integer then divide the result by `base` raised to a power such that the + // fraction part will be restored. + i = str.indexOf('.'); + isFloat = i >= 0; + Ctor = x.constructor; - /* - * Parse the value of a new Decimal `x` from a string `str`, which is not a decimal value. - */ - function parseOther(x, str) { - var base, Ctor, divisor, i, isFloat, len, p, xd, xe; + if (isFloat) { + str = str.replace('.', ''); + len = str.length; + i = len - i; - if (str === 'Infinity' || str === 'NaN') { - if (!+str) x.s = NaN; - x.e = NaN; - x.d = null; - return x; - } + // log[10](16) = 1.2041... , log[10](88) = 1.9444.... + divisor = intPow(Ctor, new Ctor(base), i, i * 2); + } - if (isHex.test(str)) { - base = 16; - str = str.toLowerCase(); - } else if (isBinary.test(str)) { - base = 2; - } else if (isOctal.test(str)) { - base = 8; - } else { - throw Error(invalidArgument + str); - } + xd = convertBase(str, base, BASE); + xe = xd.length - 1; - // Is there a binary exponent part? - i = str.search(/p/i); + // Remove trailing zeros. + for (i = xe; xd[i] === 0; --i) xd.pop(); + if (i < 0) return new Ctor(x.s * 0); + x.e = getBase10Exponent(xd, xe); + x.d = xd; + external = false; - if (i > 0) { - p = +str.slice(i + 1); - str = str.substring(2, i); - } else { - str = str.slice(2); - } + // At what precision to perform the division to ensure exact conversion? + // maxDecimalIntegerPartDigitCount = ceil(log[10](b) * otherBaseIntegerPartDigitCount) + // log[10](2) = 0.30103, log[10](8) = 0.90309, log[10](16) = 1.20412 + // E.g. ceil(1.2 * 3) = 4, so up to 4 decimal digits are needed to represent 3 hex int digits. + // maxDecimalFractionPartDigitCount = {Hex:4|Oct:3|Bin:1} * otherBaseFractionPartDigitCount + // Therefore using 4 * the number of digits of str will always be enough. + if (isFloat) x = divide(x, divisor, len * 4); - // Convert `str` as an integer then divide the result by `base` raised to a power such that the - // fraction part will be restored. - i = str.indexOf('.'); - isFloat = i >= 0; - Ctor = x.constructor; + // Multiply by the binary exponent part if present. + if (p) x = x.times(Math.abs(p) < 54 ? Math.pow(2, p) : Decimal.pow(2, p)); + external = true; - if (isFloat) { - str = str.replace('.', ''); - len = str.length; - i = len - i; + return x; +} - // log[10](16) = 1.2041... , log[10](88) = 1.9444.... - divisor = intPow(Ctor, new Ctor(base), i, i * 2); - } - xd = convertBase(str, base, BASE); - xe = xd.length - 1; +/* + * sin(x) = x - x^3/3! + x^5/5! - ... + * |x| < pi/2 + * + */ +function sine(Ctor, x) { + var k, + len = x.d.length; - // Remove trailing zeros. - for (i = xe; xd[i] === 0; --i) xd.pop(); - if (i < 0) return new Ctor(x.s * 0); - x.e = getBase10Exponent(xd, xe); - x.d = xd; - external = false; + if (len < 3) return taylorSeries(Ctor, 2, x, x); - // At what precision to perform the division to ensure exact conversion? - // maxDecimalIntegerPartDigitCount = ceil(log[10](b) * otherBaseIntegerPartDigitCount) - // log[10](2) = 0.30103, log[10](8) = 0.90309, log[10](16) = 1.20412 - // E.g. ceil(1.2 * 3) = 4, so up to 4 decimal digits are needed to represent 3 hex int digits. - // maxDecimalFractionPartDigitCount = {Hex:4|Oct:3|Bin:1} * otherBaseFractionPartDigitCount - // Therefore using 4 * the number of digits of str will always be enough. - if (isFloat) x = divide(x, divisor, len * 4); + // Argument reduction: sin(5x) = 16*sin^5(x) - 20*sin^3(x) + 5*sin(x) + // i.e. sin(x) = 16*sin^5(x/5) - 20*sin^3(x/5) + 5*sin(x/5) + // and sin(x) = sin(x/5)(5 + sin^2(x/5)(16sin^2(x/5) - 20)) - // Multiply by the binary exponent part if present. - if (p) x = x.times(Math.abs(p) < 54 ? Math.pow(2, p) : Decimal.pow(2, p)); - external = true; + // Estimate the optimum number of times to use the argument reduction. + k = 1.4 * Math.sqrt(len); + k = k > 16 ? 16 : k | 0; - return x; - } + // Max k before Math.pow precision loss is 22 + x = x.times(Math.pow(5, -k)); + x = taylorSeries(Ctor, 2, x, x); + // Reverse argument reduction + var sin2_x, + d5 = new Ctor(5), + d16 = new Ctor(16), + d20 = new Ctor(20); + for (; k--;) { + sin2_x = x.times(x); + x = x.times(d5.plus(sin2_x.times(d16.times(sin2_x).minus(d20)))); + } - /* - * sin(x) = x - x^3/3! + x^5/5! - ... - * |x| < pi/2 - * - */ - function sine(Ctor, x) { - var k, - len = x.d.length; + return x; +} - if (len < 3) return taylorSeries(Ctor, 2, x, x); - // Argument reduction: sin(5x) = 16*sin^5(x) - 20*sin^3(x) + 5*sin(x) - // i.e. sin(x) = 16*sin^5(x/5) - 20*sin^3(x/5) + 5*sin(x/5) - // and sin(x) = sin(x/5)(5 + sin^2(x/5)(16sin^2(x/5) - 20)) +// Calculate Taylor series for `cos`, `cosh`, `sin` and `sinh`. +function taylorSeries(Ctor, n, x, y, isHyperbolic) { + var j, t, u, x2, + i = 1, + pr = Ctor.precision, + k = Math.ceil(pr / LOG_BASE); - // Estimate the optimum number of times to use the argument reduction. - k = 1.4 * Math.sqrt(len); - k = k > 16 ? 16 : k | 0; + external = false; + x2 = x.times(x); + u = new Ctor(y); - // Max k before Math.pow precision loss is 22 - x = x.times(Math.pow(5, -k)); - x = taylorSeries(Ctor, 2, x, x); + for (;;) { + t = divide(u.times(x2), new Ctor(n++ * n++), pr, 1); + u = isHyperbolic ? y.plus(t) : y.minus(t); + y = divide(t.times(x2), new Ctor(n++ * n++), pr, 1); + t = u.plus(y); - // Reverse argument reduction - var sin2_x, - d5 = new Ctor(5), - d16 = new Ctor(16), - d20 = new Ctor(20); - for (; k--;) { - sin2_x = x.times(x); - x = x.times(d5.plus(sin2_x.times(d16.times(sin2_x).minus(d20)))); + if (t.d[k] !== void 0) { + for (j = k; t.d[j] === u.d[j] && j--;); + if (j == -1) break; } - return x; + j = u; + u = y; + y = t; + t = j; + i++; } + external = true; + t.d.length = k + 1; - // Calculate Taylor series for `cos`, `cosh`, `sin` and `sinh`. - function taylorSeries(Ctor, n, x, y, isHyperbolic) { - var j, t, u, x2, - i = 1, - pr = Ctor.precision, - k = Math.ceil(pr / LOG_BASE); + return t; +} - external = false; - x2 = x.times(x); - u = new Ctor(y); - - for (;;) { - t = divide(u.times(x2), new Ctor(n++ * n++), pr, 1); - u = isHyperbolic ? y.plus(t) : y.minus(t); - y = divide(t.times(x2), new Ctor(n++ * n++), pr, 1); - t = u.plus(y); - - if (t.d[k] !== void 0) { - for (j = k; t.d[j] === u.d[j] && j--;); - if (j == -1) break; - } - j = u; - u = y; - y = t; - t = j; - i++; - } +// Return the absolute value of `x` reduced to less than or equal to half pi. +function toLessThanHalfPi(Ctor, x) { + var t, + isNeg = x.s < 0, + pi = getPi(Ctor, Ctor.precision, 1), + halfPi = pi.times(0.5); - external = true; - t.d.length = k + 1; + x = x.abs(); - return t; + if (x.lte(halfPi)) { + quadrant = isNeg ? 4 : 1; + return x; } + t = x.divToInt(pi); - // Return the absolute value of `x` reduced to less than or equal to half pi. - function toLessThanHalfPi(Ctor, x) { - var t, - isNeg = x.s < 0, - pi = getPi(Ctor, Ctor.precision, 1), - halfPi = pi.times(0.5); - - x = x.abs(); + if (t.isZero()) { + quadrant = isNeg ? 3 : 2; + } else { + x = x.minus(t.times(pi)); + // 0 <= x < pi if (x.lte(halfPi)) { - quadrant = isNeg ? 4 : 1; + quadrant = isOdd(t) ? (isNeg ? 2 : 3) : (isNeg ? 4 : 1); return x; } - t = x.divToInt(pi); + quadrant = isOdd(t) ? (isNeg ? 1 : 4) : (isNeg ? 3 : 2); + } - if (t.isZero()) { - quadrant = isNeg ? 3 : 2; - } else { - x = x.minus(t.times(pi)); + return x.minus(pi).abs(); +} - // 0 <= x < pi - if (x.lte(halfPi)) { - quadrant = isOdd(t) ? (isNeg ? 2 : 3) : (isNeg ? 4 : 1); - return x; - } - quadrant = isOdd(t) ? (isNeg ? 1 : 4) : (isNeg ? 3 : 2); - } +/* + * Return the value of Decimal `x` as a string in base `baseOut`. + * + * If the optional `sd` argument is present include a binary exponent suffix. + */ +function toStringBinary(x, baseOut, sd, rm) { + var base, e, i, k, len, roundUp, str, xd, y, + Ctor = x.constructor, + isExp = sd !== void 0; - return x.minus(pi).abs(); + if (isExp) { + checkInt32(sd, 1, MAX_DIGITS); + if (rm === void 0) rm = Ctor.rounding; + else checkInt32(rm, 0, 8); + } else { + sd = Ctor.precision; + rm = Ctor.rounding; } + if (!x.isFinite()) { + str = nonFiniteToString(x); + } else { + str = finiteToString(x); + i = str.indexOf('.'); - /* - * Return the value of Decimal `x` as a string in base `baseOut`. - * - * If the optional `sd` argument is present include a binary exponent suffix. - */ - function toStringBinary(x, baseOut, sd, rm) { - var base, e, i, k, len, roundUp, str, xd, y, - Ctor = x.constructor, - isExp = sd !== void 0; + // Use exponential notation according to `toExpPos` and `toExpNeg`? No, but if required: + // maxBinaryExponent = floor((decimalExponent + 1) * log[2](10)) + // minBinaryExponent = floor(decimalExponent * log[2](10)) + // log[2](10) = 3.321928094887362347870319429489390175864 if (isExp) { - checkInt32(sd, 1, MAX_DIGITS); - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); + base = 2; + if (baseOut == 16) { + sd = sd * 4 - 3; + } else if (baseOut == 8) { + sd = sd * 3 - 2; + } } else { - sd = Ctor.precision; - rm = Ctor.rounding; + base = baseOut; } - if (!x.isFinite()) { - str = nonFiniteToString(x); - } else { - str = finiteToString(x); - i = str.indexOf('.'); - - // Use exponential notation according to `toExpPos` and `toExpNeg`? No, but if required: - // maxBinaryExponent = floor((decimalExponent + 1) * log[2](10)) - // minBinaryExponent = floor(decimalExponent * log[2](10)) - // log[2](10) = 3.321928094887362347870319429489390175864 + // Convert the number as an integer then divide the result by its base raised to a power such + // that the fraction part will be restored. - if (isExp) { - base = 2; - if (baseOut == 16) { - sd = sd * 4 - 3; - } else if (baseOut == 8) { - sd = sd * 3 - 2; - } - } else { - base = baseOut; - } - - // Convert the number as an integer then divide the result by its base raised to a power such - // that the fraction part will be restored. - - // Non-integer. - if (i >= 0) { - str = str.replace('.', ''); - y = new Ctor(1); - y.e = str.length - i; - y.d = convertBase(finiteToString(y), 10, base); - y.e = y.d.length; - } + // Non-integer. + if (i >= 0) { + str = str.replace('.', ''); + y = new Ctor(1); + y.e = str.length - i; + y.d = convertBase(finiteToString(y), 10, base); + y.e = y.d.length; + } - xd = convertBase(str, 10, base); - e = len = xd.length; + xd = convertBase(str, 10, base); + e = len = xd.length; - // Remove trailing zeros. - for (; xd[--len] == 0;) xd.pop(); + // Remove trailing zeros. + for (; xd[--len] == 0;) xd.pop(); - if (!xd[0]) { - str = isExp ? '0p+0' : '0'; + if (!xd[0]) { + str = isExp ? '0p+0' : '0'; + } else { + if (i < 0) { + e--; } else { - if (i < 0) { - e--; - } else { - x = new Ctor(x); - x.d = xd; - x.e = e; - x = divide(x, y, sd, rm, 0, base); - xd = x.d; - e = x.e; - roundUp = inexact; - } + x = new Ctor(x); + x.d = xd; + x.e = e; + x = divide(x, y, sd, rm, 0, base); + xd = x.d; + e = x.e; + roundUp = inexact; + } - // The rounding digit, i.e. the digit after the digit that may be rounded up. - i = xd[sd]; - k = base / 2; - roundUp = roundUp || xd[sd + 1] !== void 0; + // The rounding digit, i.e. the digit after the digit that may be rounded up. + i = xd[sd]; + k = base / 2; + roundUp = roundUp || xd[sd + 1] !== void 0; - roundUp = rm < 4 - ? (i !== void 0 || roundUp) && (rm === 0 || rm === (x.s < 0 ? 3 : 2)) - : i > k || i === k && (rm === 4 || roundUp || rm === 6 && xd[sd - 1] & 1 || - rm === (x.s < 0 ? 8 : 7)); + roundUp = rm < 4 + ? (i !== void 0 || roundUp) && (rm === 0 || rm === (x.s < 0 ? 3 : 2)) + : i > k || i === k && (rm === 4 || roundUp || rm === 6 && xd[sd - 1] & 1 || + rm === (x.s < 0 ? 8 : 7)); - xd.length = sd; + xd.length = sd; - if (roundUp) { + if (roundUp) { - // Rounding up may mean the previous digit has to be rounded up and so on. - for (; ++xd[--sd] > base - 1;) { - xd[sd] = 0; - if (!sd) { - ++e; - xd.unshift(1); - } + // Rounding up may mean the previous digit has to be rounded up and so on. + for (; ++xd[--sd] > base - 1;) { + xd[sd] = 0; + if (!sd) { + ++e; + xd.unshift(1); } } + } - // Determine trailing zeros. - for (len = xd.length; !xd[len - 1]; --len); - - // E.g. [4, 11, 15] becomes 4bf. - for (i = 0, str = ''; i < len; i++) str += NUMERALS.charAt(xd[i]); + // Determine trailing zeros. + for (len = xd.length; !xd[len - 1]; --len); - // Add binary exponent suffix? - if (isExp) { - if (len > 1) { - if (baseOut == 16 || baseOut == 8) { - i = baseOut == 16 ? 4 : 3; - for (--len; len % i; len++) str += '0'; - xd = convertBase(str, base, baseOut); - for (len = xd.length; !xd[len - 1]; --len); + // E.g. [4, 11, 15] becomes 4bf. + for (i = 0, str = ''; i < len; i++) str += NUMERALS.charAt(xd[i]); - // xd[0] will always be be 1 - for (i = 1, str = '1.'; i < len; i++) str += NUMERALS.charAt(xd[i]); - } else { - str = str.charAt(0) + '.' + str.slice(1); - } + // Add binary exponent suffix? + if (isExp) { + if (len > 1) { + if (baseOut == 16 || baseOut == 8) { + i = baseOut == 16 ? 4 : 3; + for (--len; len % i; len++) str += '0'; + xd = convertBase(str, base, baseOut); + for (len = xd.length; !xd[len - 1]; --len); + + // xd[0] will always be be 1 + for (i = 1, str = '1.'; i < len; i++) str += NUMERALS.charAt(xd[i]); + } else { + str = str.charAt(0) + '.' + str.slice(1); } - - str = str + (e < 0 ? 'p' : 'p+') + e; - } else if (e < 0) { - for (; ++e;) str = '0' + str; - str = '0.' + str; - } else { - if (++e > len) for (e -= len; e-- ;) str += '0'; - else if (e < len) str = str.slice(0, e) + '.' + str.slice(e); } - } - str = (baseOut == 16 ? '0x' : baseOut == 2 ? '0b' : baseOut == 8 ? '0o' : '') + str; + str = str + (e < 0 ? 'p' : 'p+') + e; + } else if (e < 0) { + for (; ++e;) str = '0' + str; + str = '0.' + str; + } else { + if (++e > len) for (e -= len; e-- ;) str += '0'; + else if (e < len) str = str.slice(0, e) + '.' + str.slice(e); + } } - return x.s < 0 ? '-' + str : str; + str = (baseOut == 16 ? '0x' : baseOut == 2 ? '0b' : baseOut == 8 ? '0o' : '') + str; } + return x.s < 0 ? '-' + str : str; +} + - // Does not strip trailing zeros. - function truncate(arr, len) { - if (arr.length > len) { - arr.length = len; - return true; - } +// Does not strip trailing zeros. +function truncate(arr, len) { + if (arr.length > len) { + arr.length = len; + return true; } +} - // Decimal methods - +// Decimal methods - /* - * abs - * acos - * acosh - * add - * asin - * asinh - * atan - * atanh - * atan2 - * cbrt - * ceil - * clone - * config - * cos - * cosh - * div - * exp - * floor - * hypot - * ln - * log - * log2 - * log10 - * max - * min - * mod - * mul - * pow - * random - * round - * set - * sign - * sin - * sinh - * sqrt - * sub - * tan - * tanh - * trunc - */ +/* + * abs + * acos + * acosh + * add + * asin + * asinh + * atan + * atanh + * atan2 + * cbrt + * ceil + * clone + * config + * cos + * cosh + * div + * exp + * floor + * hypot + * ln + * log + * log2 + * log10 + * max + * min + * mod + * mul + * pow + * random + * round + * set + * sign + * sin + * sinh + * sqrt + * sub + * tan + * tanh + * trunc + */ - /* - * Return a new Decimal whose value is the absolute value of `x`. - * - * x {number|string|Decimal} - * - */ - function abs(x) { - return new this(x).abs(); - } +/* + * Return a new Decimal whose value is the absolute value of `x`. + * + * x {number|string|Decimal} + * + */ +function abs(x) { + return new this(x).abs(); +} - /* - * Return a new Decimal whose value is the arccosine in radians of `x`. - * - * x {number|string|Decimal} - * - */ - function acos(x) { - return new this(x).acos(); - } +/* + * Return a new Decimal whose value is the arccosine in radians of `x`. + * + * x {number|string|Decimal} + * + */ +function acos(x) { + return new this(x).acos(); +} - /* - * Return a new Decimal whose value is the inverse of the hyperbolic cosine of `x`, rounded to - * `precision` significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function acosh(x) { - return new this(x).acosh(); - } +/* + * Return a new Decimal whose value is the inverse of the hyperbolic cosine of `x`, rounded to + * `precision` significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} A value in radians. + * + */ +function acosh(x) { + return new this(x).acosh(); +} - /* - * Return a new Decimal whose value is the sum of `x` and `y`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * y {number|string|Decimal} - * - */ - function add(x, y) { - return new this(x).plus(y); - } +/* + * Return a new Decimal whose value is the sum of `x` and `y`, rounded to `precision` significant + * digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * y {number|string|Decimal} + * + */ +function add(x, y) { + return new this(x).plus(y); +} - /* - * Return a new Decimal whose value is the arcsine in radians of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function asin(x) { - return new this(x).asin(); - } +/* + * Return a new Decimal whose value is the arcsine in radians of `x`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * + */ +function asin(x) { + return new this(x).asin(); +} - /* - * Return a new Decimal whose value is the inverse of the hyperbolic sine of `x`, rounded to - * `precision` significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function asinh(x) { - return new this(x).asinh(); - } +/* + * Return a new Decimal whose value is the inverse of the hyperbolic sine of `x`, rounded to + * `precision` significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} A value in radians. + * + */ +function asinh(x) { + return new this(x).asinh(); +} - /* - * Return a new Decimal whose value is the arctangent in radians of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function atan(x) { - return new this(x).atan(); - } +/* + * Return a new Decimal whose value is the arctangent in radians of `x`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * + */ +function atan(x) { + return new this(x).atan(); +} - /* - * Return a new Decimal whose value is the inverse of the hyperbolic tangent of `x`, rounded to - * `precision` significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function atanh(x) { - return new this(x).atanh(); - } +/* + * Return a new Decimal whose value is the inverse of the hyperbolic tangent of `x`, rounded to + * `precision` significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} A value in radians. + * + */ +function atanh(x) { + return new this(x).atanh(); +} - /* - * Return a new Decimal whose value is the arctangent in radians of `y/x` in the range -pi to pi - * (inclusive), rounded to `precision` significant digits using rounding mode `rounding`. - * - * Domain: [-Infinity, Infinity] - * Range: [-pi, pi] - * - * y {number|string|Decimal} The y-coordinate. - * x {number|string|Decimal} The x-coordinate. - * - * atan2(±0, -0) = ±pi - * atan2(±0, +0) = ±0 - * atan2(±0, -x) = ±pi for x > 0 - * atan2(±0, x) = ±0 for x > 0 - * atan2(-y, ±0) = -pi/2 for y > 0 - * atan2(y, ±0) = pi/2 for y > 0 - * atan2(±y, -Infinity) = ±pi for finite y > 0 - * atan2(±y, +Infinity) = ±0 for finite y > 0 - * atan2(±Infinity, x) = ±pi/2 for finite x - * atan2(±Infinity, -Infinity) = ±3*pi/4 - * atan2(±Infinity, +Infinity) = ±pi/4 - * atan2(NaN, x) = NaN - * atan2(y, NaN) = NaN - * - */ - function atan2(y, x) { - y = new this(y); - x = new this(x); - var r, - pr = this.precision, - rm = this.rounding, - wpr = pr + 4; - - // Either NaN - if (!y.s || !x.s) { - r = new this(NaN); - - // Both ±Infinity - } else if (!y.d && !x.d) { - r = getPi(this, wpr, 1).times(x.s > 0 ? 0.25 : 0.75); - r.s = y.s; - - // x is ±Infinity or y is ±0 - } else if (!x.d || y.isZero()) { - r = x.s < 0 ? getPi(this, pr, rm) : new this(0); - r.s = y.s; - - // y is ±Infinity or x is ±0 - } else if (!y.d || x.isZero()) { - r = getPi(this, wpr, 1).times(0.5); - r.s = y.s; - - // Both non-zero and finite - } else if (x.s < 0) { - this.precision = wpr; - this.rounding = 1; - r = this.atan(divide(y, x, wpr, 1)); - x = getPi(this, wpr, 1); - this.precision = pr; - this.rounding = rm; - r = y.s < 0 ? r.minus(x) : r.plus(x); - } else { - r = this.atan(divide(y, x, wpr, 1)); - } - return r; +/* + * Return a new Decimal whose value is the arctangent in radians of `y/x` in the range -pi to pi + * (inclusive), rounded to `precision` significant digits using rounding mode `rounding`. + * + * Domain: [-Infinity, Infinity] + * Range: [-pi, pi] + * + * y {number|string|Decimal} The y-coordinate. + * x {number|string|Decimal} The x-coordinate. + * + * atan2(±0, -0) = ±pi + * atan2(±0, +0) = ±0 + * atan2(±0, -x) = ±pi for x > 0 + * atan2(±0, x) = ±0 for x > 0 + * atan2(-y, ±0) = -pi/2 for y > 0 + * atan2(y, ±0) = pi/2 for y > 0 + * atan2(±y, -Infinity) = ±pi for finite y > 0 + * atan2(±y, +Infinity) = ±0 for finite y > 0 + * atan2(±Infinity, x) = ±pi/2 for finite x + * atan2(±Infinity, -Infinity) = ±3*pi/4 + * atan2(±Infinity, +Infinity) = ±pi/4 + * atan2(NaN, x) = NaN + * atan2(y, NaN) = NaN + * + */ +function atan2(y, x) { + y = new this(y); + x = new this(x); + var r, + pr = this.precision, + rm = this.rounding, + wpr = pr + 4; + + // Either NaN + if (!y.s || !x.s) { + r = new this(NaN); + + // Both ±Infinity + } else if (!y.d && !x.d) { + r = getPi(this, wpr, 1).times(x.s > 0 ? 0.25 : 0.75); + r.s = y.s; + + // x is ±Infinity or y is ±0 + } else if (!x.d || y.isZero()) { + r = x.s < 0 ? getPi(this, pr, rm) : new this(0); + r.s = y.s; + + // y is ±Infinity or x is ±0 + } else if (!y.d || x.isZero()) { + r = getPi(this, wpr, 1).times(0.5); + r.s = y.s; + + // Both non-zero and finite + } else if (x.s < 0) { + this.precision = wpr; + this.rounding = 1; + r = this.atan(divide(y, x, wpr, 1)); + x = getPi(this, wpr, 1); + this.precision = pr; + this.rounding = rm; + r = y.s < 0 ? r.minus(x) : r.plus(x); + } else { + r = this.atan(divide(y, x, wpr, 1)); } + return r; +} + - /* - * Return a new Decimal whose value is the cube root of `x`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function cbrt(x) { - return new this(x).cbrt(); - } +/* + * Return a new Decimal whose value is the cube root of `x`, rounded to `precision` significant + * digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * + */ +function cbrt(x) { + return new this(x).cbrt(); +} - /* - * Return a new Decimal whose value is `x` rounded to an integer using `ROUND_CEIL`. - * - * x {number|string|Decimal} - * - */ - function ceil(x) { - return finalise(x = new this(x), x.e + 1, 2); - } +/* + * Return a new Decimal whose value is `x` rounded to an integer using `ROUND_CEIL`. + * + * x {number|string|Decimal} + * + */ +function ceil(x) { + return finalise(x = new this(x), x.e + 1, 2); +} - /* - * Configure global settings for a Decimal constructor. - * - * `obj` is an object with one or more of the following properties, - * - * precision {number} - * rounding {number} - * toExpNeg {number} - * toExpPos {number} - * maxE {number} - * minE {number} - * modulo {number} - * crypto {boolean|number} - * - * E.g. Decimal.config({ precision: 20, rounding: 4 }) - * - */ - function config(obj) { - if (!obj || typeof obj !== 'object') throw Error(decimalError + 'Object expected'); - var i, p, v, - ps = [ - 'precision', 1, MAX_DIGITS, - 'rounding', 0, 8, - 'toExpNeg', -EXP_LIMIT, 0, - 'toExpPos', 0, EXP_LIMIT, - 'maxE', 0, EXP_LIMIT, - 'minE', -EXP_LIMIT, 0, - 'modulo', 0, 9 - ]; - - for (i = 0; i < ps.length; i += 3) { - if ((v = obj[p = ps[i]]) !== void 0) { - if (mathfloor(v) === v && v >= ps[i + 1] && v <= ps[i + 2]) this[p] = v; - else throw Error(invalidArgument + p + ': ' + v); - } +/* + * Configure global settings for a Decimal constructor. + * + * `obj` is an object with one or more of the following properties, + * + * precision {number} + * rounding {number} + * toExpNeg {number} + * toExpPos {number} + * maxE {number} + * minE {number} + * modulo {number} + * crypto {boolean|number} + * + * E.g. Decimal.config({ precision: 20, rounding: 4 }) + * + */ +function config(obj) { + if (!obj || typeof obj !== 'object') throw Error(decimalError + 'Object expected'); + var i, p, v, + ps = [ + 'precision', 1, MAX_DIGITS, + 'rounding', 0, 8, + 'toExpNeg', -EXP_LIMIT, 0, + 'toExpPos', 0, EXP_LIMIT, + 'maxE', 0, EXP_LIMIT, + 'minE', -EXP_LIMIT, 0, + 'modulo', 0, 9 + ]; + + for (i = 0; i < ps.length; i += 3) { + if ((v = obj[p = ps[i]]) !== void 0) { + if (mathfloor(v) === v && v >= ps[i + 1] && v <= ps[i + 2]) this[p] = v; + else throw Error(invalidArgument + p + ': ' + v); } + } - if ((v = obj[p = 'crypto']) !== void 0) { - if (v === true || v === false || v === 0 || v === 1) { - if (v) { - if (typeof crypto != 'undefined' && crypto && - (crypto.getRandomValues || crypto.randomBytes)) { - this[p] = true; - } else { - throw Error(cryptoUnavailable); - } + if ((v = obj[p = 'crypto']) !== void 0) { + if (v === true || v === false || v === 0 || v === 1) { + if (v) { + if (typeof crypto != 'undefined' && crypto && + (crypto.getRandomValues || crypto.randomBytes)) { + this[p] = true; } else { - this[p] = false; + throw Error(cryptoUnavailable); } } else { - throw Error(invalidArgument + p + ': ' + v); + this[p] = false; } + } else { + throw Error(invalidArgument + p + ': ' + v); } - - return this; } + return this; +} - /* - * Return a new Decimal whose value is the cosine of `x`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function cos(x) { - return new this(x).cos(); - } +/* + * Return a new Decimal whose value is the cosine of `x`, rounded to `precision` significant + * digits using rounding mode `rounding`. + * + * x {number|string|Decimal} A value in radians. + * + */ +function cos(x) { + return new this(x).cos(); +} - /* - * Return a new Decimal whose value is the hyperbolic cosine of `x`, rounded to precision - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function cosh(x) { - return new this(x).cosh(); - } +/* + * Return a new Decimal whose value is the hyperbolic cosine of `x`, rounded to precision + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} A value in radians. + * + */ +function cosh(x) { + return new this(x).cosh(); +} + + +/* + * Create and return a Decimal constructor with the same configuration properties as this Decimal + * constructor. + * + */ +function clone(obj) { + var i, p, ps; /* - * Create and return a Decimal constructor with the same configuration properties as this Decimal - * constructor. + * The Decimal constructor and exported function. + * Return a new Decimal instance. + * + * v {number|string|Decimal} A numeric value. * */ - function clone(obj) { - var i, p, ps; - - /* - * The Decimal constructor and exported function. - * Return a new Decimal instance. - * - * v {number|string|Decimal} A numeric value. - * - */ - function Decimal(v) { - var e, i, t, - x = this; - - // Decimal called without new. - if (!(x instanceof Decimal)) return new Decimal(v); - - // Retain a reference to this Decimal constructor, and shadow Decimal.prototype.constructor - // which points to Object. - x.constructor = Decimal; - - // Duplicate. - if (v instanceof Decimal) { - x.s = v.s; - x.e = v.e; - x.d = (v = v.d) ? v.slice() : v; - return; - } - - t = typeof v; - - if (t === 'number') { - if (v === 0) { - x.s = 1 / v < 0 ? -1 : 1; - x.e = 0; - x.d = [0]; - return; - } + function Decimal(v) { + var e, i, t, + x = this; - if (v < 0) { - v = -v; - x.s = -1; - } else { - x.s = 1; - } + // Decimal called without new. + if (!(x instanceof Decimal)) return new Decimal(v); - // Fast path for small integers. - if (v === ~~v && v < 1e7) { - for (e = 0, i = v; i >= 10; i /= 10) e++; - x.e = e; - x.d = [v]; - return; + // Retain a reference to this Decimal constructor, and shadow Decimal.prototype.constructor + // which points to Object. + x.constructor = Decimal; - // Infinity, NaN. - } else if (v * 0 !== 0) { - if (!v) x.s = NaN; - x.e = NaN; - x.d = null; - return; - } + // Duplicate. + if (v instanceof Decimal) { + x.s = v.s; + x.e = v.e; + x.d = (v = v.d) ? v.slice() : v; + return; + } - return parseDecimal(x, v.toString()); + t = typeof v; - } else if (t !== 'string') { - throw Error(invalidArgument + v); + if (t === 'number') { + if (v === 0) { + x.s = 1 / v < 0 ? -1 : 1; + x.e = 0; + x.d = [0]; + return; } - // Minus sign? - if (v.charCodeAt(0) === 45) { - v = v.slice(1); + if (v < 0) { + v = -v; x.s = -1; } else { x.s = 1; } - return isDecimal.test(v) ? parseDecimal(x, v) : parseOther(x, v); - } - - Decimal.prototype = P; - - Decimal.ROUND_UP = 0; - Decimal.ROUND_DOWN = 1; - Decimal.ROUND_CEIL = 2; - Decimal.ROUND_FLOOR = 3; - Decimal.ROUND_HALF_UP = 4; - Decimal.ROUND_HALF_DOWN = 5; - Decimal.ROUND_HALF_EVEN = 6; - Decimal.ROUND_HALF_CEIL = 7; - Decimal.ROUND_HALF_FLOOR = 8; - Decimal.EUCLID = 9; - - Decimal.config = Decimal.set = config; - Decimal.clone = clone; - - Decimal.abs = abs; - Decimal.acos = acos; - Decimal.acosh = acosh; // ES6 - Decimal.add = add; - Decimal.asin = asin; - Decimal.asinh = asinh; // ES6 - Decimal.atan = atan; - Decimal.atanh = atanh; // ES6 - Decimal.atan2 = atan2; - Decimal.cbrt = cbrt; // ES6 - Decimal.ceil = ceil; - Decimal.cos = cos; - Decimal.cosh = cosh; // ES6 - Decimal.div = div; - Decimal.exp = exp; - Decimal.floor = floor; - Decimal.hypot = hypot; // ES6 - Decimal.ln = ln; - Decimal.log = log; - Decimal.log10 = log10; // ES6 - Decimal.log2 = log2; // ES6 - Decimal.max = max; - Decimal.min = min; - Decimal.mod = mod; - Decimal.mul = mul; - Decimal.pow = pow; - Decimal.random = random; - Decimal.round = round; - Decimal.sign = sign; // ES6 - Decimal.sin = sin; - Decimal.sinh = sinh; // ES6 - Decimal.sqrt = sqrt; - Decimal.sub = sub; - Decimal.tan = tan; - Decimal.tanh = tanh; // ES6 - Decimal.trunc = trunc; // ES6 - - if (obj === void 0) obj = {}; - if (obj) { - ps = ['precision', 'rounding', 'toExpNeg', 'toExpPos', 'maxE', 'minE', 'modulo', 'crypto']; - for (i = 0; i < ps.length;) if (!obj.hasOwnProperty(p = ps[i++])) obj[p] = this[p]; - } - - Decimal.config(obj); - - return Decimal; - } - - - /* - * Return a new Decimal whose value is `x` divided by `y`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * y {number|string|Decimal} - * - */ - function div(x, y) { - return new this(x).div(y); - } + // Fast path for small integers. + if (v === ~~v && v < 1e7) { + for (e = 0, i = v; i >= 10; i /= 10) e++; + x.e = e; + x.d = [v]; + return; + // Infinity, NaN. + } else if (v * 0 !== 0) { + if (!v) x.s = NaN; + x.e = NaN; + x.d = null; + return; + } - /* - * Return a new Decimal whose value is the natural exponential of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} The power to which to raise the base of the natural log. - * - */ - function exp(x) { - return new this(x).exp(); - } + return parseDecimal(x, v.toString()); + } else if (t !== 'string') { + throw Error(invalidArgument + v); + } - /* - * Return a new Decimal whose value is `x` round to an integer using `ROUND_FLOOR`. - * - * x {number|string|Decimal} - * - */ - function floor(x) { - return finalise(x = new this(x), x.e + 1, 3); + // Minus sign? + if (v.charCodeAt(0) === 45) { + v = v.slice(1); + x.s = -1; + } else { + x.s = 1; + } + + return isDecimal.test(v) ? parseDecimal(x, v) : parseOther(x, v); + } + + Decimal.prototype = P; + + Decimal.ROUND_UP = 0; + Decimal.ROUND_DOWN = 1; + Decimal.ROUND_CEIL = 2; + Decimal.ROUND_FLOOR = 3; + Decimal.ROUND_HALF_UP = 4; + Decimal.ROUND_HALF_DOWN = 5; + Decimal.ROUND_HALF_EVEN = 6; + Decimal.ROUND_HALF_CEIL = 7; + Decimal.ROUND_HALF_FLOOR = 8; + Decimal.EUCLID = 9; + + Decimal.config = Decimal.set = config; + Decimal.clone = clone; + + Decimal.abs = abs; + Decimal.acos = acos; + Decimal.acosh = acosh; // ES6 + Decimal.add = add; + Decimal.asin = asin; + Decimal.asinh = asinh; // ES6 + Decimal.atan = atan; + Decimal.atanh = atanh; // ES6 + Decimal.atan2 = atan2; + Decimal.cbrt = cbrt; // ES6 + Decimal.ceil = ceil; + Decimal.cos = cos; + Decimal.cosh = cosh; // ES6 + Decimal.div = div; + Decimal.exp = exp; + Decimal.floor = floor; + Decimal.hypot = hypot; // ES6 + Decimal.ln = ln; + Decimal.log = log; + Decimal.log10 = log10; // ES6 + Decimal.log2 = log2; // ES6 + Decimal.max = max; + Decimal.min = min; + Decimal.mod = mod; + Decimal.mul = mul; + Decimal.pow = pow; + Decimal.random = random; + Decimal.round = round; + Decimal.sign = sign; // ES6 + Decimal.sin = sin; + Decimal.sinh = sinh; // ES6 + Decimal.sqrt = sqrt; + Decimal.sub = sub; + Decimal.tan = tan; + Decimal.tanh = tanh; // ES6 + Decimal.trunc = trunc; // ES6 + + if (obj === void 0) obj = {}; + if (obj) { + ps = ['precision', 'rounding', 'toExpNeg', 'toExpPos', 'maxE', 'minE', 'modulo', 'crypto']; + for (i = 0; i < ps.length;) if (!obj.hasOwnProperty(p = ps[i++])) obj[p] = this[p]; } + Decimal.config(obj); - /* - * Return a new Decimal whose value is the square root of the sum of the squares of the arguments, - * rounded to `precision` significant digits using rounding mode `rounding`. - * - * hypot(a, b, ...) = sqrt(a^2 + b^2 + ...) - * - */ - function hypot() { - var i, n, - t = new this(0); + return Decimal; +} - external = false; - for (i = 0; i < arguments.length;) { - n = new this(arguments[i++]); - if (!n.d) { - if (n.s) { - external = true; - return new this(1 / 0); - } - t = n; - } else if (t.d) { - t = t.plus(n.times(n)); - } - } +/* + * Return a new Decimal whose value is `x` divided by `y`, rounded to `precision` significant + * digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * y {number|string|Decimal} + * + */ +function div(x, y) { + return new this(x).div(y); +} - external = true; - return t.sqrt(); - } +/* + * Return a new Decimal whose value is the natural exponential of `x`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} The power to which to raise the base of the natural log. + * + */ +function exp(x) { + return new this(x).exp(); +} - /* - * Return a new Decimal whose value is the natural logarithm of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function ln(x) { - return new this(x).ln(); - } +/* + * Return a new Decimal whose value is `x` round to an integer using `ROUND_FLOOR`. + * + * x {number|string|Decimal} + * + */ +function floor(x) { + return finalise(x = new this(x), x.e + 1, 3); +} - /* - * Return a new Decimal whose value is the log of `x` to the base `y`, or to base 10 if no base - * is specified, rounded to `precision` significant digits using rounding mode `rounding`. - * - * log[y](x) - * - * x {number|string|Decimal} The argument of the logarithm. - * y {number|string|Decimal} The base of the logarithm. - * - */ - function log(x, y) { - return new this(x).log(y); +/* + * Return a new Decimal whose value is the square root of the sum of the squares of the arguments, + * rounded to `precision` significant digits using rounding mode `rounding`. + * + * hypot(a, b, ...) = sqrt(a^2 + b^2 + ...) + * + */ +function hypot() { + var i, n, + t = new this(0); + + external = false; + + for (i = 0; i < arguments.length;) { + n = new this(arguments[i++]); + if (!n.d) { + if (n.s) { + external = true; + return new this(1 / 0); + } + t = n; + } else if (t.d) { + t = t.plus(n.times(n)); + } } + external = true; - /* - * Return a new Decimal whose value is the base 2 logarithm of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function log2(x) { - return new this(x).log(2); - } + return t.sqrt(); +} - /* - * Return a new Decimal whose value is the base 10 logarithm of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function log10(x) { - return new this(x).log(10); - } +/* + * Return a new Decimal whose value is the natural logarithm of `x`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * + */ +function ln(x) { + return new this(x).ln(); +} - /* - * Return a new Decimal whose value is the maximum of the arguments. - * - * arguments {number|string|Decimal} - * - */ - function max() { - return maxOrMin(this, arguments, 'lt'); - } +/* + * Return a new Decimal whose value is the log of `x` to the base `y`, or to base 10 if no base + * is specified, rounded to `precision` significant digits using rounding mode `rounding`. + * + * log[y](x) + * + * x {number|string|Decimal} The argument of the logarithm. + * y {number|string|Decimal} The base of the logarithm. + * + */ +function log(x, y) { + return new this(x).log(y); +} - /* - * Return a new Decimal whose value is the minimum of the arguments. - * - * arguments {number|string|Decimal} - * - */ - function min() { - return maxOrMin(this, arguments, 'gt'); - } +/* + * Return a new Decimal whose value is the base 2 logarithm of `x`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * + */ +function log2(x) { + return new this(x).log(2); +} - /* - * Return a new Decimal whose value is `x` modulo `y`, rounded to `precision` significant digits - * using rounding mode `rounding`. - * - * x {number|string|Decimal} - * y {number|string|Decimal} - * - */ - function mod(x, y) { - return new this(x).mod(y); - } +/* + * Return a new Decimal whose value is the base 10 logarithm of `x`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * + */ +function log10(x) { + return new this(x).log(10); +} - /* - * Return a new Decimal whose value is `x` multiplied by `y`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * y {number|string|Decimal} - * - */ - function mul(x, y) { - return new this(x).mul(y); - } +/* + * Return a new Decimal whose value is the maximum of the arguments. + * + * arguments {number|string|Decimal} + * + */ +function max() { + return maxOrMin(this, arguments, 'lt'); +} - /* - * Return a new Decimal whose value is `x` raised to the power `y`, rounded to precision - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} The base. - * y {number|string|Decimal} The exponent. - * - */ - function pow(x, y) { - return new this(x).pow(y); - } +/* + * Return a new Decimal whose value is the minimum of the arguments. + * + * arguments {number|string|Decimal} + * + */ +function min() { + return maxOrMin(this, arguments, 'gt'); +} - /* - * Returns a new Decimal with a random value equal to or greater than 0 and less than 1, and with - * `sd`, or `Decimal.precision` if `sd` is omitted, significant digits (or less if trailing zeros - * are produced). - * - * [sd] {number} Significant digits. Integer, 0 to MAX_DIGITS inclusive. - * - */ - function random(sd) { - var d, e, k, n, - i = 0, - r = new this(1), - rd = []; +/* + * Return a new Decimal whose value is `x` modulo `y`, rounded to `precision` significant digits + * using rounding mode `rounding`. + * + * x {number|string|Decimal} + * y {number|string|Decimal} + * + */ +function mod(x, y) { + return new this(x).mod(y); +} - if (sd === void 0) sd = this.precision; - else checkInt32(sd, 1, MAX_DIGITS); - k = Math.ceil(sd / LOG_BASE); +/* + * Return a new Decimal whose value is `x` multiplied by `y`, rounded to `precision` significant + * digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * y {number|string|Decimal} + * + */ +function mul(x, y) { + return new this(x).mul(y); +} - if (!this.crypto) { - for (; i < k;) rd[i++] = Math.random() * 1e7 | 0; - // Browsers supporting crypto.getRandomValues. - } else if (crypto.getRandomValues) { - d = crypto.getRandomValues(new Uint32Array(k)); +/* + * Return a new Decimal whose value is `x` raised to the power `y`, rounded to precision + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} The base. + * y {number|string|Decimal} The exponent. + * + */ +function pow(x, y) { + return new this(x).pow(y); +} - for (; i < k;) { - n = d[i]; - // 0 <= n < 4294967296 - // Probability n >= 4.29e9, is 4967296 / 4294967296 = 0.00116 (1 in 865). - if (n >= 4.29e9) { - d[i] = crypto.getRandomValues(new Uint32Array(1))[0]; - } else { +/* + * Returns a new Decimal with a random value equal to or greater than 0 and less than 1, and with + * `sd`, or `Decimal.precision` if `sd` is omitted, significant digits (or less if trailing zeros + * are produced). + * + * [sd] {number} Significant digits. Integer, 0 to MAX_DIGITS inclusive. + * + */ +function random(sd) { + var d, e, k, n, + i = 0, + r = new this(1), + rd = []; - // 0 <= n <= 4289999999 - // 0 <= (n % 1e7) <= 9999999 - rd[i++] = n % 1e7; - } - } + if (sd === void 0) sd = this.precision; + else checkInt32(sd, 1, MAX_DIGITS); - // Node.js supporting crypto.randomBytes. - } else if (crypto.randomBytes) { + k = Math.ceil(sd / LOG_BASE); - // buffer - d = crypto.randomBytes(k *= 4); + if (!this.crypto) { + for (; i < k;) rd[i++] = Math.random() * 1e7 | 0; - for (; i < k;) { + // Browsers supporting crypto.getRandomValues. + } else if (crypto.getRandomValues) { + d = crypto.getRandomValues(new Uint32Array(k)); - // 0 <= n < 2147483648 - n = d[i] + (d[i + 1] << 8) + (d[i + 2] << 16) + ((d[i + 3] & 0x7f) << 24); + for (; i < k;) { + n = d[i]; - // Probability n >= 2.14e9, is 7483648 / 2147483648 = 0.0035 (1 in 286). - if (n >= 2.14e9) { - crypto.randomBytes(4).copy(d, i); - } else { + // 0 <= n < 4294967296 + // Probability n >= 4.29e9, is 4967296 / 4294967296 = 0.00116 (1 in 865). + if (n >= 4.29e9) { + d[i] = crypto.getRandomValues(new Uint32Array(1))[0]; + } else { - // 0 <= n <= 2139999999 - // 0 <= (n % 1e7) <= 9999999 - rd.push(n % 1e7); - i += 4; - } + // 0 <= n <= 4289999999 + // 0 <= (n % 1e7) <= 9999999 + rd[i++] = n % 1e7; } - - i = k / 4; - } else { - throw Error(cryptoUnavailable); } - k = rd[--i]; - sd %= LOG_BASE; - - // Convert trailing digits to zeros according to sd. - if (k && sd) { - n = mathpow(10, LOG_BASE - sd); - rd[i] = (k / n | 0) * n; - } + // Node.js supporting crypto.randomBytes. + } else if (crypto.randomBytes) { - // Remove trailing words which are zero. - for (; rd[i] === 0; i--) rd.pop(); + // buffer + d = crypto.randomBytes(k *= 4); - // Zero? - if (i < 0) { - e = 0; - rd = [0]; - } else { - e = -1; + for (; i < k;) { - // Remove leading words which are zero and adjust exponent accordingly. - for (; rd[0] === 0; e -= LOG_BASE) rd.shift(); + // 0 <= n < 2147483648 + n = d[i] + (d[i + 1] << 8) + (d[i + 2] << 16) + ((d[i + 3] & 0x7f) << 24); - // Count the digits of the first word of rd to determine leading zeros. - for (k = 1, n = rd[0]; n >= 10; n /= 10) k++; + // Probability n >= 2.14e9, is 7483648 / 2147483648 = 0.0035 (1 in 286). + if (n >= 2.14e9) { + crypto.randomBytes(4).copy(d, i); + } else { - // Adjust the exponent for leading zeros of the first word of rd. - if (k < LOG_BASE) e -= LOG_BASE - k; + // 0 <= n <= 2139999999 + // 0 <= (n % 1e7) <= 9999999 + rd.push(n % 1e7); + i += 4; + } } - r.e = e; - r.d = rd; - - return r; + i = k / 4; + } else { + throw Error(cryptoUnavailable); } + k = rd[--i]; + sd %= LOG_BASE; - /* - * Return a new Decimal whose value is `x` rounded to an integer using rounding mode `rounding`. - * - * To emulate `Math.round`, set rounding to 7 (ROUND_HALF_CEIL). - * - * x {number|string|Decimal} - * - */ - function round(x) { - return finalise(x = new this(x), x.e + 1, this.rounding); + // Convert trailing digits to zeros according to sd. + if (k && sd) { + n = mathpow(10, LOG_BASE - sd); + rd[i] = (k / n | 0) * n; } + // Remove trailing words which are zero. + for (; rd[i] === 0; i--) rd.pop(); - /* - * Return - * 1 if x > 0, - * -1 if x < 0, - * 0 if x is 0, - * -0 if x is -0, - * NaN otherwise - * - */ - function sign(x) { - x = new this(x); - return x.d ? (x.d[0] ? x.s : 0 * x.s) : x.s || NaN; - } + // Zero? + if (i < 0) { + e = 0; + rd = [0]; + } else { + e = -1; + // Remove leading words which are zero and adjust exponent accordingly. + for (; rd[0] === 0; e -= LOG_BASE) rd.shift(); - /* - * Return a new Decimal whose value is the sine of `x`, rounded to `precision` significant digits - * using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function sin(x) { - return new this(x).sin(); + // Count the digits of the first word of rd to determine leading zeros. + for (k = 1, n = rd[0]; n >= 10; n /= 10) k++; + + // Adjust the exponent for leading zeros of the first word of rd. + if (k < LOG_BASE) e -= LOG_BASE - k; } + r.e = e; + r.d = rd; - /* - * Return a new Decimal whose value is the hyperbolic sine of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function sinh(x) { - return new this(x).sinh(); - } + return r; +} - /* - * Return a new Decimal whose value is the square root of `x`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function sqrt(x) { - return new this(x).sqrt(); - } +/* + * Return a new Decimal whose value is `x` rounded to an integer using rounding mode `rounding`. + * + * To emulate `Math.round`, set rounding to 7 (ROUND_HALF_CEIL). + * + * x {number|string|Decimal} + * + */ +function round(x) { + return finalise(x = new this(x), x.e + 1, this.rounding); +} - /* - * Return a new Decimal whose value is `x` minus `y`, rounded to `precision` significant digits - * using rounding mode `rounding`. - * - * x {number|string|Decimal} - * y {number|string|Decimal} - * - */ - function sub(x, y) { - return new this(x).sub(y); - } +/* + * Return + * 1 if x > 0, + * -1 if x < 0, + * 0 if x is 0, + * -0 if x is -0, + * NaN otherwise + * + */ +function sign(x) { + x = new this(x); + return x.d ? (x.d[0] ? x.s : 0 * x.s) : x.s || NaN; +} - /* - * Return a new Decimal whose value is the tangent of `x`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function tan(x) { - return new this(x).tan(); - } +/* + * Return a new Decimal whose value is the sine of `x`, rounded to `precision` significant digits + * using rounding mode `rounding`. + * + * x {number|string|Decimal} A value in radians. + * + */ +function sin(x) { + return new this(x).sin(); +} - /* - * Return a new Decimal whose value is the hyperbolic tangent of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function tanh(x) { - return new this(x).tanh(); - } +/* + * Return a new Decimal whose value is the hyperbolic sine of `x`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} A value in radians. + * + */ +function sinh(x) { + return new this(x).sinh(); +} - /* - * Return a new Decimal whose value is `x` truncated to an integer. - * - * x {number|string|Decimal} - * - */ - function trunc(x) { - return finalise(x = new this(x), x.e + 1, 1); - } +/* + * Return a new Decimal whose value is the square root of `x`, rounded to `precision` significant + * digits using rounding mode `rounding`. + * + * x {number|string|Decimal} + * + */ +function sqrt(x) { + return new this(x).sqrt(); +} + +/* + * Return a new Decimal whose value is `x` minus `y`, rounded to `precision` significant digits + * using rounding mode `rounding`. + * + * x {number|string|Decimal} + * y {number|string|Decimal} + * + */ +function sub(x, y) { + return new this(x).sub(y); +} - // Create and configure initial Decimal constructor. - Decimal = clone(Decimal); - // Create the internal constants from their string values. - LN10 = new Decimal(LN10); - PI = new Decimal(PI); +/* + * Return a new Decimal whose value is the tangent of `x`, rounded to `precision` significant + * digits using rounding mode `rounding`. + * + * x {number|string|Decimal} A value in radians. + * + */ +function tan(x) { + return new this(x).tan(); +} - // Export. +/* + * Return a new Decimal whose value is the hyperbolic tangent of `x`, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * x {number|string|Decimal} A value in radians. + * + */ +function tanh(x) { + return new this(x).tanh(); +} - // AMD. - if (true) { - !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () { - return Decimal; - }).call(exports, __webpack_require__, exports, module), - __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); +/* + * Return a new Decimal whose value is `x` truncated to an integer. + * + * x {number|string|Decimal} + * + */ +function trunc(x) { + return finalise(x = new this(x), x.e + 1, 1); +} + + +// Create and configure initial Decimal constructor. +Decimal = clone(defaults); + +// Create the internal constants from their string values. +LN10 = new Decimal(ln10); +PI = new Decimal(pi); - // Node and other environments that support module.exports. - } else {} -})(this); +/* harmony default export */ __webpack_exports__["default"] = (Decimal); /***/ }), @@ -29317,7 +29314,7 @@ function initBladeburner() { Skills[SkillNames.Overclock] = new Skill({ name:SkillNames.Overclock, desc:"Each level of this skill decreases the time it takes " + - "to attempt a contract or operation by 1% (Max Level: 99)", + "to attempt a contract or operation by 1% (Max Level: 95)", baseCost:5, costInc:1, maxLvl:95, actionTime:1 }); @@ -30289,8 +30286,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./NetscriptEvaluator.js */ 6); /* harmony import */ var _NetscriptEnvironment_js__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./NetscriptEnvironment.js */ 69); /* harmony import */ var _NetscriptPort_js__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./NetscriptPort.js */ 46); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../utils/decimal.js */ 24); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_27___default = /*#__PURE__*/__webpack_require__.n(_utils_decimal_js__WEBPACK_IMPORTED_MODULE_27__); +/* harmony import */ var decimal_js__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! decimal.js */ 24); /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../utils/DialogBox.js */ 7); /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1); /* harmony import */ var _utils_IPAddress_js__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ../utils/IPAddress.js */ 16); @@ -30419,7 +30415,7 @@ function NetscriptFunctions(workerScript) { Math : Math, Date : Date, Number : Number, - hacknetnodes : _Player_js__WEBPACK_IMPORTED_MODULE_15__["Player"].hacknetNodes, + hacknetnodes : _Player_js__WEBPACK_IMPORTED_MODULE_15__["Player"].hacknetNodeWrappers, sprintf : sprintf, vsprintf: vsprintf, scan : function(ip=workerScript.serverIp, hostnames=true){ @@ -31386,7 +31382,8 @@ function NetscriptFunctions(workerScript) { if (!hasAISF) { throw Object(_NetscriptEvaluator_js__WEBPACK_IMPORTED_MODULE_24__["makeRuntimeRejectMsg"])(workerScript, "Cannot run getBitNodeMultipliers(). It requires Source-File 5 to run."); } - return _BitNode_js__WEBPACK_IMPORTED_MODULE_2__["BitNodeMultipliers"]; + let copy = Object.assign({}, _BitNode_js__WEBPACK_IMPORTED_MODULE_2__["BitNodeMultipliers"]); + return copy; }, getServerMoneyAvailable : function(ip){ if (workerScript.checkingRam) { @@ -52297,6 +52294,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateHacknetNodesContent", function() { return updateHacknetNodesContent; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "processAllHacknetNodeEarnings", function() { return processAllHacknetNodeEarnings; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getHacknetNode", function() { return getHacknetNode; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createPlayerHacknetNodeWrappers", function() { return createPlayerHacknetNodeWrappers; }); /* harmony import */ var _BitNode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BitNode.js */ 15); /* harmony import */ var _Constants_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Constants.js */ 3); /* harmony import */ var _engine_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./engine.js */ 5); @@ -52362,6 +52360,7 @@ function HacknetNode(name) { this.moneyGainRatePerSecond = 0; } + HacknetNode.prototype.updateMoneyGainRate = function() { //How much extra $/s is gained per level var gainPerLevel = _Constants_js__WEBPACK_IMPORTED_MODULE_1__["CONSTANTS"].HacknetNodeMoneyGainPerLevel; @@ -52486,6 +52485,36 @@ HacknetNode.fromJSON = function(value) { _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_7__["Reviver"].constructors.HacknetNode = HacknetNode; +var HacknetNodeWrapper = function(hacknetNodeObj) { + var _node = hacknetNodeObj; + return { + name : _node.name, + level : _node.level, + ram : _node.ram, + cores : _node.cores, + totalMoneyGenerated : _node.totalMoneyGenerated, + onlineTimeSeconds : _node.onlineTimeSeconds, + moneyGainRatePerSecond : _node.moneyGainRatePerSecond, + upgradeLevel : function(n) { + return _node.upgradeLevel(n); + }, + upgradeRam : function() { + return _node.upgradeRam(); + }, + upgradeCore : function() { + return _node.upgradeCore(); + }, + getLevelUpgradeCost : function(n) { + return _node.getLevelUpgradeCost(n); + }, + getRamUpgradeCost : function() { + return _node.getRamUpgradeCost(); + }, + getCoreUpgradeCost : function() { + return _node.getCoreUpgradeCost(); + } + } +} function purchaseHacknet() { /* INTERACTIVE TUTORIAL */ @@ -52775,8 +52804,31 @@ function updateHacknetNodeDomElement(nodeObj) { } } +function createPlayerHacknetNodeWrappers() { + _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers.length = _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length; + for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length; ++i) { + _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers[i] = new HacknetNodeWrapper(_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i]); + } +} + +function updatePlayerHacknetNodeWrappers() { + if (_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers.length !== _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length) { + return createPlayerHacknetNodeWrappers(); + } + for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers.length; ++i) { + if (!(_Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers[i] instanceof HacknetNodeWrapper)) {return createPlayerHacknetNodeWrappers();} + _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers[i].level = _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i].level; + _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers[i].ram = _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i].ram; + _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers[i].cores = _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i].cores; + _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers[i].totalMoneyGenerated = _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i].totalMoneyGenerated; + _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers[i].onlineTimeSeconds = _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i].onlineTimeSeconds; + _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodeWrappers[i].moneyGainRatePerSecond = _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i].moneyGainRatePerSecond; + } +} + function processAllHacknetNodeEarnings(numCycles) { var total = 0; + updatePlayerHacknetNodeWrappers(); for (var i = 0; i < _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes.length; ++i) { total += processSingleHacknetNodeEarnings(numCycles, _Player_js__WEBPACK_IMPORTED_MODULE_4__["Player"].hacknetNodes[i]); } @@ -53128,8 +53180,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _Literature_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Literature.js */ 53); /* harmony import */ var _Location_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Location.js */ 4); /* harmony import */ var _Player_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Player.js */ 0); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/decimal.js */ 24); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_utils_decimal_js__WEBPACK_IMPORTED_MODULE_6__); +/* harmony import */ var decimal_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! decimal.js */ 24); /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/DialogBox.js */ 7); /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1); /* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8); @@ -53763,10 +53814,10 @@ function Industry(params={}) { this.prodMult = 0; //Production multiplier //Financials - this.lastCycleRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); - this.lastCycleExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); - this.thisCycleRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); - this.thisCycleExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); + this.lastCycleRevenue = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); + this.lastCycleExpenses = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); + this.thisCycleRevenue = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); + this.thisCycleExpenses = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); //Upgrades var numUpgrades = Object.keys(IndustryUpgrades).length; @@ -54064,13 +54115,13 @@ Industry.prototype.process = function(marketCycles=1, state, company) { console.log(this.thisCycleRevenue.toString()); console.log(this.thisCycleExpenses.toString()); Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("Something went wrong when compting Corporation's revenue/expenses. This is a bug. Please report to game developer"); - this.thisCycleRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); - this.thisCycleExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); + this.thisCycleRevenue = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); + this.thisCycleExpenses = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); } this.lastCycleRevenue = this.thisCycleRevenue.dividedBy(marketCycles * SecsPerMarketCycle); this.lastCycleExpenses = this.thisCycleExpenses.dividedBy(marketCycles * SecsPerMarketCycle); - this.thisCycleRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); - this.thisCycleExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); + this.thisCycleRevenue = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); + this.thisCycleExpenses = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); //Once you start making revenue, the player should no longer be //considered new, and therefore no longer needs the 'tutorial' UI elements @@ -56181,9 +56232,9 @@ function Corporation(params={}) { this.divisions = []; //Financial stats - this.funds = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(150e9); - this.revenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); - this.expenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); + this.funds = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](150e9); + this.revenue = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); + this.expenses = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); this.fundingRound = 0; this.public = false; //Publicly traded this.numShares = TOTALSHARES; @@ -56217,8 +56268,8 @@ Corporation.prototype.process = function() { //At the start of a new cycle, calculate profits from previous cycle if (state === "START") { - this.revenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); - this.expenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); + this.revenue = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); + this.expenses = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); this.divisions.forEach((ind)=>{ this.revenue = this.revenue.plus(ind.lastCycleRevenue); this.expenses = this.expenses.plus(ind.lastCycleExpenses); @@ -56229,7 +56280,7 @@ Corporation.prototype.process = function() { Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_7__["dialogBoxCreate"])("There was an error calculating your Corporations funds and they got reset to 0. " + "This is a bug. Please report to game developer.

" + "(Your funds have been set to $150b for the inconvenience)"); - this.funds = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(150e9); + this.funds = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](150e9); } this.funds = this.funds.plus(cycleProfit); this.updateSharePrice(); @@ -57139,8 +57190,8 @@ Corporation.prototype.updateCorporationOverviewContent = function() { return; } var totalFunds = this.funds, - totalRevenue = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0), - totalExpenses = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_6___default.a(0); + totalRevenue = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0), + totalExpenses = new decimal_js__WEBPACK_IMPORTED_MODULE_6__["default"](0); var profit = this.revenue.minus(this.expenses).toNumber(), profitStr = profit >= 0 ? _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(profit).format("$0.000a") : "-" + _utils_numeral_min_js__WEBPACK_IMPORTED_MODULE_10___default()(-1 * profit).format("$0.000a"); @@ -58810,8 +58861,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1); /* harmony import */ var _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../utils/JSONReviver.js */ 8); /* harmony import */ var _utils_StringHelperFunctions_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../utils/StringHelperFunctions.js */ 2); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../utils/decimal.js */ 24); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20___default = /*#__PURE__*/__webpack_require__.n(_utils_decimal_js__WEBPACK_IMPORTED_MODULE_20__); +/* harmony import */ var decimal_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! decimal.js */ 24); @@ -59036,6 +59086,8 @@ function loadGame(saveString) { } } + //Re-initialize Hacknet Node Wrappers + Object(_HacknetNode_js__WEBPACK_IMPORTED_MODULE_7__["createPlayerHacknetNodeWrappers"])(); return true; } @@ -59062,9 +59114,9 @@ function loadImportedGame(saveObj, saveString) { tempPlayer = JSON.parse(tempSaveObj.PlayerSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]); //Parse Decimal.js objects - tempPlayer.money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20___default.a(tempPlayer.money); - tempPlayer.total_money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20___default.a(tempPlayer.total_money); - tempPlayer.lifetime_money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_20___default.a(tempPlayer.lifetime_money); + tempPlayer.money = new decimal_js__WEBPACK_IMPORTED_MODULE_20__["default"](tempPlayer.money); + tempPlayer.total_money = new decimal_js__WEBPACK_IMPORTED_MODULE_20__["default"](tempPlayer.total_money); + tempPlayer.lifetime_money = new decimal_js__WEBPACK_IMPORTED_MODULE_20__["default"](tempPlayer.lifetime_money); tempAllServers = JSON.parse(tempSaveObj.AllServersSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]); tempCompanies = JSON.parse(tempSaveObj.CompaniesSave, _utils_JSONReviver_js__WEBPACK_IMPORTED_MODULE_18__["Reviver"]); @@ -59252,6 +59304,9 @@ function loadImportedGame(saveObj, saveString) { } } + //Re-initialize Hacknet Node Wrappers + Object(_HacknetNode_js__WEBPACK_IMPORTED_MODULE_7__["createPlayerHacknetNodeWrappers"])(); + var popupId = "import-game-restart-game-notice"; var txt = Object(_utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_17__["createElement"])("p", { innerText:"Imported game! I would suggest saving the game and then reloading the page " + @@ -60687,8 +60742,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _SpecialServerIps_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./SpecialServerIps.js */ 17); /* harmony import */ var _StockMarket_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./StockMarket.js */ 22); /* harmony import */ var _Terminal_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./Terminal.js */ 18); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../utils/decimal.js */ 24); -/* harmony import */ var _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18___default = /*#__PURE__*/__webpack_require__.n(_utils_decimal_js__WEBPACK_IMPORTED_MODULE_18__); +/* harmony import */ var decimal_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! decimal.js */ 24); /* harmony import */ var _utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../utils/DialogBox.js */ 7); /* harmony import */ var _utils_HelperFunctions_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../utils/HelperFunctions.js */ 1); /* harmony import */ var _utils_YesNoBox_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../utils/YesNoBox.js */ 12); @@ -60715,6 +60769,8 @@ __webpack_require__.r(__webpack_exports__); + +let BitNode8StartingMoney = 250e6; //Prestige by purchasing augmentation function prestigeAugmentation() { @@ -60743,7 +60799,7 @@ function prestigeAugmentation() { } if (Object(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["augmentationExists"])(_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["AugmentationNames"].CashRoot) && _Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["Augmentations"][_Augmentations_js__WEBPACK_IMPORTED_MODULE_1__["AugmentationNames"].CashRoot].owned) { - _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].setMoney(new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18___default.a(1000000)); + _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].setMoney(new decimal_js__WEBPACK_IMPORTED_MODULE_18__["default"](1000000)); homeComp.programs.push(_CreateProgram_js__WEBPACK_IMPORTED_MODULE_5__["Programs"].BruteSSHProgram); } @@ -60809,7 +60865,7 @@ function prestigeAugmentation() { _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bladeburner = null; //BitNode 8: Ghost of Wall Street - if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 8) {_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18___default.a(100e6);} + if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 8) {_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].money = new decimal_js__WEBPACK_IMPORTED_MODULE_18__["default"](BitNode8StartingMoney);} if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 8 || _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_11__["hasWallStreetSF"]) { _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].hasWseAccount = true; _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].hasTixApiAccess = true; @@ -60937,7 +60993,7 @@ function prestigeSourceFile() { //BitNode 3: Corporatocracy if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 3) { - _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].money = new _utils_decimal_js__WEBPACK_IMPORTED_MODULE_18___default.a(150e9); + _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].money = new decimal_js__WEBPACK_IMPORTED_MODULE_18__["default"](150e9); homeComp.messages.push("corporation-management-handbook.lit"); Object(_utils_DialogBox_js__WEBPACK_IMPORTED_MODULE_19__["dialogBoxCreate"])("You received a copy of the Corporation Management Handbook on your home computer. " + "Read it if you need help getting started with Corporations!"); @@ -60987,6 +61043,13 @@ function prestigeSourceFile() { } + //BitNode 8: Ghost of Wall Street + if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 8) {_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].money = new decimal_js__WEBPACK_IMPORTED_MODULE_18__["default"](BitNode8StartingMoney);} + if (_Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].bitNodeN === 8 || _NetscriptFunctions_js__WEBPACK_IMPORTED_MODULE_11__["hasWallStreetSF"]) { + _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].hasWseAccount = true; + _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].hasTixApiAccess = true; + } + //Gain int exp _Player_js__WEBPACK_IMPORTED_MODULE_13__["Player"].gainIntelligenceExp(5); } @@ -97015,7 +97078,7 @@ var NetscriptHighlightRules = function(options) { "JSON|Math|" + // Other "this|arguments|prototype|window|document" , // Pseudo "keyword": - "const|yield|import|get|set|async|await|foop|" + + "const|yield|import|get|set|async|await|" + "break|case|catch|continue|default|delete|do|else|finally|for|function|" + "if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|" + "__parent__|__count__|escape|unescape|with|__proto__|" + diff --git a/doc/build/doctrees/changelog.doctree b/doc/build/doctrees/changelog.doctree index 68d425d855..1c53164d2e 100644 Binary files a/doc/build/doctrees/changelog.doctree and b/doc/build/doctrees/changelog.doctree differ diff --git a/doc/build/doctrees/environment.pickle b/doc/build/doctrees/environment.pickle index 3425ba2b13..0ae7a90c33 100644 Binary files a/doc/build/doctrees/environment.pickle and b/doc/build/doctrees/environment.pickle differ diff --git a/doc/build/html/_sources/changelog.rst.txt b/doc/build/html/_sources/changelog.rst.txt index 4dcd7947f1..03d84f44ae 100644 --- a/doc/build/html/_sources/changelog.rst.txt +++ b/doc/build/html/_sources/changelog.rst.txt @@ -3,8 +3,18 @@ Changelog ========= -v0.37.1 -------- +v0.37.2 - 6/2/2018 +------------------ + +* After joining the Bladeburners division, there is now a button to go to the Bladeburner content + in the 'City' page +* You now start with $250m in BitNode-8 (increased from $100m) +* Bug Fix: You can now no longer directly edit Hacknet Node values through NetscriptJS (hopefully) +* Bug Fix: Bladeburners is no longer accessible in BN-8 +* Bug Fix: getBitNodeMultipliers() Netscript function now returns a copy rather than the original object + +v0.37.1 - 5/22/2018 +------------------- * You now earn money from successfully completing Bladeburner contracts. The amount you earn is based on the difficulty of the contract. * Completing Field Analysis in Bladeburner now grants 0.1 rank diff --git a/doc/build/html/changelog.html b/doc/build/html/changelog.html index b4181b9c58..d0d6b296ea 100644 --- a/doc/build/html/changelog.html +++ b/doc/build/html/changelog.html @@ -50,8 +50,19 @@

Changelog

-
-

v0.37.1

+
+

v0.37.2 - 6/2/2018

+
    +
  • After joining the Bladeburners division, there is now a button to go to the Bladeburner content +in the 'City' page
  • +
  • You now start with $250m in BitNode-8 (increased from $100m)
  • +
  • Bug Fix: You can now no longer directly edit Hacknet Node values through NetscriptJS (hopefully)
  • +
  • Bug Fix: Bladeburners is no longer accessible in BN-8
  • +
  • Bug Fix: getBitNodeMultipliers() Netscript function now returns a copy rather than the original object
  • +
+
+
+

v0.37.1 - 5/22/2018

  • You now earn money from successfully completing Bladeburner contracts. The amount you earn is based on the difficulty of the contract.
  • @@ -971,7 +982,8 @@

    Table Of Contents

  • Terminal
  • Keyboard Shortcuts
  • Changelog
      -
    • v0.37.1
    • +
    • v0.37.2 - 6/2/2018
    • +
    • v0.37.1 - 5/22/2018
    • v0.37.0 - 5/20/2018
    • v0.36.1 - 5/11/2018
    • v0.36.0 - 5/2/2018
    • diff --git a/doc/build/html/index.html b/doc/build/html/index.html index 13a64c95f0..8e384e7958 100644 --- a/doc/build/html/index.html +++ b/doc/build/html/index.html @@ -268,7 +268,8 @@

      What is Bitburner? Changelog
        -
      • v0.37.1
      • +
      • v0.37.2 - 6/2/2018
      • +
      • v0.37.1 - 5/22/2018
      • v0.37.0 - 5/20/2018
      • v0.36.1 - 5/11/2018
      • v0.36.0 - 5/2/2018
      • diff --git a/doc/build/html/searchindex.js b/doc/build/html/searchindex.js index f0ef76224e..0439368a68 100644 --- a/doc/build/html/searchindex.js +++ b/doc/build/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["changelog","index","netscript","netscriptadvancedfunctions","netscriptdatatypes","netscriptfunctions","netscripthacknetnodeapi","netscriptixapi","netscriptjs","netscriptloopsandconditionals","netscriptmisc","netscriptoperators","netscriptscriptarguments","netscriptsingularityfunctions","shortcuts","terminal"],envversion:53,filenames:["changelog.rst","index.rst","netscript.rst","netscriptadvancedfunctions.rst","netscriptdatatypes.rst","netscriptfunctions.rst","netscripthacknetnodeapi.rst","netscriptixapi.rst","netscriptjs.rst","netscriptloopsandconditionals.rst","netscriptmisc.rst","netscriptoperators.rst","netscriptscriptarguments.rst","netscriptsingularityfunctions.rst","shortcuts.rst","terminal.rst"],objects:{"":{applyToCompany:[13,2,1,""],buyStock:[7,2,1,""],cancelOrder:[7,2,1,""],checkFactionInvitations:[13,2,1,""],clearLog:[5,2,1,""],commitCrime:[13,2,1,""],createProgram:[13,2,1,""],deleteServer:[5,2,1,""],disableLog:[5,2,1,""],enableLog:[5,2,1,""],fileExists:[5,2,1,""],getAugmentationCost:[13,2,1,""],getAugmentationsFromFaction:[13,2,1,""],getBitNodeMultipliers:[3,2,1,""],getCompanyFavor:[13,2,1,""],getCompanyRep:[13,2,1,""],getCrimeChance:[13,2,1,""],getFactionFavor:[13,2,1,""],getFactionRep:[13,2,1,""],getGrowTime:[5,2,1,""],getHackTime:[5,2,1,""],getHackingLevel:[5,2,1,""],getHackingMultipliers:[5,2,1,""],getHacknetMultipliers:[5,2,1,""],getHostname:[5,2,1,""],getNextHacknetNodeCost:[5,2,1,""],getOwnedAugmentations:[13,2,1,""],getPurchasedServers:[5,2,1,""],getScriptExpGain:[5,2,1,""],getScriptIncome:[5,2,1,""],getScriptName:[5,2,1,""],getScriptRam:[5,2,1,""],getServerBaseSecurityLevel:[5,2,1,""],getServerGrowth:[5,2,1,""],getServerMaxMoney:[5,2,1,""],getServerMinSecurityLevel:[5,2,1,""],getServerMoneyAvailable:[5,2,1,""],getServerNumPortsRequired:[5,2,1,""],getServerRam:[5,2,1,""],getServerRequiredHackingLevel:[5,2,1,""],getServerSecurityLevel:[5,2,1,""],getStats:[13,2,1,""],getStockPosition:[7,2,1,""],getStockPrice:[7,2,1,""],getTimeSinceLastAug:[5,2,1,""],getUpgradeHomeRamCost:[13,2,1,""],getWeakenTime:[5,2,1,""],gymWorkout:[13,2,1,""],hasRootAccess:[5,2,1,""],installAugmentations:[13,2,1,""],isBusy:[13,2,1,""],isRunning:[5,2,1,""],joinFaction:[13,2,1,""],placeOrder:[7,2,1,""],purchaseAugmentation:[13,2,1,""],purchaseHacknetNode:[5,2,1,""],purchaseProgram:[13,2,1,""],purchaseServer:[5,2,1,""],purchaseTor:[13,2,1,""],scriptKill:[5,2,1,""],scriptRunning:[5,2,1,""],sellShort:[7,2,1,""],sellStock:[7,2,1,""],serverExists:[5,2,1,""],shortStock:[7,2,1,""],stopAction:[13,2,1,""],travelToCity:[13,2,1,""],universityCourse:[13,2,1,""],upgradeHomeRam:[13,2,1,""],workForCompany:[13,2,1,""],workForFaction:[13,2,1,""]},"hacknetnodes[i]":{cores:[6,1,1,""],getCoreUpgradeCost:[6,0,1,""],getLevelUpgradeCost:[6,0,1,""],getRamUpgradeCost:[6,0,1,""],level:[6,1,1,""],moneyGainRatePerSecond:[6,1,1,""],name:[6,1,1,""],onlineTimeSeconds:[6,1,1,""],ram:[6,1,1,""],totalMoneyGenerated:[6,1,1,""],upgradeCore:[6,0,1,""],upgradeLevel:[6,0,1,""],upgradeRam:[6,0,1,""]},NetscriptPort:{clear:[10,0,1,""],data:[10,1,1,""],empty:[10,0,1,""],full:[10,0,1,""],tryWrite:[10,0,1,""],write:[10,0,1,""]}},objnames:{"0":["js","method","JavaScript method"],"1":["js","attribute","JavaScript attribute"],"2":["js","function","JavaScript function"]},objtypes:{"0":"js:method","1":"js:attribute","2":"js:function"},terms:{"000m":0,"05gb":0,"0gb":0,"0x726564646974":0,"100m":0,"1048576gb":[],"15m":0,"1e3":15,"1gb":0,"200k":0,"200m":0,"25gb":0,"25m":0,"25x":0,"2gb":0,"300m":0,"3087e3":8,"400m":0,"4gb":0,"500m":0,"50e3":15,"50x":0,"55k":0,"5gb":0,"64gb":0,"8gb":[0,6],"boolean":[0,4,5,13],"break":[0,12],"case":[0,5,7,13,15],"catch":[0,8],"class":[0,8,13,14],"default":[0,5,13,14,15],"export":[0,8,10],"final":[1,2],"float":4,"function":[0,1,2,4,6,7,8,9,14,15],"import":[0,1,2,5,8,15],"long":[0,7],"new":[0,5,6,8,10,13,14,15],"null":[0,5,8,10],"public":0,"return":[0,3,5,6,7,10,11,13,14],"short":[0,7],"static":[0,8,10],"super":0,"switch":[0,14],"throw":[0,8],"true":[0,4,5,6,7,8,10,11,13],"try":[0,5,8,10,12,13],"var":9,"while":[0,5,6,8,9,10,13,15],AND:11,Ace:[0,14],Added:0,Adding:4,And:10,But:0,Doing:8,For:[0,3,4,5,6,8,9,10,11,12,15],IPs:[0,5],NOT:[0,5,7,11,13,14,15],Not:13,One:13,THE:0,The:[0,1,3,4,5,6,7,8,9,10,12,13,15],Their:4,Then:[6,8,10,15],There:[0,10],These:[0,3,5,6,8,13,14,15],Use:[0,5,8],Used:0,Using:0,WILL:0,WITH:0,Will:[5,7,14],With:[0,8],Yes:5,_termin:[],abbrevi:15,abil:[0,7],abl:[0,8,13],about:[0,4,5,10,13,15],abov:[0,4,5,10,11,15],accept:[0,13],access:[0,4,5,6,7,8,10,12,13,15],accident:0,account:0,accumul:8,acorn:0,across:0,action:[0,13,14],activ:[0,5,14],actual:[0,5,7,10,13,15],add:[0,6,8,15],added:[0,5],addit:[0,5,6,8,11,13],address:[0,5,15],adjac:15,adjust:0,adr:0,advanc:[1,2],advert:0,advertis:0,aevum:13,affect:[0,5],afford:[5,6],after:[0,4,5,7,10,13,15],afterward:15,again:0,against:0,agenc:[13,14],agent:13,agi:13,agil:13,aid:1,aka:[0,13,14],alexei:0,algorithm:[0,7,13],alia:[0,1],alias:[0,15],all:[0,4,5,6,7,8,10,13,15],allow:[0,7,8,10,13,15],almost:[0,2,8,14],alphabet:[5,15],alphanumer:4,alreadi:[0,5,13,15],also:[0,4,5,7,8,12,13,14,15],alt:[14,15],alter:8,altern:15,although:[0,13],alwai:[8,14],amount:[0,5,6,7,12,13,15],analysi:0,analyt:0,analyz:[0,1,14],ani:[0,1,2,4,5,8,13,14,15],annoi:0,anoth:[0,5,10,12,15],anymor:0,anyon:0,anyth:[0,5],anytim:15,anywher:[5,15],api:[0,1,2],appear:5,append:[0,5],appendchild:8,appli:[0,5,8,13],applic:13,applytocompani:[1,2],approxim:0,arbitrari:0,area:0,arg1:8,arg2:8,arg3:8,arg:[0,5,8,10,12,15],argument:[0,1,2,5,6,7,8,10,13,15],arm:13,armor:0,around:[1,13],arrai:[0,4,5,6,7,10,12,13],arrow:[14,15],artifici:0,aspect:[0,13],assassin:13,assign:[0,6,11],assum:[8,10],async:8,asynchron:8,attack:[0,5],attempt:[0,7,10,13,15],augment:[0,5,7,13,14],augmentationmoneycost:3,augmentationrepcost:3,augnam:13,auto:13,autocomplet:[0,14],autolink:[0,13],autom:[0,6,7],automat:[0,5,7,13],automcomplet:0,autosav:0,avail:[0,4,5,7,8,9,13,14,15],averag:7,avgpx:7,avgpxshort:7,avoid:0,awai:15,await:8,awar:0,awesom:0,b1t_flum3:0,back:[0,10],background:15,backspac:14,backstori:0,backup:8,balanc:0,bar:0,base:[0,5,11],bash:[0,1],basic:[0,1,2,15],becaus:[0,3,5,8,13,15],becom:3,been:[0,1,8],befor:[0,5,8,10],begin:[0,14],being:[0,5,8,15],below:[0,5],benefici:0,benefit:0,best:12,beta:[0,1],better:[0,14],between:[0,3,5,8,10,14,15],big:0,billion:7,binari:[0,1,2],bind:[0,14],bit:0,bitburn:[0,2],bitnod:[0,3,13],bitrunn:0,black:0,blade:0,bladeburn:0,blob:8,block:0,blue:8,bluebird:0,board:0,bond:[0,13],bonu:0,boost:0,both:[0,5,13,15],box:[0,5],bribe:0,brief:[0,10,15],bring:0,broken:0,brokerag:0,browser:[0,8,13,14],brutessh:[0,1,2,13,15],buf:0,bug:0,bugfix:0,bui:[0,1,7,13],build:[0,7],built:0,busi:[0,13],button:0,buystock:[0,1,2],calcul:[0,7],call:[0,1,5,6,8,10,12,13,15],callback:[0,13],can:[0,1,4,5,6,7,8,9,10,12,13,14,15],cancel:[0,7,13,14],cancelord:[1,2],cannot:[0,5,6,8,15],cap:0,capabl:[4,8],capac:0,capit:[0,7],cat:[0,1],caus:[0,5],cave:0,caveat:[8,9],cbscript:13,cellel:8,certain:[0,5,7,10,13],cha:13,chanc:[5,13,15],chang:[0,3,4,5,8,11,15],changelog:1,charact:[4,13,14],characterist:0,charisma:13,cheaper:0,check:[0,1,5,9,13],checkfactioninvit:[0,1,2],chongq:13,choos:0,circuit:0,citi:[0,13,14],citynam:13,classgymexpgain:3,classifi:0,classlist:8,clear:[0,1,2,8,10,14],clearanc:0,clearlog:[0,1,2],click:[0,5,15],cloak:0,close:[0,8,10,14,15],cls:1,code:[0,5,7,8,9,10,11,12],codebas:0,collaps:0,collect:8,color:[0,8,15],com:0,combat:0,come:[8,15],command:[0,1,4,5,13,14],comment:[0,1,2,11],commiss:7,commit:[3,13],commitcrim:[0,1,2],common:0,commonli:15,commun:[7,10],compani:[0,7,13,14],companynam:13,companyworkexpgain:3,companyworkmonei:3,compar:0,compens:0,complet:[0,5,8],comput:[0,5,8,13,15],concat:8,concept:0,condit:[0,1,2],config:0,configur:[0,1,14],confirm:[0,1],connect:[0,1],conquer:0,consid:0,consider:0,consist:0,consol:15,constantli:5,constrain:5,constructor:[0,8],consult:13,contain:[0,3,4,5,6,8,10,13],content:[0,1],continu:[0,13],contract:[0,13],control:13,convers:0,convert:[5,8],copi:[0,5,15],core:[0,5,6,15],corecost:[5,6],corpor:0,corporatocraci:0,correct:13,correspond:6,cosmet:15,cost:[0,5,6,7,13,15],could:[0,15],count:[0,5,15],cours:13,coursenam:13,courtesi:0,cplusplu:[],cpp_static_memb:[],cpu:[0,15],crash:[0,8],creat:[0,5,7,13,14,15],createel:8,createprogram:[1,2],credit:0,crime:[0,3,13],crimeexpgain:3,crimemonei:3,crimin:0,crush:13,ctor:8,ctrl:[0,14],current:[0,1,3,5,7,13,14,15],cursor:14,custom:0,cyberpunk:1,cybersec:0,cycl:[0,14],daedalu:0,dai:[],damag:0,dark:[0,1,13,15],darkweb:0,data:[1,2,5,10,13],datamanc:0,date:[0,1,2],deal:[0,10,13],dealt:0,decid:8,decim:[0,13],declar:[0,4,5,8,9,10,15],declin:0,decreas:[0,5],decrement:[0,11],deepscan:0,deepscanv1:[13,15],deepscanv2:[13,15],def:13,defens:[0,13],defin:[0,1,2,8,14,15],definit:10,delai:[0,5],delet:[0,5,8,14,15],deleteserv:[0,1,2],demand:0,denot:[0,5,10],depend:[0,5,8],depth:15,describ:5,descript:[0,15],design:0,desir:15,destin:[0,5],destroi:0,detail:[0,5,15],determin:[0,5],develop:[0,1,2,8],devoidfuri:0,dex:13,dexter:13,dialog:[0,5],did:0,didn:0,die:0,differ:[0,3,4,5,8,14],differenti:15,difficult:0,difficulti:0,digit:[0,15],diminish:0,directli:8,disabl:[0,5],disablelog:[0,1,2],displai:[0,15],divid:0,divis:[0,11],dni:0,doc:0,document:[0,5,8,9,10,13,14,15],doe:[0,2,5,7,8,10,11,14,15],doesn:0,doing:[0,6,8,10,12],dom:8,don:[0,8,10,13],donat:0,done:[0,14],dont:0,doubl:[0,4,6,15],down:[8,14,15],download:[0,1],drag:0,drawback:0,drug:13,due:[0,5],dure:0,dynam:[0,8,15],dystopian:1,each:[0,6,7,13,15],earli:[0,1],earn:[0,5,6,13],easier:0,easili:0,ecp:7,edg:0,edit:[0,8,14,15],editor:[0,1,15],effect:[0,5],effici:0,either:[4,5,15],element:[0,5,6,7,10,12,13],elif:0,els:[0,9,10,13],emac:14,embark:1,emploi:[13,14],employe:[0,13],empti:[0,5,10,15],emul:[14,15],enabl:[0,5,8,14,15],enable_bash_hotkei:14,enable_timestamp:0,enablelog:[0,1,2],encapsul:4,end:[0,5,6,10,13,14],endgam:0,endpoint:10,enemi:0,energi:0,engin:[0,8,13],enough:[0,5,7],enter:[0,14,15],entiti:0,entri:[0,8],environ:8,equal:[0,11],equival:[4,5,6],error:[0,5,8],esc:14,especi:5,essenti:0,estat:0,estim:[0,15],etc:[0,4,5,8,12,13,15],evalu:[8,10],even:[0,5,7,10,11],eventu:0,everi:[0,5,7,8,10,13,15],everyth:0,exampl:[0,1,2,3,4,5,7,9,10,11,12,13,15],exce:7,exceed:5,except:[0,5,8,14,15],exchang:[0,1,2],exe:[0,5,13,15],exec:[0,1,2,8],execarg:8,execut:[0,5,7,8,10,15],exist:[0,5,6,9,15],exit:[0,1,2],exp:0,expand:15,expens:0,experi:[0,5,8,13],explain:10,explanatori:0,exploit:[0,8],exponenti:0,extens:[0,5,8,13,15],facil:0,facnam:13,fact:0,faction:[0,13,14],factionnam:13,factionpassiverepgain:3,factionworkexpgain:3,factionworkrepgain:3,factor:0,fail:[0,5,13,15],failur:5,fairli:13,fairlyn:13,fals:[0,4,5,6,7,10,11,13],far:13,faster:[0,8],favor:[1,13],fconf:[0,14,15],featur:[0,2,8],fee:7,feed:0,feedback:0,feel:[0,2],few:[0,15],ffffff:15,field:[0,13],fieldwork:13,file:[0,3,5,13,14,15],fileexist:[0,1,2],filenam:[0,5,8,10,15],fill:5,find:[0,5,8],findindex:10,fine:5,finish:[0,13],firefox:[1,2],firewal:0,first:[0,4,5,6,7,10,12,13,15],fisg:7,fit:13,fix:[0,5],fl1ght:0,flag:[0,15],flat:0,fledg:8,flesh:0,floor:10,fn1:10,fn2:10,folder:0,follow:[0,3,4,5,6,8,9,10,13,15],foo1:[5,10],foo2:[5,10],foo3:[5,10],foo4:10,foo:[0,5,8,10,15],foodnstuff:[0,5,8,9,10,15],forc:0,foreach:0,forgeri:[0,13],forgot:0,form:[3,5,6,15],format:0,formula:0,fortifi:0,forward:8,found:0,four:[6,7],fourth:[6,7],fraction:5,framework:0,free:[0,1,2],from:[0,5,7,8,10,12,13,15],ftpcrack:[1,2,13],fulcrum:0,full:[0,8,10,15],fulli:[0,4],fund:0,furthermor:[0,5,8],futur:[0,3,5,14],gain:[0,1,5,13],game:[0,1,3,5,7,8,10,12,13,15],gameplai:0,gang:0,garbag:8,gene:0,gener:[0,5,8,11,12],get:[0,5,8,10,12,13,15],getaugment:0,getaugmentationcost:[1,2],getaugmentationsfromfact:[0,1,2],getbitnodemultipli:[0,1,2],getcharacterinform:[0,1,2],getcompanyfavor:[0,1,2],getcompanyrep:[1,2],getcoreupgradecost:[0,6],getcrimech:[0,1,2],getelementbyid:8,getfactionfavor:[0,1,2],getfactionrep:[1,2],getgrowtim:[0,1,2],gethackinglevel:[1,2],gethackingmultipli:[0,1,2],gethacknetmultipli:[0,1,2,6],gethacktim:[0,1,2],gethostnam:[0,1,2,8],getintellig:0,getip:0,getlevelupgradecost:[0,6],getnexthacknetnodecost:[0,1,2,6],getnumhacknetnod:0,getownedaugment:[1,2],getporthandl:[0,10],getpurchasedserv:[0,1,2],getramupgradecost:[0,6],getscriptexpgain:[0,1,2],getscriptincom:[0,1,2],getscriptnam:[0,1,2],getscriptram:[0,1,2],getserv:0,getserverbasesecuritylevel:[0,1,2],getservergrowth:[0,1,2],getservermaxmonei:[0,1,2],getserverminsecuritylevel:[0,1,2],getservermoneyavail:[0,1,2,9],getservernumportsrequir:[0,1,2],getserverram:[0,1,2,10],getserverrequiredhackinglevel:[0,1,2],getserversecuritylevel:[0,1,2],getstat:[0,1,2],getstockposit:[1,2],getstockpric:[1,2],gettimesincelastaug:[0,1,2],getupgradehomeramcost:[1,2],getweakentim:[0,1,2],ghost:0,github:[0,8],give:[0,3,5,13],given:[0,5,7,13,15],global:[0,5,8,15],global_object:0,globalvari:8,goe:0,going:[0,8],googl:15,governor:0,grand:13,grant:0,great:8,greater:[0,11],greatli:0,grep:[0,5,15],grow:[0,1,2,8,9],grown:9,growth:[0,5],guarante:13,guid:0,gym:[0,13,14],gymnam:13,gymworkout:[0,1,2],hack:[0,1,2,8,9,13,14],hacker:1,hackexpgain:3,hackingcontract:13,hacknet:[0,1,2,5,14],hacknetnod:[0,1,2],hacknetnodemonei:3,had:0,half:0,halt:5,halv:[0,13],hand:[0,15],handbook:0,handl:[0,10],happen:0,happi:8,harder:0,hardwar:0,has:[0,2,3,5,6,8,13,15],hasrootaccess:[0,1,2],have:[0,2,3,5,6,7,8,10,13,15],havoc_mayhem:0,header:[0,15],heist:13,helio:[0,5],hello:5,help:[0,1],her:0,here:[0,1,4,5,7,8,9,10,13,15],hex:[0,8,15],hidden:0,high:0,higher:[0,5],highlight:[0,15],his:0,histori:15,hoist:5,hold:4,home:[0,1,5,13,14],homicid:13,hope:1,hopefulli:0,hospit:0,hostnam:[0,1,5],hotkei:0,how:[0,1,2,4,5,6,9,10,15],howev:[0,5,9,10,15],htm:[],html:0,http:0,httpworm:[1,2,13,15],hydroflam:0,hyphen:4,idea:0,ident:2,identifi:[0,5,15],ifconfig:1,immedi:[0,5,7,13,15],implement:[0,2,10,14],importantinfo:15,improv:[0,2,8],inc:0,includ:[0,4,5,8,13,14,15],incom:[0,5,6],incomplet:0,incorrect:0,incorrectli:0,increas:[0,5],increment:[0,1,11],incur:[0,10],index:[1,5,6],indexeddb:0,indexof:0,indic:[0,5,13,15],individu:[0,15],industri:0,inequ:11,infiltr:0,infinit:8,info:0,inform:[0,1,2,5,13,15],initi:[0,4],innertext:8,input:[0,8,13,14],insan:0,insert:0,insid:[5,6,10],instal:[0,5,7,13],installaugment:[0,1,2],instanc:[0,5,8],instead:[0,3,5,6,8,13],institut:13,instrins:5,instruct:0,integ:[3,4,5,6,7],intellig:[0,13],interact:10,interest:0,interfac:[0,15],interpret:0,interv:0,intuit:0,invalid:[0,5,13],invest:0,investor:0,invit:[0,13],involv:0,iron:[0,13],isbusi:[0,1,2],ishima:13,isinteg:10,isn:0,isrun:[0,1,2],issu:[0,13,15],item:[0,10],iter:[6,9],its:[0,5,7,8,10,15],itself:6,jaguilar:8,javascript:[0,1,2,4,5,8,9],job:[0,8,13,14],jobtitl:13,joesgun:5,join:[0,4,13],joinfact:[1,2],jqueri:0,jshint:0,jump3r:[0,1],just:[0,5,8,10,15],karma:0,keep:0,kei:[0,14,15],kernel:0,keybind:0,keyboard:[0,1,15],keyword:[0,9],kidnap:13,kill:[0,1,2],killal:[0,1,2],know:[0,8,10],label:4,languag:[0,2,4,5],larceni:13,larg:0,last:[0,5,8,10,14],late:0,later:[0,3,4,7,13],latest:0,lead:1,leadership:13,leak:8,least:[0,5,6],left:[0,15],length:[0,5,6,8,12],lenient:13,less:[0,11],let:[0,7,8,9,10,12,15],letter:[4,7],level:[0,5,6,13,15],levelcost:[5,6],librari:[0,10],life:15,lightli:0,like:[0,5,8,10,12,14],limit:[0,5,7,13],limitbui:7,limitsel:7,line:[0,8,10,14],linear:0,linearli:0,link:[0,5,15],list:[0,6,13,15],lit:[0,5,15],literatur:[0,5,15],littl:0,load:[0,8],local:5,localstorag:0,locat:[0,5,13],lock:0,log:[0,5,6,10,14,15],logic:[0,11],longer:0,look:[8,10,12],loop:[0,1,2,8],lore:0,lose:[0,10],lot:[0,8,13],low:0,lower:[0,5],lscpu:[0,1],ltcnugget:0,machin:[0,15],made:[0,7,15],mai:[0,5,8,15],main:8,maintain:0,major:1,make:[0,5,8,12],manag:[0,13],mani:[0,2,4,13],manipul:8,manual:[0,13],manualhackmonei:3,map:6,mark:[0,8,15],market:[0,7],masterscript:15,match:15,mateon1:0,materi:0,math:[0,1,2],matter:15,max:[0,6],maximum:[0,5,15],mayb:[0,10],mean:[0,1,2,3,4,5,6,8,10,13],meant:0,mechan:[0,15],med:0,medic:0,mem:1,member:[0,1,2,4,8,13],memori:[0,5,8,15],mention:0,menu:[0,14,15],messag:[0,1,5,15],method:[0,1,2,4,8,10],mid:0,middl:13,might:0,migrat:0,mild:0,millenium:13,millisecond:[0,5],minigam:0,minimum:[0,5],minor:0,minut:[0,13],misc:[0,1],miscellan:[1,2],mission:[0,14],mode:[0,5,14],modifi:[0,12],modul:[0,1,2,8],modulo:11,monei:[0,1,3,5,6,7,9,13,15],monetari:0,moneygainratepersecond:6,more:[0,4,5,9,14,15],most:[0,4],mostli:0,move:14,mozilla:[0,1,2],mrnuggelz:0,msg:[5,15],much:[0,9,15],mug:13,mult:[3,5,6],multi:[0,10],multidimension:0,multilin:0,multipl:[0,5,8,11,15],multipli:[0,3,5,6,13],multithread:0,must:[0,4,5,6,7,8,10,13,14,15],mute:15,mysteri:1,name:[0,4,5,6,7,11,12,13,15],namespac:10,nano:[0,1,8,14],nativ:0,natur:0,navig:[0,1,15],nearest:[5,6,7],necessari:[0,1,15],need:[0,5,8,10,15],neg:0,negat:[0,11],nerf:0,nest:0,net:7,netscript:[0,1],netscriptj:[0,1,2],netscriptport:10,netsction:0,network:[0,13,15],neuroflux:0,never:[0,8],newer:0,newli:5,newlin:0,next:[5,14],nitesec:0,node:[0,1,2,5,14,15],non:15,none:[5,6],normal:[0,10,12,13],noscript:0,notabl:[0,5],note:[0,1,2,5,6,10,13,14,15],notifi:0,now:[0,1,8,10,15],nuke:[0,1,2,15],num:15,number:[0,1,2,4,5,6,7,8,11,12,13,15],numer:[0,4,7,11],numthread:[0,5,10],object:[0,3,4,5,6,8,13],observ:0,obtain:5,obvious:13,occur:0,off:0,offic:0,offici:0,offlin:[0,5],old:0,omit:[5,15],onc:[0,15],one:[0,5,6,8,9,10,13],ones:0,onli:[0,3,5,6,7,8,10,11,13,14,15],onlin:[0,5],onlinetimesecond:6,onto:4,open:[0,5,8,10,13,14,15],oper:[0,1,2,10,12],operand:11,optim:1,option:[0,5,8,13,14,15],order:[0,3,5,7,13,15],org:0,origin:3,osx:0,other:[0,5,8,10,13,14],otherwis:[0,5,6,7,9,10,13,14,15],our:10,oustand:[0,7,13],out:[0,2,5,10,13],outdat:0,output:5,outsid:[0,5,13],outstand:0,over:[0,5,8],overclock:0,overrid:14,overwrit:[0,5],own:[0,1,2,7,8,15],page:[0,1,3,5,8,10,13,14,15],param:8,paramet:[0,5,15],pars:[0,10],parser:0,part:[0,13,15],particular:13,pass:[0,5,8,10,12,13,15],passiv:0,past:0,path:15,pattern:[0,15],peek:[0,1,2,10],peopl:8,per:0,percentag:[0,5,6],perform:[0,13],perman:15,persist:0,pheromon:0,pick:0,picker:15,pill:0,place:7,placeord:[1,2],plai:1,plan:12,player:[0,1,5,6,7,12,13,15],pleas:[0,8],plenti:8,plot:0,point:[0,8],pointer:0,pop:[0,4,10],popular:0,popup:0,port:[0,1,2,5,15],portfolio:0,pos:7,posit:[0,4,6,7,13],possibl:[0,8,12],post:8,pound:15,power:[0,1,5,8],powerhous:13,pre:[0,8,11],preced:15,prefac:8,prefix:0,prerequisit:0,preset:[14,15],press:0,prestig:0,prevent:12,preventdefault:0,previou:[0,14],previous:0,price:[0,7],primarili:8,primit:4,print:[0,1,2,3,6,8,10,13,15],privat:0,problem:0,process:[0,5],prod:0,produc:[0,11],product:[0,5,6],profit:[0,7],program:[0,2,5,13,14,15],programat:0,programnam:13,progress:0,promis:0,promot:[0,13],prompt:[0,1,2,8],proper:0,properli:0,properti:[0,13],protocol:7,prototyp:8,provid:[0,6,7],pserv:5,puchas:0,purchas:[0,1,2,5,7,13,15],purchaseaugment:[1,2],purchasecost:[5,6],purchasedserver1:8,purchasehacknetnod:[0,1,2,6],purchaseprogram:[1,2],purchaseserv:[0,1,2],purchasetor:[1,2],purpos:[4,5],push:0,put:[3,11],qualifi:0,qualiti:0,queri:0,quest:1,queue:[0,5,10],quickli:[0,5],quit:0,quot:4,quotat:15,rais:[0,5],ram:[0,5,6,10,13,15],ramcost:[5,6],ramus:5,ran:[0,5,8,10,15],random:0,randomarg:8,rank:0,rate:[0,5],rather:[0,8,15],reach:[0,2,15],read:[0,1,2,4,6,10],readthedoc:0,real:[0,15],realli:0,reason:[0,5],rebalanc:1,receiv:[0,3,13],recommend:[8,13],record:0,recurs:0,red:[0,8],reddit:0,reduc:[0,8],refactor:0,refer:[0,4,9],referenc:[0,4],reflect:7,refresh:[0,8],regain:0,regard:0,regardless:[0,5],reject:0,rel:[0,15],relat:[5,6,10,15],relaysmtp:[1,2,13],releas:[0,8],relev:[0,3],reload:[0,8,10],remain:0,rememb:[5,7,8,15],remot:15,remov:[0,5,10,15],rep:0,repeat:0,repeatedli:[0,8],replac:[0,15],report:[0,8],repres:[0,3,4,5,7,10,15],reput:[0,13],request:2,requir:[0,3,5,10,11,13,15],res:[5,10,13],research:0,reset:[0,5,7,13],resolv:5,respect:[0,15],respons:8,rest:[0,4],restart:[0,13],result:[0,5,8,11],retain:[0,7],reusabl:15,revert:5,reward:0,right:[0,10],risk:8,rob:13,robot:0,role:1,room:10,root:[5,15],rothman:[5,13],round:[0,5,6,7],router:[0,13,15],rowel:8,rpg:1,rule:8,run:[0,1,2,3,8,9,10,11,12,13],runarg:8,runtim:[0,5],safe:8,sai:[5,12],sake:10,salari:0,sale:[0,7],same:[0,5,8,9,10,13,14,15],satisfi:0,save:[0,8,10,14],scale:0,scan:[0,1,2],schedul:[8,13],scheme:15,scienc:13,scientif:0,scope:[5,8],scp:[0,1,2,8],screen:[0,14,15],screw:0,script:[0,1,2,5,6,7,8,10,13,15],scripthackmonei:3,scriptjob:8,scriptkil:[0,1,2],scriptnam:[0,5],scriptrun:[0,1,2],scriptschedul:8,scroll:0,search:[1,5],second:[0,4,5,6,7,12,13,15],secondari:0,secret:[0,1],section:[2,5],sector:13,secur:[0,5,13],securitywork:13,see:[0,5,6,8,9,15],select:[0,5],self:0,sell:[0,7],sellshort:[0,1,2],sellstock:[0,1,2],semicolon:0,sensit:[0,5,7,13,15],sent:0,separ:[3,5,15],sequenc:[4,7],sequenti:8,serial:[0,5,10],seriou:8,server:[0,5,9,15],serverexist:[0,1,2],servergrowthr:3,servermaxmonei:3,serverprofil:[0,13],serverstartingmonei:3,serverstartingsecur:3,serverweakenr:3,set:[0,5,8,13,14,15],sever:[0,10],share:[0,7,8],sharesshort:7,she:1,shell:14,shield:0,shift:0,shoplift:13,shortcut:[0,1,15],shorthand:0,shortstock:[0,1,2],should:[0,5,9,13,15],show:[0,4,5,8,9,15],shown:[5,15],side:15,sigma:15,sign:15,signatur:[0,5,8],signific:[0,5],significantli:[0,8],similar:[0,5],simpl:[8,9,10],simplest:5,simpli:[2,4],simplic:10,sinc:[0,5,8,10],singl:[0,4,5,11,15],singular:[0,1,2],situat:8,size:0,skill:[0,5],sleep:[0,1,2,6,8,10,13],slice:10,slight:0,slightli:0,slow:8,slower:0,slowli:0,small:[0,8,13],smaller:0,smart:0,snap:13,soft:0,softwar:[0,13],solar:15,sold:7,some:[0,5,8,9,10,11,13],some_valu:5,someth:1,sometim:0,someval1:10,someval2:10,soon:0,sorri:0,sort:[0,5,10],sourc:[0,3,5,13],space:[0,14,15],spaceglac:0,spam:0,spawn:[0,1,2],special:[0,4,6,12,13],specif:[0,5,10],specifi:[0,5,6,7,10,12,13,15],speed:[0,5],splice:[0,4],spoiler:[0,3,13],sprintf:[0,1,2],sqlinject:[1,2,13],stack:0,stage:[0,1],stai:5,stamina:0,start:[0,4,5,8,10,13,15],starter:0,stat:[0,13,14],state:0,statement:[0,9],statist:[0,7,15],steal:[0,5],still:[0,5,8,15],stock:[0,7],stolen:[0,5],stop:[0,5,7,13,15],stopact:[0,1,2],stopbui:7,stopsel:7,storag:0,store:[4,13],str:13,strategi:7,street:0,strength:13,strict:11,string:[0,4,5,7,13,15],structur:[3,5,6,10],strucur:13,studi:[0,13],stupid:0,style:[0,8],subject:3,subreddit:0,subset:2,substitut:15,substr:5,subtract:11,success:[0,5,7,13],successfulli:[0,5,6,7,10,13,15],sudov:1,suggest:2,sum:[0,5],summari:8,summit:13,suppli:0,support:[0,4,6,7,8,10,15],suppos:10,suppress:0,sure:0,suspend:5,suspicion:1,sym:7,symbol:7,syntax:[0,2,5,10],system:[1,7],tab:[0,8,14,15],tail:[0,1],take:[0,1,5,13,14,15],target:[0,5,8,15],task:0,technolgi:0,technolog:[0,13],tell:0,templat:5,ten:9,term:[0,13],termin:[0,1,5,8,13],terminalinput:8,territori:0,test2:[],test:[0,5,8],testlib:10,testlibrari:10,text:[0,4,5,8,15],than:[0,5,8,9,11,15],thank:0,theft:13,thei:[0,2,3,5,8,14,15],them:[0,5,10,13],theme:[0,1],themselv:0,therefor:[0,8],theres:0,thi:[0,1,2,3,4,5,6,7,8,10,11,12,13,14,15],thing:15,think:0,third:[0,5,7],those:[5,6,8],though:[0,5,10],thought:[4,8],thread:[0,5,8,12,13,15],three:[4,5,8,10,14,15],through:[0,5,6,8,10,13,14,15],throughout:0,thrown:8,tier:0,time:[0,5,6,8,9,10,13,15],timework:13,tini:2,tip:0,tix:[0,1,2],todo:15,tokyo:13,tolocalestr:0,tolowercas:4,too:0,tooltip:0,top:[0,1,8],tor:[0,13,15],total:[0,5,6,15],totalmoneygener:6,totalram:5,toward:0,tprint:[0,1,2,8,10],tprintcolor:8,tracer:0,track:0,trade:[0,1,2],traffick:13,train:[0,13,14],transact:[0,7],transfer:0,travel:[0,13,14],traveltoc:[1,2],travers:9,treat:0,trend:0,tri:[5,6,15],trigger:0,troubl:0,trywrit:[0,10],tutori:[0,14],tutorialspoint:[],tweak:0,two:[0,5,7,8,10,11,12,13],txt:[0,5,8,15],type:[0,1,2,5,7,8,13,15],typic:5,typo:0,unabl:8,unalia:[0,1],unalias_terminal_command:[],unari:[1,2],uncov:1,undefin:0,underli:[0,5,10],underscor:4,undo:15,undon:15,uni:5,uniqu:[0,5,8,15],univeristi:13,univers:[0,13,14],universitycours:[1,2],universitynam:13,unknown:1,unless:[0,14],unlik:8,unlock:[0,7,13],unrecogn:0,until:[0,5,6,13],untyp:4,updat:[0,13],upgrad:[0,6,13],upgradecor:6,upgradehacknetnod:0,upgradehomeram:[1,2],upgradelevel:6,upgraderam:6,upon:0,url:8,usag:[0,5,10,15],use:[0,1,2,5,7,9,10,13,15],useabl:0,used:[0,2,4,5,6,7,10,13,14,15],useful:0,user:[0,8,15],uses:[0,8,9],using:[0,5,6,7,8,9,10,12,13,15],usual:13,utc:[0,10],util:[0,1,2],valid:[0,5,10,13,15],valu:[0,3,4,5,6,7,8,10,11,13,15],valuat:0,vari:5,variabl:[0,1,2,5,8,9,11,15],varieti:0,variou:[0,13,14],vechain:0,vehicl:0,veri:[0,8],version:8,via:0,viabl:0,view:0,vim:[0,14],visibl:8,visit:[0,7,13],volatil:0,volhaven:13,vsprintf:[0,1,2],w0r1d_d43m0n:0,waer:0,wage:0,wai:[0,5,6,10,13,15],wait:[0,10],waiter:13,wall:0,want:[0,6,8,10,12,13,15],warehous:0,warn:[0,1,2,11,12,13,15],wasn:0,water:0,weaken:[0,1,2,8],weapon:0,web:[0,8,13,15],webpack:0,week:[],well:[0,4,8,14,15],were:[0,5,13,14,15],wese:7,what:[0,5,6,8,13,15],whatev:13,when:[0,1,2,5,8,9,10,13,15],whenev:0,where:[0,1,5,8,10,14],whether:[0,5,7,13,15],which:[0,4,5,6,7,10,13,15],whitespac:[0,5],who:[0,8],whose:15,wiki:0,wikia:0,wilson:0,win:0,window:14,within:8,without:[0,5,8,10,15],won:0,word:[0,5,14,15],work:[0,5,7,8,10,11,13,14,15],workagiexpgain:13,workchaexpgain:13,workdefexpgain:13,workdexexpgain:13,workforcompani:[1,2],workforfact:[1,2],workhackexpgain:13,workmoneygain:13,workrepgain:13,workstrexpgain:13,worktyp:13,world:[0,1,2,5,7],worm:15,would:[0,3,11,12,13,15],wouldnt:0,wraithan:0,wrap:0,write:[0,1,2,6,7,8,10],written:[2,5,10],wrong:1,wrote:10,wse:[0,7],www:[],x10:0,yet:[0,5,13],you:[0,1,2,3,4,5,6,7,8,9,10,11,13,14,15],your:[0,1,2,6,7,8,13,14,15],yourself:[0,6],zero:[0,5],zeu:0,zeud:0,zip:[0,15]},titles:["Changelog","Welcome to Bitburner's documentation!","Netscript Documentation","Netscript Advanced Functions","Netscript Data Types and Variables","Netscript Basic Functions","Netscript Hacknet Node API","Netscript Trade Information eXchange (TIX) API","NetscriptJS (Netscript 2.0)","Netscript Loops and Conditionals","Netscript Miscellaneous","Netscript Operators","Netscript Script Arguments","Netscript Singularity Functions","Keyboard Shortcuts","Terminal"],titleterms:{"final":8,"function":[3,5,10,13],"import":10,advanc:3,alia:15,analyz:15,api:[6,7],applytocompani:13,argument:12,bash:14,basic:5,binari:11,bitburn:1,brutessh:5,bui:15,buystock:7,cancelord:7,cat:15,changelog:0,check:15,checkfactioninvit:13,clear:[5,15],clearlog:5,cls:15,command:15,comment:10,commitcrim:13,condit:9,configur:15,connect:15,createprogram:13,data:4,date:10,defin:5,deleteserv:5,disablelog:5,document:[1,2],dom:[],download:15,editor:14,enablelog:5,exampl:[6,8],exchang:7,exec:5,exit:5,favor:0,fileexist:5,firefox:8,free:15,ftpcrack:5,game:14,getaugmentationcost:13,getaugmentationsfromfact:13,getbitnodemultipli:3,getcharacterinform:13,getcompanyfavor:13,getcompanyrep:13,getcrimech:13,getfactionfavor:13,getfactionrep:13,getgrowtim:5,gethackinglevel:5,gethackingmultipli:5,gethacknetmultipli:5,gethacktim:5,gethostnam:5,getnexthacknetnodecost:5,getownedaugment:13,getpurchasedserv:5,getscriptexpgain:5,getscriptincom:5,getscriptnam:5,getscriptram:5,getserverbasesecuritylevel:5,getservergrowth:5,getservermaxmonei:5,getserverminsecuritylevel:5,getservermoneyavail:5,getservernumportsrequir:5,getserverram:5,getserverrequiredhackinglevel:5,getserversecuritylevel:5,getstat:13,getstockposit:7,getstockpric:7,gettimesincelastaug:5,getupgradehomeramcost:13,getweakentim:5,grow:5,gymworkout:13,hack:[5,15],hacknet:6,hacknetnod:6,handl:[],hasrootaccess:5,help:15,home:15,hostnam:15,how:8,httpworm:5,ifconfig:15,indic:1,inform:7,installaugment:13,isbusi:13,isrun:5,javascript:10,joinfact:13,keyboard:14,kill:[5,15],killal:[5,15],loop:9,lscpu:15,major:0,manipul:[],math:10,mem:15,member:6,method:6,misc:14,miscellan:10,modul:10,mozilla:8,nano:15,navig:14,netscript:[2,3,4,5,6,7,8,9,10,11,12,13],netscriptj:8,node:6,note:8,nuke:5,number:10,oper:11,optim:0,own:5,peek:5,placeord:7,port:10,print:5,prompt:5,purchas:6,purchaseaugment:13,purchasehacknetnod:5,purchaseprogram:13,purchaseserv:5,purchasetor:13,read:5,rebalanc:0,relaysmtp:5,round:[],run:[5,15],scan:[5,15],scp:[5,15],script:[12,14],scriptkil:5,scriptrun:5,sellshort:7,sellstock:7,serverexist:5,shortcut:14,shortstock:7,singular:13,sleep:5,spawn:5,sprintf:5,sqlinject:5,stopact:13,sudov:15,system:0,tabl:1,tail:15,termin:[14,15],theme:15,tix:7,top:15,tprint:5,trade:7,traveltoc:13,type:4,unalia:15,unari:11,universitycours:13,upgradehomeram:13,usag:[],use:8,util:6,variabl:[4,6],vsprintf:5,warn:8,weaken:5,welcom:1,what:1,workforcompani:13,workforfact:13,write:5,your:5}}) \ No newline at end of file +Search.setIndex({docnames:["changelog","index","netscript","netscriptadvancedfunctions","netscriptdatatypes","netscriptfunctions","netscripthacknetnodeapi","netscriptixapi","netscriptjs","netscriptloopsandconditionals","netscriptmisc","netscriptoperators","netscriptscriptarguments","netscriptsingularityfunctions","shortcuts","terminal"],envversion:53,filenames:["changelog.rst","index.rst","netscript.rst","netscriptadvancedfunctions.rst","netscriptdatatypes.rst","netscriptfunctions.rst","netscripthacknetnodeapi.rst","netscriptixapi.rst","netscriptjs.rst","netscriptloopsandconditionals.rst","netscriptmisc.rst","netscriptoperators.rst","netscriptscriptarguments.rst","netscriptsingularityfunctions.rst","shortcuts.rst","terminal.rst"],objects:{"":{applyToCompany:[13,2,1,""],buyStock:[7,2,1,""],cancelOrder:[7,2,1,""],checkFactionInvitations:[13,2,1,""],clearLog:[5,2,1,""],commitCrime:[13,2,1,""],createProgram:[13,2,1,""],deleteServer:[5,2,1,""],disableLog:[5,2,1,""],enableLog:[5,2,1,""],fileExists:[5,2,1,""],getAugmentationCost:[13,2,1,""],getAugmentationsFromFaction:[13,2,1,""],getBitNodeMultipliers:[3,2,1,""],getCompanyFavor:[13,2,1,""],getCompanyRep:[13,2,1,""],getCrimeChance:[13,2,1,""],getFactionFavor:[13,2,1,""],getFactionRep:[13,2,1,""],getGrowTime:[5,2,1,""],getHackTime:[5,2,1,""],getHackingLevel:[5,2,1,""],getHackingMultipliers:[5,2,1,""],getHacknetMultipliers:[5,2,1,""],getHostname:[5,2,1,""],getNextHacknetNodeCost:[5,2,1,""],getOwnedAugmentations:[13,2,1,""],getPurchasedServers:[5,2,1,""],getScriptExpGain:[5,2,1,""],getScriptIncome:[5,2,1,""],getScriptName:[5,2,1,""],getScriptRam:[5,2,1,""],getServerBaseSecurityLevel:[5,2,1,""],getServerGrowth:[5,2,1,""],getServerMaxMoney:[5,2,1,""],getServerMinSecurityLevel:[5,2,1,""],getServerMoneyAvailable:[5,2,1,""],getServerNumPortsRequired:[5,2,1,""],getServerRam:[5,2,1,""],getServerRequiredHackingLevel:[5,2,1,""],getServerSecurityLevel:[5,2,1,""],getStats:[13,2,1,""],getStockPosition:[7,2,1,""],getStockPrice:[7,2,1,""],getTimeSinceLastAug:[5,2,1,""],getUpgradeHomeRamCost:[13,2,1,""],getWeakenTime:[5,2,1,""],gymWorkout:[13,2,1,""],hasRootAccess:[5,2,1,""],installAugmentations:[13,2,1,""],isBusy:[13,2,1,""],isRunning:[5,2,1,""],joinFaction:[13,2,1,""],placeOrder:[7,2,1,""],purchaseAugmentation:[13,2,1,""],purchaseHacknetNode:[5,2,1,""],purchaseProgram:[13,2,1,""],purchaseServer:[5,2,1,""],purchaseTor:[13,2,1,""],scriptKill:[5,2,1,""],scriptRunning:[5,2,1,""],sellShort:[7,2,1,""],sellStock:[7,2,1,""],serverExists:[5,2,1,""],shortStock:[7,2,1,""],stopAction:[13,2,1,""],travelToCity:[13,2,1,""],universityCourse:[13,2,1,""],upgradeHomeRam:[13,2,1,""],workForCompany:[13,2,1,""],workForFaction:[13,2,1,""]},"hacknetnodes[i]":{cores:[6,1,1,""],getCoreUpgradeCost:[6,0,1,""],getLevelUpgradeCost:[6,0,1,""],getRamUpgradeCost:[6,0,1,""],level:[6,1,1,""],moneyGainRatePerSecond:[6,1,1,""],name:[6,1,1,""],onlineTimeSeconds:[6,1,1,""],ram:[6,1,1,""],totalMoneyGenerated:[6,1,1,""],upgradeCore:[6,0,1,""],upgradeLevel:[6,0,1,""],upgradeRam:[6,0,1,""]},NetscriptPort:{clear:[10,0,1,""],data:[10,1,1,""],empty:[10,0,1,""],full:[10,0,1,""],tryWrite:[10,0,1,""],write:[10,0,1,""]}},objnames:{"0":["js","method","JavaScript method"],"1":["js","attribute","JavaScript attribute"],"2":["js","function","JavaScript function"]},objtypes:{"0":"js:method","1":"js:attribute","2":"js:function"},terms:{"000m":0,"05gb":0,"0gb":0,"0x726564646974":0,"100m":0,"1048576gb":[],"15m":0,"1e3":15,"1gb":0,"200k":0,"200m":0,"250m":0,"25gb":0,"25m":0,"25x":0,"2gb":0,"300m":0,"3087e3":8,"400m":0,"4gb":0,"500m":0,"50e3":15,"50x":0,"55k":0,"5gb":0,"64gb":0,"8gb":[0,6],"boolean":[0,4,5,13],"break":[0,12],"case":[0,5,7,13,15],"catch":[0,8],"class":[0,8,13,14],"default":[0,5,13,14,15],"export":[0,8,10],"final":[1,2],"float":4,"function":[0,1,2,4,6,7,8,9,14,15],"import":[0,1,2,5,8,15],"long":[0,7],"new":[0,5,6,8,10,13,14,15],"null":[0,5,8,10],"public":0,"return":[0,3,5,6,7,10,11,13,14],"short":[0,7],"static":[0,8,10],"super":0,"switch":[0,14],"throw":[0,8],"true":[0,4,5,6,7,8,10,11,13],"try":[0,5,8,10,12,13],"var":9,"while":[0,5,6,8,9,10,13,15],AND:11,Ace:[0,14],Added:0,Adding:4,And:10,But:0,Doing:8,For:[0,3,4,5,6,8,9,10,11,12,15],IPs:[0,5],NOT:[0,5,7,11,13,14,15],Not:13,One:13,THE:0,The:[0,1,3,4,5,6,7,8,9,10,12,13,15],Their:4,Then:[6,8,10,15],There:[0,10],These:[0,3,5,6,8,13,14,15],Use:[0,5,8],Used:0,Using:0,WILL:0,WITH:0,Will:[5,7,14],With:[0,8],Yes:5,_termin:[],abbrevi:15,abil:[0,7],abl:[0,8,13],about:[0,4,5,10,13,15],abov:[0,4,5,10,11,15],accept:[0,13],access:[0,4,5,6,7,8,10,12,13,15],accident:0,account:0,accumul:8,acorn:0,across:0,action:[0,13,14],activ:[0,5,14],actual:[0,5,7,10,13,15],add:[0,6,8,15],added:[0,5],addit:[0,5,6,8,11,13],address:[0,5,15],adjac:15,adjust:0,adr:0,advanc:[1,2],advert:0,advertis:0,aevum:13,affect:[0,5],afford:[5,6],after:[0,4,5,7,10,13,15],afterward:15,again:0,against:0,agenc:[13,14],agent:13,agi:13,agil:13,aid:1,aka:[0,13,14],alexei:0,algorithm:[0,7,13],alia:[0,1],alias:[0,15],all:[0,4,5,6,7,8,10,13,15],allow:[0,7,8,10,13,15],almost:[0,2,8,14],alphabet:[5,15],alphanumer:4,alreadi:[0,5,13,15],also:[0,4,5,7,8,12,13,14,15],alt:[14,15],alter:8,altern:15,although:[0,13],alwai:[8,14],amount:[0,5,6,7,12,13,15],analysi:0,analyt:0,analyz:[0,1,14],ani:[0,1,2,4,5,8,13,14,15],annoi:0,anoth:[0,5,10,12,15],anymor:0,anyon:0,anyth:[0,5],anytim:15,anywher:[5,15],api:[0,1,2],appear:5,append:[0,5],appendchild:8,appli:[0,5,8,13],applic:13,applytocompani:[1,2],approxim:0,arbitrari:0,area:0,arg1:8,arg2:8,arg3:8,arg:[0,5,8,10,12,15],argument:[0,1,2,5,6,7,8,10,13,15],arm:13,armor:0,around:[1,13],arrai:[0,4,5,6,7,10,12,13],arrow:[14,15],artifici:0,aspect:[0,13],assassin:13,assign:[0,6,11],assum:[8,10],async:8,asynchron:8,attack:[0,5],attempt:[0,7,10,13,15],augment:[0,5,7,13,14],augmentationmoneycost:3,augmentationrepcost:3,augnam:13,auto:13,autocomplet:[0,14],autolink:[0,13],autom:[0,6,7],automat:[0,5,7,13],automcomplet:0,autosav:0,avail:[0,4,5,7,8,9,13,14,15],averag:7,avgpx:7,avgpxshort:7,avoid:0,awai:15,await:8,awar:0,awesom:0,b1t_flum3:0,back:[0,10],background:15,backspac:14,backstori:0,backup:8,balanc:0,bar:0,base:[0,5,11],bash:[0,1],basic:[0,1,2,15],becaus:[0,3,5,8,13,15],becom:3,been:[0,1,8],befor:[0,5,8,10],begin:[0,14],being:[0,5,8,15],below:[0,5],benefici:0,benefit:0,best:12,beta:[0,1],better:[0,14],between:[0,3,5,8,10,14,15],big:0,billion:7,binari:[0,1,2],bind:[0,14],bit:0,bitburn:[0,2],bitnod:[0,3,13],bitrunn:0,black:0,blade:0,bladeburn:0,blob:8,block:0,blue:8,bluebird:0,board:0,bond:[0,13],bonu:0,boost:0,both:[0,5,13,15],box:[0,5],bribe:0,brief:[0,10,15],bring:0,broken:0,brokerag:0,browser:[0,8,13,14],brutessh:[0,1,2,13,15],buf:0,bug:0,bugfix:0,bui:[0,1,7,13],build:[0,7],built:0,busi:[0,13],button:0,buystock:[0,1,2],calcul:[0,7],call:[0,1,5,6,8,10,12,13,15],callback:[0,13],can:[0,1,4,5,6,7,8,9,10,12,13,14,15],cancel:[0,7,13,14],cancelord:[1,2],cannot:[0,5,6,8,15],cap:0,capabl:[4,8],capac:0,capit:[0,7],cat:[0,1],caus:[0,5],cave:0,caveat:[8,9],cbscript:13,cellel:8,certain:[0,5,7,10,13],cha:13,chanc:[5,13,15],chang:[0,3,4,5,8,11,15],changelog:1,charact:[4,13,14],characterist:0,charisma:13,cheaper:0,check:[0,1,5,9,13],checkfactioninvit:[0,1,2],chongq:13,choos:0,circuit:0,citi:[0,13,14],citynam:13,classgymexpgain:3,classifi:0,classlist:8,clear:[0,1,2,8,10,14],clearanc:0,clearlog:[0,1,2],click:[0,5,15],cloak:0,close:[0,8,10,14,15],cls:1,code:[0,5,7,8,9,10,11,12],codebas:0,collaps:0,collect:8,color:[0,8,15],com:0,combat:0,come:[8,15],command:[0,1,4,5,13,14],comment:[0,1,2,11],commiss:7,commit:[3,13],commitcrim:[0,1,2],common:0,commonli:15,commun:[7,10],compani:[0,7,13,14],companynam:13,companyworkexpgain:3,companyworkmonei:3,compar:0,compens:0,complet:[0,5,8],comput:[0,5,8,13,15],concat:8,concept:0,condit:[0,1,2],config:0,configur:[0,1,14],confirm:[0,1],connect:[0,1],conquer:0,consid:0,consider:0,consist:0,consol:15,constantli:5,constrain:5,constructor:[0,8],consult:13,contain:[0,3,4,5,6,8,10,13],content:[0,1],continu:[0,13],contract:[0,13],control:13,convers:0,convert:[5,8],copi:[0,5,15],core:[0,5,6,15],corecost:[5,6],corpor:0,corporatocraci:0,correct:13,correspond:6,cosmet:15,cost:[0,5,6,7,13,15],could:[0,15],count:[0,5,15],cours:13,coursenam:13,courtesi:0,cplusplu:[],cpp_static_memb:[],cpu:[0,15],crash:[0,8],creat:[0,5,7,13,14,15],createel:8,createprogram:[1,2],credit:0,crime:[0,3,13],crimeexpgain:3,crimemonei:3,crimin:0,crush:13,ctor:8,ctrl:[0,14],current:[0,1,3,5,7,13,14,15],cursor:14,custom:0,cyberpunk:1,cybersec:0,cycl:[0,14],daedalu:0,dai:[],damag:0,dark:[0,1,13,15],darkweb:0,data:[1,2,5,10,13],datamanc:0,date:[0,1,2],deal:[0,10,13],dealt:0,decid:8,decim:[0,13],declar:[0,4,5,8,9,10,15],declin:0,decreas:[0,5],decrement:[0,11],deepscan:0,deepscanv1:[13,15],deepscanv2:[13,15],def:13,defens:[0,13],defin:[0,1,2,8,14,15],definit:10,delai:[0,5],delet:[0,5,8,14,15],deleteserv:[0,1,2],demand:0,denot:[0,5,10],depend:[0,5,8],depth:15,describ:5,descript:[0,15],design:0,desir:15,destin:[0,5],destroi:0,detail:[0,5,15],determin:[0,5],develop:[0,1,2,8],devoidfuri:0,dex:13,dexter:13,dialog:[0,5],did:0,didn:0,die:0,differ:[0,3,4,5,8,14],differenti:15,difficult:0,difficulti:0,digit:[0,15],diminish:0,directli:[0,8],disabl:[0,5],disablelog:[0,1,2],displai:[0,15],divid:0,divis:[0,11],dni:0,doc:0,document:[0,5,8,9,10,13,14,15],doe:[0,2,5,7,8,10,11,14,15],doesn:0,doing:[0,6,8,10,12],dom:8,don:[0,8,10,13],donat:0,done:[0,14],dont:0,doubl:[0,4,6,15],down:[8,14,15],download:[0,1],drag:0,drawback:0,drug:13,due:[0,5],dure:0,dynam:[0,8,15],dystopian:1,each:[0,6,7,13,15],earli:[0,1],earn:[0,5,6,13],easier:0,easili:0,ecp:7,edg:0,edit:[0,8,14,15],editor:[0,1,15],effect:[0,5],effici:0,either:[4,5,15],element:[0,5,6,7,10,12,13],elif:0,els:[0,9,10,13],emac:14,embark:1,emploi:[13,14],employe:[0,13],empti:[0,5,10,15],emul:[14,15],enabl:[0,5,8,14,15],enable_bash_hotkei:14,enable_timestamp:0,enablelog:[0,1,2],encapsul:4,end:[0,5,6,10,13,14],endgam:0,endpoint:10,enemi:0,energi:0,engin:[0,8,13],enough:[0,5,7],enter:[0,14,15],entiti:0,entri:[0,8],environ:8,equal:[0,11],equival:[4,5,6],error:[0,5,8],esc:14,especi:5,essenti:0,estat:0,estim:[0,15],etc:[0,4,5,8,12,13,15],evalu:[8,10],even:[0,5,7,10,11],eventu:0,everi:[0,5,7,8,10,13,15],everyth:0,exampl:[0,1,2,3,4,5,7,9,10,11,12,13,15],exce:7,exceed:5,except:[0,5,8,14,15],exchang:[0,1,2],exe:[0,5,13,15],exec:[0,1,2,8],execarg:8,execut:[0,5,7,8,10,15],exist:[0,5,6,9,15],exit:[0,1,2],exp:0,expand:15,expens:0,experi:[0,5,8,13],explain:10,explanatori:0,exploit:[0,8],exponenti:0,extens:[0,5,8,13,15],facil:0,facnam:13,fact:0,faction:[0,13,14],factionnam:13,factionpassiverepgain:3,factionworkexpgain:3,factionworkrepgain:3,factor:0,fail:[0,5,13,15],failur:5,fairli:13,fairlyn:13,fals:[0,4,5,6,7,10,11,13],far:13,faster:[0,8],favor:[1,13],fconf:[0,14,15],featur:[0,2,8],fee:7,feed:0,feedback:0,feel:[0,2],few:[0,15],ffffff:15,field:[0,13],fieldwork:13,file:[0,3,5,13,14,15],fileexist:[0,1,2],filenam:[0,5,8,10,15],fill:5,find:[0,5,8],findindex:10,fine:5,finish:[0,13],firefox:[1,2],firewal:0,first:[0,4,5,6,7,10,12,13,15],fisg:7,fit:13,fix:[0,5],fl1ght:0,flag:[0,15],flat:0,fledg:8,flesh:0,floor:10,fn1:10,fn2:10,folder:0,follow:[0,3,4,5,6,8,9,10,13,15],foo1:[5,10],foo2:[5,10],foo3:[5,10],foo4:10,foo:[0,5,8,10,15],foodnstuff:[0,5,8,9,10,15],forc:0,foreach:0,forgeri:[0,13],forgot:0,form:[3,5,6,15],format:0,formula:0,fortifi:0,forward:8,found:0,four:[6,7],fourth:[6,7],fraction:5,framework:0,free:[0,1,2],from:[0,5,7,8,10,12,13,15],ftpcrack:[1,2,13],fulcrum:0,full:[0,8,10,15],fulli:[0,4],fund:0,furthermor:[0,5,8],futur:[0,3,5,14],gain:[0,1,5,13],game:[0,1,3,5,7,8,10,12,13,15],gameplai:0,gang:0,garbag:8,gene:0,gener:[0,5,8,11,12],get:[0,5,8,10,12,13,15],getaugment:0,getaugmentationcost:[1,2],getaugmentationsfromfact:[0,1,2],getbitnodemultipli:[0,1,2],getcharacterinform:[0,1,2],getcompanyfavor:[0,1,2],getcompanyrep:[1,2],getcoreupgradecost:[0,6],getcrimech:[0,1,2],getelementbyid:8,getfactionfavor:[0,1,2],getfactionrep:[1,2],getgrowtim:[0,1,2],gethackinglevel:[1,2],gethackingmultipli:[0,1,2],gethacknetmultipli:[0,1,2,6],gethacktim:[0,1,2],gethostnam:[0,1,2,8],getintellig:0,getip:0,getlevelupgradecost:[0,6],getnexthacknetnodecost:[0,1,2,6],getnumhacknetnod:0,getownedaugment:[1,2],getporthandl:[0,10],getpurchasedserv:[0,1,2],getramupgradecost:[0,6],getscriptexpgain:[0,1,2],getscriptincom:[0,1,2],getscriptnam:[0,1,2],getscriptram:[0,1,2],getserv:0,getserverbasesecuritylevel:[0,1,2],getservergrowth:[0,1,2],getservermaxmonei:[0,1,2],getserverminsecuritylevel:[0,1,2],getservermoneyavail:[0,1,2,9],getservernumportsrequir:[0,1,2],getserverram:[0,1,2,10],getserverrequiredhackinglevel:[0,1,2],getserversecuritylevel:[0,1,2],getstat:[0,1,2],getstockposit:[1,2],getstockpric:[1,2],gettimesincelastaug:[0,1,2],getupgradehomeramcost:[1,2],getweakentim:[0,1,2],ghost:0,github:[0,8],give:[0,3,5,13],given:[0,5,7,13,15],global:[0,5,8,15],global_object:0,globalvari:8,goe:0,going:[0,8],googl:15,governor:0,grand:13,grant:0,great:8,greater:[0,11],greatli:0,grep:[0,5,15],grow:[0,1,2,8,9],grown:9,growth:[0,5],guarante:13,guid:0,gym:[0,13,14],gymnam:13,gymworkout:[0,1,2],hack:[0,1,2,8,9,13,14],hacker:1,hackexpgain:3,hackingcontract:13,hacknet:[0,1,2,5,14],hacknetnod:[0,1,2],hacknetnodemonei:3,had:0,half:0,halt:5,halv:[0,13],hand:[0,15],handbook:0,handl:[0,10],happen:0,happi:8,harder:0,hardwar:0,has:[0,2,3,5,6,8,13,15],hasrootaccess:[0,1,2],have:[0,2,3,5,6,7,8,10,13,15],havoc_mayhem:0,header:[0,15],heist:13,helio:[0,5],hello:5,help:[0,1],her:0,here:[0,1,4,5,7,8,9,10,13,15],hex:[0,8,15],hidden:0,high:0,higher:[0,5],highlight:[0,15],his:0,histori:15,hoist:5,hold:4,home:[0,1,5,13,14],homicid:13,hope:1,hopefulli:0,hospit:0,hostnam:[0,1,5],hotkei:0,how:[0,1,2,4,5,6,9,10,15],howev:[0,5,9,10,15],htm:[],html:0,http:0,httpworm:[1,2,13,15],hydroflam:0,hyphen:4,idea:0,ident:2,identifi:[0,5,15],ifconfig:1,immedi:[0,5,7,13,15],implement:[0,2,10,14],importantinfo:15,improv:[0,2,8],inc:0,includ:[0,4,5,8,13,14,15],incom:[0,5,6],incomplet:0,incorrect:0,incorrectli:0,increas:[0,5],increment:[0,1,11],incur:[0,10],index:[1,5,6],indexeddb:0,indexof:0,indic:[0,5,13,15],individu:[0,15],industri:0,inequ:11,infiltr:0,infinit:8,info:0,inform:[0,1,2,5,13,15],initi:[0,4],innertext:8,input:[0,8,13,14],insan:0,insert:0,insid:[5,6,10],instal:[0,5,7,13],installaugment:[0,1,2],instanc:[0,5,8],instead:[0,3,5,6,8,13],institut:13,instrins:5,instruct:0,integ:[3,4,5,6,7],intellig:[0,13],interact:10,interest:0,interfac:[0,15],interpret:0,interv:0,intuit:0,invalid:[0,5,13],invest:0,investor:0,invit:[0,13],involv:0,iron:[0,13],isbusi:[0,1,2],ishima:13,isinteg:10,isn:0,isrun:[0,1,2],issu:[0,13,15],item:[0,10],iter:[6,9],its:[0,5,7,8,10,15],itself:6,jaguilar:8,javascript:[0,1,2,4,5,8,9],job:[0,8,13,14],jobtitl:13,joesgun:5,join:[0,4,13],joinfact:[1,2],jqueri:0,jshint:0,jump3r:[0,1],just:[0,5,8,10,15],karma:0,keep:0,kei:[0,14,15],kernel:0,keybind:0,keyboard:[0,1,15],keyword:[0,9],kidnap:13,kill:[0,1,2],killal:[0,1,2],know:[0,8,10],label:4,languag:[0,2,4,5],larceni:13,larg:0,last:[0,5,8,10,14],late:0,later:[0,3,4,7,13],latest:0,lead:1,leadership:13,leak:8,least:[0,5,6],left:[0,15],length:[0,5,6,8,12],lenient:13,less:[0,11],let:[0,7,8,9,10,12,15],letter:[4,7],level:[0,5,6,13,15],levelcost:[5,6],librari:[0,10],life:15,lightli:0,like:[0,5,8,10,12,14],limit:[0,5,7,13],limitbui:7,limitsel:7,line:[0,8,10,14],linear:0,linearli:0,link:[0,5,15],list:[0,6,13,15],lit:[0,5,15],literatur:[0,5,15],littl:0,load:[0,8],local:5,localstorag:0,locat:[0,5,13],lock:0,log:[0,5,6,10,14,15],logic:[0,11],longer:0,look:[8,10,12],loop:[0,1,2,8],lore:0,lose:[0,10],lot:[0,8,13],low:0,lower:[0,5],lscpu:[0,1],ltcnugget:0,machin:[0,15],made:[0,7,15],mai:[0,5,8,15],main:8,maintain:0,major:1,make:[0,5,8,12],manag:[0,13],mani:[0,2,4,13],manipul:8,manual:[0,13],manualhackmonei:3,map:6,mark:[0,8,15],market:[0,7],masterscript:15,match:15,mateon1:0,materi:0,math:[0,1,2],matter:15,max:[0,6],maximum:[0,5,15],mayb:[0,10],mean:[0,1,2,3,4,5,6,8,10,13],meant:0,mechan:[0,15],med:0,medic:0,mem:1,member:[0,1,2,4,8,13],memori:[0,5,8,15],mention:0,menu:[0,14,15],messag:[0,1,5,15],method:[0,1,2,4,8,10],mid:0,middl:13,might:0,migrat:0,mild:0,millenium:13,millisecond:[0,5],minigam:0,minimum:[0,5],minor:0,minut:[0,13],misc:[0,1],miscellan:[1,2],mission:[0,14],mode:[0,5,14],modifi:[0,12],modul:[0,1,2,8],modulo:11,monei:[0,1,3,5,6,7,9,13,15],monetari:0,moneygainratepersecond:6,more:[0,4,5,9,14,15],most:[0,4],mostli:0,move:14,mozilla:[0,1,2],mrnuggelz:0,msg:[5,15],much:[0,9,15],mug:13,mult:[3,5,6],multi:[0,10],multidimension:0,multilin:0,multipl:[0,5,8,11,15],multipli:[0,3,5,6,13],multithread:0,must:[0,4,5,6,7,8,10,13,14,15],mute:15,mysteri:1,name:[0,4,5,6,7,11,12,13,15],namespac:10,nano:[0,1,8,14],nativ:0,natur:0,navig:[0,1,15],nearest:[5,6,7],necessari:[0,1,15],need:[0,5,8,10,15],neg:0,negat:[0,11],nerf:0,nest:0,net:7,netscript:[0,1],netscriptj:[0,1,2],netscriptport:10,netsction:0,network:[0,13,15],neuroflux:0,never:[0,8],newer:0,newli:5,newlin:0,next:[5,14],nitesec:0,node:[0,1,2,5,14,15],non:15,none:[5,6],normal:[0,10,12,13],noscript:0,notabl:[0,5],note:[0,1,2,5,6,10,13,14,15],notifi:0,now:[0,1,8,10,15],nuke:[0,1,2,15],num:15,number:[0,1,2,4,5,6,7,8,11,12,13,15],numer:[0,4,7,11],numthread:[0,5,10],object:[0,3,4,5,6,8,13],observ:0,obtain:5,obvious:13,occur:0,off:0,offic:0,offici:0,offlin:[0,5],old:0,omit:[5,15],onc:[0,15],one:[0,5,6,8,9,10,13],ones:0,onli:[0,3,5,6,7,8,10,11,13,14,15],onlin:[0,5],onlinetimesecond:6,onto:4,open:[0,5,8,10,13,14,15],oper:[0,1,2,10,12],operand:11,optim:1,option:[0,5,8,13,14,15],order:[0,3,5,7,13,15],org:0,origin:[0,3],osx:0,other:[0,5,8,10,13,14],otherwis:[0,5,6,7,9,10,13,14,15],our:10,oustand:[0,7,13],out:[0,2,5,10,13],outdat:0,output:5,outsid:[0,5,13],outstand:0,over:[0,5,8],overclock:0,overrid:14,overwrit:[0,5],own:[0,1,2,7,8,15],page:[0,1,3,5,8,10,13,14,15],param:8,paramet:[0,5,15],pars:[0,10],parser:0,part:[0,13,15],particular:13,pass:[0,5,8,10,12,13,15],passiv:0,past:0,path:15,pattern:[0,15],peek:[0,1,2,10],peopl:8,per:0,percentag:[0,5,6],perform:[0,13],perman:15,persist:0,pheromon:0,pick:0,picker:15,pill:0,place:7,placeord:[1,2],plai:1,plan:12,player:[0,1,5,6,7,12,13,15],pleas:[0,8],plenti:8,plot:0,point:[0,8],pointer:0,pop:[0,4,10],popular:0,popup:0,port:[0,1,2,5,15],portfolio:0,pos:7,posit:[0,4,6,7,13],possibl:[0,8,12],post:8,pound:15,power:[0,1,5,8],powerhous:13,pre:[0,8,11],preced:15,prefac:8,prefix:0,prerequisit:0,preset:[14,15],press:0,prestig:0,prevent:12,preventdefault:0,previou:[0,14],previous:0,price:[0,7],primarili:8,primit:4,print:[0,1,2,3,6,8,10,13,15],privat:0,problem:0,process:[0,5],prod:0,produc:[0,11],product:[0,5,6],profit:[0,7],program:[0,2,5,13,14,15],programat:0,programnam:13,progress:0,promis:0,promot:[0,13],prompt:[0,1,2,8],proper:0,properli:0,properti:[0,13],protocol:7,prototyp:8,provid:[0,6,7],pserv:5,puchas:0,purchas:[0,1,2,5,7,13,15],purchaseaugment:[1,2],purchasecost:[5,6],purchasedserver1:8,purchasehacknetnod:[0,1,2,6],purchaseprogram:[1,2],purchaseserv:[0,1,2],purchasetor:[1,2],purpos:[4,5],push:0,put:[3,11],qualifi:0,qualiti:0,queri:0,quest:1,queue:[0,5,10],quickli:[0,5],quit:0,quot:4,quotat:15,rais:[0,5],ram:[0,5,6,10,13,15],ramcost:[5,6],ramus:5,ran:[0,5,8,10,15],random:0,randomarg:8,rank:0,rate:[0,5],rather:[0,8,15],reach:[0,2,15],read:[0,1,2,4,6,10],readthedoc:0,real:[0,15],realli:0,reason:[0,5],rebalanc:1,receiv:[0,3,13],recommend:[8,13],record:0,recurs:0,red:[0,8],reddit:0,reduc:[0,8],refactor:0,refer:[0,4,9],referenc:[0,4],reflect:7,refresh:[0,8],regain:0,regard:0,regardless:[0,5],reject:0,rel:[0,15],relat:[5,6,10,15],relaysmtp:[1,2,13],releas:[0,8],relev:[0,3],reload:[0,8,10],remain:0,rememb:[5,7,8,15],remot:15,remov:[0,5,10,15],rep:0,repeat:0,repeatedli:[0,8],replac:[0,15],report:[0,8],repres:[0,3,4,5,7,10,15],reput:[0,13],request:2,requir:[0,3,5,10,11,13,15],res:[5,10,13],research:0,reset:[0,5,7,13],resolv:5,respect:[0,15],respons:8,rest:[0,4],restart:[0,13],result:[0,5,8,11],retain:[0,7],reusabl:15,revert:5,reward:0,right:[0,10],risk:8,rob:13,robot:0,role:1,room:10,root:[5,15],rothman:[5,13],round:[0,5,6,7],router:[0,13,15],rowel:8,rpg:1,rule:8,run:[0,1,2,3,8,9,10,11,12,13],runarg:8,runtim:[0,5],safe:8,sai:[5,12],sake:10,salari:0,sale:[0,7],same:[0,5,8,9,10,13,14,15],satisfi:0,save:[0,8,10,14],scale:0,scan:[0,1,2],schedul:[8,13],scheme:15,scienc:13,scientif:0,scope:[5,8],scp:[0,1,2,8],screen:[0,14,15],screw:0,script:[0,1,2,5,6,7,8,10,13,15],scripthackmonei:3,scriptjob:8,scriptkil:[0,1,2],scriptnam:[0,5],scriptrun:[0,1,2],scriptschedul:8,scroll:0,search:[1,5],second:[0,4,5,6,7,12,13,15],secondari:0,secret:[0,1],section:[2,5],sector:13,secur:[0,5,13],securitywork:13,see:[0,5,6,8,9,15],select:[0,5],self:0,sell:[0,7],sellshort:[0,1,2],sellstock:[0,1,2],semicolon:0,sensit:[0,5,7,13,15],sent:0,separ:[3,5,15],sequenc:[4,7],sequenti:8,serial:[0,5,10],seriou:8,server:[0,5,9,15],serverexist:[0,1,2],servergrowthr:3,servermaxmonei:3,serverprofil:[0,13],serverstartingmonei:3,serverstartingsecur:3,serverweakenr:3,set:[0,5,8,13,14,15],sever:[0,10],share:[0,7,8],sharesshort:7,she:1,shell:14,shield:0,shift:0,shoplift:13,shortcut:[0,1,15],shorthand:0,shortstock:[0,1,2],should:[0,5,9,13,15],show:[0,4,5,8,9,15],shown:[5,15],side:15,sigma:15,sign:15,signatur:[0,5,8],signific:[0,5],significantli:[0,8],similar:[0,5],simpl:[8,9,10],simplest:5,simpli:[2,4],simplic:10,sinc:[0,5,8,10],singl:[0,4,5,11,15],singular:[0,1,2],situat:8,size:0,skill:[0,5],sleep:[0,1,2,6,8,10,13],slice:10,slight:0,slightli:0,slow:8,slower:0,slowli:0,small:[0,8,13],smaller:0,smart:0,snap:13,soft:0,softwar:[0,13],solar:15,sold:7,some:[0,5,8,9,10,11,13],some_valu:5,someth:1,sometim:0,someval1:10,someval2:10,soon:0,sorri:0,sort:[0,5,10],sourc:[0,3,5,13],space:[0,14,15],spaceglac:0,spam:0,spawn:[0,1,2],special:[0,4,6,12,13],specif:[0,5,10],specifi:[0,5,6,7,10,12,13,15],speed:[0,5],splice:[0,4],spoiler:[0,3,13],sprintf:[0,1,2],sqlinject:[1,2,13],stack:0,stage:[0,1],stai:5,stamina:0,start:[0,4,5,8,10,13,15],starter:0,stat:[0,13,14],state:0,statement:[0,9],statist:[0,7,15],steal:[0,5],still:[0,5,8,15],stock:[0,7],stolen:[0,5],stop:[0,5,7,13,15],stopact:[0,1,2],stopbui:7,stopsel:7,storag:0,store:[4,13],str:13,strategi:7,street:0,strength:13,strict:11,string:[0,4,5,7,13,15],structur:[3,5,6,10],strucur:13,studi:[0,13],stupid:0,style:[0,8],subject:3,subreddit:0,subset:2,substitut:15,substr:5,subtract:11,success:[0,5,7,13],successfulli:[0,5,6,7,10,13,15],sudov:1,suggest:2,sum:[0,5],summari:8,summit:13,suppli:0,support:[0,4,6,7,8,10,15],suppos:10,suppress:0,sure:0,suspend:5,suspicion:1,sym:7,symbol:7,syntax:[0,2,5,10],system:[1,7],tab:[0,8,14,15],tail:[0,1],take:[0,1,5,13,14,15],target:[0,5,8,15],task:0,technolgi:0,technolog:[0,13],tell:0,templat:5,ten:9,term:[0,13],termin:[0,1,5,8,13],terminalinput:8,territori:0,test2:[],test:[0,5,8],testlib:10,testlibrari:10,text:[0,4,5,8,15],than:[0,5,8,9,11,15],thank:0,theft:13,thei:[0,2,3,5,8,14,15],them:[0,5,10,13],theme:[0,1],themselv:0,therefor:[0,8],theres:0,thi:[0,1,2,3,4,5,6,7,8,10,11,12,13,14,15],thing:15,think:0,third:[0,5,7],those:[5,6,8],though:[0,5,10],thought:[4,8],thread:[0,5,8,12,13,15],three:[4,5,8,10,14,15],through:[0,5,6,8,10,13,14,15],throughout:0,thrown:8,tier:0,time:[0,5,6,8,9,10,13,15],timework:13,tini:2,tip:0,tix:[0,1,2],todo:15,tokyo:13,tolocalestr:0,tolowercas:4,too:0,tooltip:0,top:[0,1,8],tor:[0,13,15],total:[0,5,6,15],totalmoneygener:6,totalram:5,toward:0,tprint:[0,1,2,8,10],tprintcolor:8,tracer:0,track:0,trade:[0,1,2],traffick:13,train:[0,13,14],transact:[0,7],transfer:0,travel:[0,13,14],traveltoc:[1,2],travers:9,treat:0,trend:0,tri:[5,6,15],trigger:0,troubl:0,trywrit:[0,10],tutori:[0,14],tutorialspoint:[],tweak:0,two:[0,5,7,8,10,11,12,13],txt:[0,5,8,15],type:[0,1,2,5,7,8,13,15],typic:5,typo:0,unabl:8,unalia:[0,1],unalias_terminal_command:[],unari:[1,2],uncov:1,undefin:0,underli:[0,5,10],underscor:4,undo:15,undon:15,uni:5,uniqu:[0,5,8,15],univeristi:13,univers:[0,13,14],universitycours:[1,2],universitynam:13,unknown:1,unless:[0,14],unlik:8,unlock:[0,7,13],unrecogn:0,until:[0,5,6,13],untyp:4,updat:[0,13],upgrad:[0,6,13],upgradecor:6,upgradehacknetnod:0,upgradehomeram:[1,2],upgradelevel:6,upgraderam:6,upon:0,url:8,usag:[0,5,10,15],use:[0,1,2,5,7,9,10,13,15],useabl:0,used:[0,2,4,5,6,7,10,13,14,15],useful:0,user:[0,8,15],uses:[0,8,9],using:[0,5,6,7,8,9,10,12,13,15],usual:13,utc:[0,10],util:[0,1,2],valid:[0,5,10,13,15],valu:[0,3,4,5,6,7,8,10,11,13,15],valuat:0,vari:5,variabl:[0,1,2,5,8,9,11,15],varieti:0,variou:[0,13,14],vechain:0,vehicl:0,veri:[0,8],version:8,via:0,viabl:0,view:0,vim:[0,14],visibl:8,visit:[0,7,13],volatil:0,volhaven:13,vsprintf:[0,1,2],w0r1d_d43m0n:0,waer:0,wage:0,wai:[0,5,6,10,13,15],wait:[0,10],waiter:13,wall:0,want:[0,6,8,10,12,13,15],warehous:0,warn:[0,1,2,11,12,13,15],wasn:0,water:0,weaken:[0,1,2,8],weapon:0,web:[0,8,13,15],webpack:0,week:[],well:[0,4,8,14,15],were:[0,5,13,14,15],wese:7,what:[0,5,6,8,13,15],whatev:13,when:[0,1,2,5,8,9,10,13,15],whenev:0,where:[0,1,5,8,10,14],whether:[0,5,7,13,15],which:[0,4,5,6,7,10,13,15],whitespac:[0,5],who:[0,8],whose:15,wiki:0,wikia:0,wilson:0,win:0,window:14,within:8,without:[0,5,8,10,15],won:0,word:[0,5,14,15],work:[0,5,7,8,10,11,13,14,15],workagiexpgain:13,workchaexpgain:13,workdefexpgain:13,workdexexpgain:13,workforcompani:[1,2],workforfact:[1,2],workhackexpgain:13,workmoneygain:13,workrepgain:13,workstrexpgain:13,worktyp:13,world:[0,1,2,5,7],worm:15,would:[0,3,11,12,13,15],wouldnt:0,wraithan:0,wrap:0,write:[0,1,2,6,7,8,10],written:[2,5,10],wrong:1,wrote:10,wse:[0,7],www:[],x10:0,yet:[0,5,13],you:[0,1,2,3,4,5,6,7,8,9,10,11,13,14,15],your:[0,1,2,6,7,8,13,14,15],yourself:[0,6],zero:[0,5],zeu:0,zeud:0,zip:[0,15]},titles:["Changelog","Welcome to Bitburner's documentation!","Netscript Documentation","Netscript Advanced Functions","Netscript Data Types and Variables","Netscript Basic Functions","Netscript Hacknet Node API","Netscript Trade Information eXchange (TIX) API","NetscriptJS (Netscript 2.0)","Netscript Loops and Conditionals","Netscript Miscellaneous","Netscript Operators","Netscript Script Arguments","Netscript Singularity Functions","Keyboard Shortcuts","Terminal"],titleterms:{"final":8,"function":[3,5,10,13],"import":10,advanc:3,alia:15,analyz:15,api:[6,7],applytocompani:13,argument:12,bash:14,basic:5,binari:11,bitburn:1,brutessh:5,bui:15,buystock:7,cancelord:7,cat:15,changelog:0,check:15,checkfactioninvit:13,clear:[5,15],clearlog:5,cls:15,command:15,comment:10,commitcrim:13,condit:9,configur:15,connect:15,createprogram:13,data:4,date:10,defin:5,deleteserv:5,disablelog:5,document:[1,2],dom:[],download:15,editor:14,enablelog:5,exampl:[6,8],exchang:7,exec:5,exit:5,favor:0,fileexist:5,firefox:8,free:15,ftpcrack:5,game:14,getaugmentationcost:13,getaugmentationsfromfact:13,getbitnodemultipli:3,getcharacterinform:13,getcompanyfavor:13,getcompanyrep:13,getcrimech:13,getfactionfavor:13,getfactionrep:13,getgrowtim:5,gethackinglevel:5,gethackingmultipli:5,gethacknetmultipli:5,gethacktim:5,gethostnam:5,getnexthacknetnodecost:5,getownedaugment:13,getpurchasedserv:5,getscriptexpgain:5,getscriptincom:5,getscriptnam:5,getscriptram:5,getserverbasesecuritylevel:5,getservergrowth:5,getservermaxmonei:5,getserverminsecuritylevel:5,getservermoneyavail:5,getservernumportsrequir:5,getserverram:5,getserverrequiredhackinglevel:5,getserversecuritylevel:5,getstat:13,getstockposit:7,getstockpric:7,gettimesincelastaug:5,getupgradehomeramcost:13,getweakentim:5,grow:5,gymworkout:13,hack:[5,15],hacknet:6,hacknetnod:6,handl:[],hasrootaccess:5,help:15,home:15,hostnam:15,how:8,httpworm:5,ifconfig:15,indic:1,inform:7,installaugment:13,isbusi:13,isrun:5,javascript:10,joinfact:13,keyboard:14,kill:[5,15],killal:[5,15],loop:9,lscpu:15,major:0,manipul:[],math:10,mem:15,member:6,method:6,misc:14,miscellan:10,modul:10,mozilla:8,nano:15,navig:14,netscript:[2,3,4,5,6,7,8,9,10,11,12,13],netscriptj:8,node:6,note:8,nuke:5,number:10,oper:11,optim:0,own:5,peek:5,placeord:7,port:10,print:5,prompt:5,purchas:6,purchaseaugment:13,purchasehacknetnod:5,purchaseprogram:13,purchaseserv:5,purchasetor:13,read:5,rebalanc:0,relaysmtp:5,round:[],run:[5,15],scan:[5,15],scp:[5,15],script:[12,14],scriptkil:5,scriptrun:5,sellshort:7,sellstock:7,serverexist:5,shortcut:14,shortstock:7,singular:13,sleep:5,spawn:5,sprintf:5,sqlinject:5,stopact:13,sudov:15,system:0,tabl:1,tail:15,termin:[14,15],theme:15,tix:7,top:15,tprint:5,trade:7,traveltoc:13,type:4,unalia:15,unari:11,universitycours:13,upgradehomeram:13,usag:[],use:8,util:6,variabl:[4,6],vsprintf:5,warn:8,weaken:5,welcom:1,what:1,workforcompani:13,workforfact:13,write:5,your:5}}) \ No newline at end of file diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst index 4dcd7947f1..03d84f44ae 100644 --- a/doc/source/changelog.rst +++ b/doc/source/changelog.rst @@ -3,8 +3,18 @@ Changelog ========= -v0.37.1 -------- +v0.37.2 - 6/2/2018 +------------------ + +* After joining the Bladeburners division, there is now a button to go to the Bladeburner content + in the 'City' page +* You now start with $250m in BitNode-8 (increased from $100m) +* Bug Fix: You can now no longer directly edit Hacknet Node values through NetscriptJS (hopefully) +* Bug Fix: Bladeburners is no longer accessible in BN-8 +* Bug Fix: getBitNodeMultipliers() Netscript function now returns a copy rather than the original object + +v0.37.1 - 5/22/2018 +------------------- * You now earn money from successfully completing Bladeburner contracts. The amount you earn is based on the difficulty of the contract. * Completing Field Analysis in Bladeburner now grants 0.1 rank diff --git a/netscript.js b/netscript.js index d42b2bcb82..88fd9a03bb 100644 --- a/netscript.js +++ b/netscript.js @@ -103,7 +103,7 @@ var NetscriptHighlightRules = function(options) { "JSON|Math|" + // Other "this|arguments|prototype|window|document" , // Pseudo "keyword": - "const|yield|import|get|set|async|await|foop|" + + "const|yield|import|get|set|async|await|" + "break|case|catch|continue|default|delete|do|else|finally|for|function|" + "if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|" + "__parent__|__count__|escape|unescape|with|__proto__|" + diff --git a/package-lock.json b/package-lock.json index 2798aa85df..f491032025 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7432,6 +7432,11 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, + "decimal.js": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-7.2.3.tgz", + "integrity": "sha512-AoFI37QS0S87Ft0r3Bdz4q9xSpm1Paa9lSeKLXgMPk/u/+QPIM5Gy4DHcZQS1seqPJH4gHLauPGn347z0HbsrA==" + }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", diff --git a/package.json b/package.json index 6d39d7f22a..a8487b3d44 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "async": "^2.1.2", "bluebird": "^3.5.1", "brace": "^0.11.1", + "decimal.js": "7.2.3", "enhanced-resolve": "^3.4.0", "escope": "^3.6.0", "file-saver": "^1.3.3", diff --git a/src/Bladeburner.js b/src/Bladeburner.js index 312363f8bb..daca05e914 100644 --- a/src/Bladeburner.js +++ b/src/Bladeburner.js @@ -3185,7 +3185,7 @@ function initBladeburner() { Skills[SkillNames.Overclock] = new Skill({ name:SkillNames.Overclock, desc:"Each level of this skill decreases the time it takes " + - "to attempt a contract or operation by 1% (Max Level: 99)", + "to attempt a contract or operation by 1% (Max Level: 95)", baseCost:5, costInc:1, maxLvl:95, actionTime:1 }); diff --git a/src/CompanyManagement.js b/src/CompanyManagement.js index 6f4a3925b0..9414d65300 100644 --- a/src/CompanyManagement.js +++ b/src/CompanyManagement.js @@ -5,7 +5,7 @@ import {showLiterature} from "./Literature.js"; import {Locations} from "./Location.js"; import {Player} from "./Player.js"; -import Decimal from '../utils/decimal.js'; +import Decimal from "decimal.js"; import {dialogBoxCreate} from "../utils/DialogBox.js"; import {getRandomInt, removeElementById, createElement, createAccordionElement, diff --git a/src/Constants.js b/src/Constants.js index 87274b7f01..3e665a6635 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -1,5 +1,5 @@ let CONSTANTS = { - Version: "0.37.1", + Version: "0.37.2", //Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience //and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then @@ -484,16 +484,13 @@ let CONSTANTS = { "World Stock Exchange account and TIX API Access
        ", LatestUpdate: - "v0.37.1
        " + - "* You now earn money from successfully completing Bladeburner contracts. The amount you earn is based " + - "on the difficulty of the contract.
        " + - "* Completing Field Analysis in Bladeburner now grants 0.1 rank
        " + - "* The maximum RAM you can get on a purchased server is now 1,048,576GB (2^20)
        " + - "* Bug Fix: Fixed Netscript syntax highlighting issues with the new NetscriptJS
        " + - "* Bug Fix: Netscript Functions now properly incur RAM costs in NetscriptJS
        " + - "* Bug Fix: deleteServer() now fails if its called on the server you are currently connected to
        " + - "* Removed in-game Netscript documentation, since it was outdated and difficult to maintain.
        " + - "* Bug Fix: Updated the gymWorkout() Singularity function with the new exp/cost values for gyms
        " + "v0.37.2
        " + + "* After joining the Bladeburners division, there is now a button to go to the Bladeburner content " + + "in the 'City' page
        " + + "* You now start with $250m in BitNode-8 (increased from $100m)
        " + + "* Bug Fix: You can now no longer directly edit Hacknet Node values through NetscriptJS (hopefully)
        " + + "* Bug Fix: Bladeburners is no longer accessible in BN-8
        " + + "* Bug Fix: getBitNodeMultipliers() Netscript function now returns a copy rather than the original object
        " } export {CONSTANTS}; diff --git a/src/HacknetNode.js b/src/HacknetNode.js index 4c7597b735..8461dd58a2 100644 --- a/src/HacknetNode.js +++ b/src/HacknetNode.js @@ -56,6 +56,7 @@ function HacknetNode(name) { this.moneyGainRatePerSecond = 0; } + HacknetNode.prototype.updateMoneyGainRate = function() { //How much extra $/s is gained per level var gainPerLevel = CONSTANTS.HacknetNodeMoneyGainPerLevel; @@ -180,6 +181,36 @@ HacknetNode.fromJSON = function(value) { Reviver.constructors.HacknetNode = HacknetNode; +var HacknetNodeWrapper = function(hacknetNodeObj) { + var _node = hacknetNodeObj; + return { + name : _node.name, + level : _node.level, + ram : _node.ram, + cores : _node.cores, + totalMoneyGenerated : _node.totalMoneyGenerated, + onlineTimeSeconds : _node.onlineTimeSeconds, + moneyGainRatePerSecond : _node.moneyGainRatePerSecond, + upgradeLevel : function(n) { + return _node.upgradeLevel(n); + }, + upgradeRam : function() { + return _node.upgradeRam(); + }, + upgradeCore : function() { + return _node.upgradeCore(); + }, + getLevelUpgradeCost : function(n) { + return _node.getLevelUpgradeCost(n); + }, + getRamUpgradeCost : function() { + return _node.getRamUpgradeCost(); + }, + getCoreUpgradeCost : function() { + return _node.getCoreUpgradeCost(); + } + } +} function purchaseHacknet() { /* INTERACTIVE TUTORIAL */ @@ -469,8 +500,31 @@ function updateHacknetNodeDomElement(nodeObj) { } } +function createPlayerHacknetNodeWrappers() { + Player.hacknetNodeWrappers.length = Player.hacknetNodes.length; + for (var i = 0; i < Player.hacknetNodes.length; ++i) { + Player.hacknetNodeWrappers[i] = new HacknetNodeWrapper(Player.hacknetNodes[i]); + } +} + +function updatePlayerHacknetNodeWrappers() { + if (Player.hacknetNodeWrappers.length !== Player.hacknetNodes.length) { + return createPlayerHacknetNodeWrappers(); + } + for (var i = 0; i < Player.hacknetNodeWrappers.length; ++i) { + if (!(Player.hacknetNodeWrappers[i] instanceof HacknetNodeWrapper)) {return createPlayerHacknetNodeWrappers();} + Player.hacknetNodeWrappers[i].level = Player.hacknetNodes[i].level; + Player.hacknetNodeWrappers[i].ram = Player.hacknetNodes[i].ram; + Player.hacknetNodeWrappers[i].cores = Player.hacknetNodes[i].cores; + Player.hacknetNodeWrappers[i].totalMoneyGenerated = Player.hacknetNodes[i].totalMoneyGenerated; + Player.hacknetNodeWrappers[i].onlineTimeSeconds = Player.hacknetNodes[i].onlineTimeSeconds; + Player.hacknetNodeWrappers[i].moneyGainRatePerSecond = Player.hacknetNodes[i].moneyGainRatePerSecond; + } +} + function processAllHacknetNodeEarnings(numCycles) { var total = 0; + updatePlayerHacknetNodeWrappers(); for (var i = 0; i < Player.hacknetNodes.length; ++i) { total += processSingleHacknetNodeEarnings(numCycles, Player.hacknetNodes[i]); } @@ -503,4 +557,4 @@ function getHacknetNode(name) { export {hacknetNodesInit, HacknetNode, purchaseHacknet, updateTotalHacknetProduction, getCostOfNextHacknetNode, updateHacknetNodesMultiplierButtons, getMaxNumberLevelUpgrades, displayHacknetNodesContent, updateHacknetNodesContent, processAllHacknetNodeEarnings, - getHacknetNode}; + getHacknetNode, createPlayerHacknetNodeWrappers}; diff --git a/src/Location.js b/src/Location.js index 65ad38c67b..30e8bdf1ca 100644 --- a/src/Location.js +++ b/src/Location.js @@ -726,6 +726,7 @@ function displayLocationContent() { securityJob.style.display = "block"; agentJob.style.display = "block"; if (Player.bitNodeN === 6 || hasBladeburnerSF === true) { + if (Player.bitNodeN === 8) {break;} if (Player.bladeburner instanceof Bladeburner) { //Note: Can't infiltrate NSA when part of bladeburner nsaBladeburner.innerText = "Enter Bladeburner Headquarters"; diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index c5f5c7ffa9..6e40dddbb4 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -58,7 +58,7 @@ import {makeRuntimeRejectMsg, netscriptDelay, runScriptFromScript, import {Environment} from "./NetscriptEnvironment.js"; import {NetscriptPort} from "./NetscriptPort.js"; -import Decimal from '../utils/decimal.js'; +import Decimal from "decimal.js"; import {dialogBoxCreate} from "../utils/DialogBox.js"; import {printArray, powerOfTwo} from "../utils/HelperFunctions.js"; import {createRandomIp} from "../utils/IPAddress.js"; @@ -151,7 +151,7 @@ function NetscriptFunctions(workerScript) { Math : Math, Date : Date, Number : Number, - hacknetnodes : Player.hacknetNodes, + hacknetnodes : Player.hacknetNodeWrappers, sprintf : sprintf, vsprintf: vsprintf, scan : function(ip=workerScript.serverIp, hostnames=true){ @@ -1118,7 +1118,8 @@ function NetscriptFunctions(workerScript) { if (!hasAISF) { throw makeRuntimeRejectMsg(workerScript, "Cannot run getBitNodeMultipliers(). It requires Source-File 5 to run."); } - return BitNodeMultipliers; + let copy = Object.assign({}, BitNodeMultipliers); + return copy; }, getServerMoneyAvailable : function(ip){ if (workerScript.checkingRam) { diff --git a/src/Player.js b/src/Player.js index f3883e8b60..4d76c79de1 100644 --- a/src/Player.js +++ b/src/Player.js @@ -19,7 +19,7 @@ import {AllServers, Server, AddToAllServers} from "./Server.js"; import {SpecialServerIps, SpecialServerNames} from "./SpecialServerIps.js"; import {SourceFiles, applySourceFile} from "./SourceFile.js"; -import Decimal from '../utils/decimal.js'; +import Decimal from "decimal.js"; import {dialogBoxCreate} from "../utils/DialogBox.js"; import {clearEventListeners} from "../utils/HelperFunctions.js"; import {createRandomIp} from "../utils/IPAddress.js"; @@ -99,6 +99,7 @@ function PlayerObject() { this.currentServer = ""; //IP address of Server currently being accessed through terminal this.purchasedServers = []; //IP Addresses of purchased servers this.hacknetNodes = []; + this.hacknetNodeWrappers = []; this.totalHacknetNodeProduction = 0; //Factions @@ -390,16 +391,8 @@ PlayerObject.prototype.prestigeSourceFile = function() { if (this.bitNodeN === 3) {this.money = new Decimal(150e9);} this.corporation = 0; - //Reset Bladeburner this.bladeburner = 0; - //BitNode 8: Ghost of Wall Street - if (this.bitNodeN === 8) {this.money = new Decimal(100000000);} - if (this.bitNodeN === 8 || hasWallStreetSF) { - this.hasWseAccount = true; - this.hasTixApiAccess = true; - } - this.playtimeSinceLastAug = 0; this.scriptProdSinceLastAug = 0; } diff --git a/src/Prestige.js b/src/Prestige.js index ceaf6e56a5..51ba473552 100644 --- a/src/Prestige.js +++ b/src/Prestige.js @@ -27,13 +27,15 @@ import {initStockMarket, initSymbolToStockMap, stockMarketContentCreated, setStockMarketContentCreated} from "./StockMarket.js"; import {Terminal, postNetburnerText} from "./Terminal.js"; -import Decimal from '../utils/decimal.js'; +import Decimal from "decimal.js"; import {dialogBoxCreate} from "../utils/DialogBox.js"; import {createPopup, createElement, removeElementById, exceptionAlert} from "../utils/HelperFunctions.js"; import {yesNoBoxCreate, yesNoBoxGetYesButton, yesNoBoxGetNoButton, yesNoBoxClose} from "../utils/YesNoBox.js"; +let BitNode8StartingMoney = 250e6; + //Prestige by purchasing augmentation function prestigeAugmentation() { initBitNodeMultipliers(); @@ -127,7 +129,7 @@ function prestigeAugmentation() { Player.bladeburner = null; //BitNode 8: Ghost of Wall Street - if (Player.bitNodeN === 8) {Player.money = new Decimal(100e6);} + if (Player.bitNodeN === 8) {Player.money = new Decimal(BitNode8StartingMoney);} if (Player.bitNodeN === 8 || hasWallStreetSF) { Player.hasWseAccount = true; Player.hasTixApiAccess = true; @@ -305,6 +307,13 @@ function prestigeSourceFile() { } + //BitNode 8: Ghost of Wall Street + if (Player.bitNodeN === 8) {Player.money = new Decimal(BitNode8StartingMoney);} + if (Player.bitNodeN === 8 || hasWallStreetSF) { + Player.hasWseAccount = true; + Player.hasTixApiAccess = true; + } + //Gain int exp Player.gainIntelligenceExp(5); } diff --git a/src/SaveObject.js b/src/SaveObject.js index 020ecca3ab..244c8820c7 100644 --- a/src/SaveObject.js +++ b/src/SaveObject.js @@ -8,7 +8,8 @@ import {loadFactions, Factions, processPassiveFactionRepGain} from "./Faction.js"; import {FconfSettings, loadFconf} from "./Fconf.js"; import {loadAllGangs, AllGangs} from "./Gang.js"; -import {processAllHacknetNodeEarnings} from "./HacknetNode.js"; +import {processAllHacknetNodeEarnings, + createPlayerHacknetNodeWrappers} from "./HacknetNode.js"; import {loadMessages, initMessages, Messages} from "./Message.js"; import {Player, loadPlayer} from "./Player.js"; import {loadAllRunningScripts} from "./Script.js"; @@ -24,7 +25,7 @@ import {Reviver, Generic_toJSON, Generic_fromJSON} from "../utils/JSONReviver.js"; import {formatNumber} from "../utils/StringHelperFunctions.js"; -import Decimal from '../utils/decimal.js'; +import Decimal from "decimal.js"; /* SaveObject.js * Defines the object used to save/load games @@ -227,6 +228,8 @@ function loadGame(saveString) { } } + //Re-initialize Hacknet Node Wrappers + createPlayerHacknetNodeWrappers(); return true; } @@ -443,6 +446,9 @@ function loadImportedGame(saveObj, saveString) { } } + //Re-initialize Hacknet Node Wrappers + createPlayerHacknetNodeWrappers(); + var popupId = "import-game-restart-game-notice"; var txt = createElement("p", { innerText:"Imported game! I would suggest saving the game and then reloading the page " + diff --git a/src/StockMarket.js b/src/StockMarket.js index 7a060111ad..9c9a6b6b3a 100644 --- a/src/StockMarket.js +++ b/src/StockMarket.js @@ -702,6 +702,9 @@ function displayStockMarketContent() { wseAccountButton.innerText = "Buy WSE Account - $" + formatNumber(CONSTANTS.WSEAccountCost, 2).toString(); if (!Player.hasWseAccount && Player.money.gte(CONSTANTS.WSEAccountCost)) { wseAccountButton.setAttribute("class", "a-link-button"); + } else if (Player.hasWseAccount){ + wseAccountButton.innerText = "WSE Account - Purchased"; + wseAccountButton.setAttribute("class", "a-link-button-bought"); } else { wseAccountButton.setAttribute("class", "a-link-button-inactive"); } @@ -720,6 +723,9 @@ function displayStockMarketContent() { formatNumber(CONSTANTS.TIXAPICost, 2).toString(); if (!Player.hasTixApiAccess && Player.money.gte(CONSTANTS.TIXAPICost)) { tixApiAccessButton.setAttribute("class", "a-link-button"); + } else if(Player.hasTixApiAccess) { + tixApiAccessButton.innerText = "Trade Information eXchange (TIX) API Access - Purchased" + tixApiAccessButton.setAttribute("class", "a-link-button-bought"); } else { tixApiAccessButton.setAttribute("class", "a-link-button-inactive"); } diff --git a/src/engine.js b/src/engine.js index 809405e2ff..d913f39522 100644 --- a/src/engine.js +++ b/src/engine.js @@ -650,6 +650,7 @@ let Engine = { //Generic Locations (common to every city): // World Stock Exchange // Corporation (if applicable) + // Bladeburner HQ (if applicable); var genericLocationsList = document.getElementById("generic-locations-list"); genericLocationsList.style.display = "inline"; removeChildrenFromElement(genericLocationsList); @@ -676,6 +677,18 @@ let Engine = { })); genericLocationsList.appendChild(li); } + + if (Player.bladeburner instanceof Bladeburner) { + var li = createElement("li"); + li.appendChild(createElement("a", { + innerText:"Bladeburner Headquarters", class:"a-link-button", + clickListener:()=>{ + Engine.loadBladeburnerContent(); + return false; + } + })); + genericLocationsList.appendChild(li); + } }, displayFactionsInfo: function() { @@ -738,9 +751,9 @@ let Engine = { clickListener:()=>{ joinFaction(Factions[factionName]); for (var i = 0; i < Player.factionInvitations.length; ++i) { - if (Player.factionInvitations[i] == factionName) { + if (Player.factionInvitations[i] == factionName || Factions[Player.factionInvitations[i]].isBanned) { Player.factionInvitations.splice(i, 1); - break; + i--; } } Engine.displayFactionsInfo(); diff --git a/utils/decimal.js b/utils/decimal.js deleted file mode 100644 index deca2957e1..0000000000 --- a/utils/decimal.js +++ /dev/null @@ -1,4812 +0,0 @@ -/*! decimal.js v7.2.3 https://github.com/MikeMcl/decimal.js/LICENCE */ -;(function (globalScope) { - 'use strict'; - - - /* - * decimal.js v7.2.3 - * An arbitrary-precision Decimal type for JavaScript. - * https://github.com/MikeMcl/decimal.js - * Copyright (c) 2017 Michael Mclaughlin - * MIT Licence - */ - - - // ----------------------------------- EDITABLE DEFAULTS ------------------------------------ // - - - // The maximum exponent magnitude. - // The limit on the value of `toExpNeg`, `toExpPos`, `minE` and `maxE`. - var EXP_LIMIT = 9e15, // 0 to 9e15 - - // The limit on the value of `precision`, and on the value of the first argument to - // `toDecimalPlaces`, `toExponential`, `toFixed`, `toPrecision` and `toSignificantDigits`. - MAX_DIGITS = 1e9, // 0 to 1e9 - - // Base conversion alphabet. - NUMERALS = '0123456789abcdef', - // The natural logarithm of 10 (1025 digits). - LN10 = '2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840422862486334095254650828067566662873690987816894829072083255546808437998948262331985283935053089653777326288461633662222876982198867465436674744042432743651550489343149393914796194044002221051017141748003688084012647080685567743216228355220114804663715659121373450747856947683463616792101806445070648000277502684916746550586856935673420670581136429224554405758925724208241314695689016758940256776311356919292033376587141660230105703089634572075440370847469940168269282808481184289314848524948644871927809676271275775397027668605952496716674183485704422507197965004714951050492214776567636938662976979522110718264549734772662425709429322582798502585509785265383207606726317164309505995087807523710333101197857547331541421808427543863591778117054309827482385045648019095610299291824318237525357709750539565187697510374970888692180205189339507238539205144634197265287286965110862571492198849978748873771345686209167058', - - // Pi (1025 digits). - PI = '3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632789', - - - // The initial configuration properties of the Decimal constructor. - Decimal = { - - // These values must be integers within the stated ranges (inclusive). - // Most of these values can be changed at run-time using the `Decimal.config` method. - - // The maximum number of significant digits of the result of a calculation or base conversion. - // E.g. `Decimal.config({ precision: 20 });` - precision: 20, // 1 to MAX_DIGITS - - // The rounding mode used when rounding to `precision`. - // - // ROUND_UP 0 Away from zero. - // ROUND_DOWN 1 Towards zero. - // ROUND_CEIL 2 Towards +Infinity. - // ROUND_FLOOR 3 Towards -Infinity. - // ROUND_HALF_UP 4 Towards nearest neighbour. If equidistant, up. - // ROUND_HALF_DOWN 5 Towards nearest neighbour. If equidistant, down. - // ROUND_HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour. - // ROUND_HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity. - // ROUND_HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity. - // - // E.g. - // `Decimal.rounding = 4;` - // `Decimal.rounding = Decimal.ROUND_HALF_UP;` - rounding: 4, // 0 to 8 - - // The modulo mode used when calculating the modulus: a mod n. - // The quotient (q = a / n) is calculated according to the corresponding rounding mode. - // The remainder (r) is calculated as: r = a - n * q. - // - // UP 0 The remainder is positive if the dividend is negative, else is negative. - // DOWN 1 The remainder has the same sign as the dividend (JavaScript %). - // FLOOR 3 The remainder has the same sign as the divisor (Python %). - // HALF_EVEN 6 The IEEE 754 remainder function. - // EUCLID 9 Euclidian division. q = sign(n) * floor(a / abs(n)). Always positive. - // - // Truncated division (1), floored division (3), the IEEE 754 remainder (6), and Euclidian - // division (9) are commonly used for the modulus operation. The other rounding modes can also - // be used, but they may not give useful results. - modulo: 1, // 0 to 9 - - // The exponent value at and beneath which `toString` returns exponential notation. - // JavaScript numbers: -7 - toExpNeg: -7, // 0 to -EXP_LIMIT - - // The exponent value at and above which `toString` returns exponential notation. - // JavaScript numbers: 21 - toExpPos: 21, // 0 to EXP_LIMIT - - // The minimum exponent value, beneath which underflow to zero occurs. - // JavaScript numbers: -324 (5e-324) - minE: -EXP_LIMIT, // -1 to -EXP_LIMIT - - // The maximum exponent value, above which overflow to Infinity occurs. - // JavaScript numbers: 308 (1.7976931348623157e+308) - maxE: EXP_LIMIT, // 1 to EXP_LIMIT - - // Whether to use cryptographically-secure random number generation, if available. - crypto: false // true/false - }, - - - // ----------------------------------- END OF EDITABLE DEFAULTS ------------------------------- // - - - inexact, noConflict, quadrant, - external = true, - - decimalError = '[DecimalError] ', - invalidArgument = decimalError + 'Invalid argument: ', - precisionLimitExceeded = decimalError + 'Precision limit exceeded', - cryptoUnavailable = decimalError + 'crypto unavailable', - - mathfloor = Math.floor, - mathpow = Math.pow, - - isBinary = /^0b([01]+(\.[01]*)?|\.[01]+)(p[+-]?\d+)?$/i, - isHex = /^0x([0-9a-f]+(\.[0-9a-f]*)?|\.[0-9a-f]+)(p[+-]?\d+)?$/i, - isOctal = /^0o([0-7]+(\.[0-7]*)?|\.[0-7]+)(p[+-]?\d+)?$/i, - isDecimal = /^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i, - - BASE = 1e7, - LOG_BASE = 7, - MAX_SAFE_INTEGER = 9007199254740991, - - LN10_PRECISION = LN10.length - 1, - PI_PRECISION = PI.length - 1, - - // Decimal.prototype object - P = {}; - - - // Decimal prototype methods - - - /* - * absoluteValue abs - * ceil - * comparedTo cmp - * cosine cos - * cubeRoot cbrt - * decimalPlaces dp - * dividedBy div - * dividedToIntegerBy divToInt - * equals eq - * floor - * greaterThan gt - * greaterThanOrEqualTo gte - * hyperbolicCosine cosh - * hyperbolicSine sinh - * hyperbolicTangent tanh - * inverseCosine acos - * inverseHyperbolicCosine acosh - * inverseHyperbolicSine asinh - * inverseHyperbolicTangent atanh - * inverseSine asin - * inverseTangent atan - * isFinite - * isInteger isInt - * isNaN - * isNegative isNeg - * isPositive isPos - * isZero - * lessThan lt - * lessThanOrEqualTo lte - * logarithm log - * [maximum] [max] - * [minimum] [min] - * minus sub - * modulo mod - * naturalExponential exp - * naturalLogarithm ln - * negated neg - * plus add - * precision sd - * round - * sine sin - * squareRoot sqrt - * tangent tan - * times mul - * toBinary - * toDecimalPlaces toDP - * toExponential - * toFixed - * toFraction - * toHexadecimal toHex - * toNearest - * toNumber - * toOctal - * toPower pow - * toPrecision - * toSignificantDigits toSD - * toString - * truncated trunc - * valueOf toJSON - */ - - - /* - * Return a new Decimal whose value is the absolute value of this Decimal. - * - */ - P.absoluteValue = P.abs = function () { - var x = new this.constructor(this); - if (x.s < 0) x.s = 1; - return finalise(x); - }; - - - /* - * Return a new Decimal whose value is the value of this Decimal rounded to a whole number in the - * direction of positive Infinity. - * - */ - P.ceil = function () { - return finalise(new this.constructor(this), this.e + 1, 2); - }; - - - /* - * Return - * 1 if the value of this Decimal is greater than the value of `y`, - * -1 if the value of this Decimal is less than the value of `y`, - * 0 if they have the same value, - * NaN if the value of either Decimal is NaN. - * - */ - P.comparedTo = P.cmp = function (y) { - var i, j, xdL, ydL, - x = this, - xd = x.d, - yd = (y = new x.constructor(y)).d, - xs = x.s, - ys = y.s; - - // Either NaN or ±Infinity? - if (!xd || !yd) { - return !xs || !ys ? NaN : xs !== ys ? xs : xd === yd ? 0 : !xd ^ xs < 0 ? 1 : -1; - } - - // Either zero? - if (!xd[0] || !yd[0]) return xd[0] ? xs : yd[0] ? -ys : 0; - - // Signs differ? - if (xs !== ys) return xs; - - // Compare exponents. - if (x.e !== y.e) return x.e > y.e ^ xs < 0 ? 1 : -1; - - xdL = xd.length; - ydL = yd.length; - - // Compare digit by digit. - for (i = 0, j = xdL < ydL ? xdL : ydL; i < j; ++i) { - if (xd[i] !== yd[i]) return xd[i] > yd[i] ^ xs < 0 ? 1 : -1; - } - - // Compare lengths. - return xdL === ydL ? 0 : xdL > ydL ^ xs < 0 ? 1 : -1; - }; - - - /* - * Return a new Decimal whose value is the cosine of the value in radians of this Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-1, 1] - * - * cos(0) = 1 - * cos(-0) = 1 - * cos(Infinity) = NaN - * cos(-Infinity) = NaN - * cos(NaN) = NaN - * - */ - P.cosine = P.cos = function () { - var pr, rm, - x = this, - Ctor = x.constructor; - - if (!x.d) return new Ctor(NaN); - - // cos(0) = cos(-0) = 1 - if (!x.d[0]) return new Ctor(1); - - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + Math.max(x.e, x.sd()) + LOG_BASE; - Ctor.rounding = 1; - - x = cosine(Ctor, toLessThanHalfPi(Ctor, x)); - - Ctor.precision = pr; - Ctor.rounding = rm; - - return finalise(quadrant == 2 || quadrant == 3 ? x.neg() : x, pr, rm, true); - }; - - - /* - * - * Return a new Decimal whose value is the cube root of the value of this Decimal, rounded to - * `precision` significant digits using rounding mode `rounding`. - * - * cbrt(0) = 0 - * cbrt(-0) = -0 - * cbrt(1) = 1 - * cbrt(-1) = -1 - * cbrt(N) = N - * cbrt(-I) = -I - * cbrt(I) = I - * - * Math.cbrt(x) = (x < 0 ? -Math.pow(-x, 1/3) : Math.pow(x, 1/3)) - * - */ - P.cubeRoot = P.cbrt = function () { - var e, m, n, r, rep, s, sd, t, t3, t3plusx, - x = this, - Ctor = x.constructor; - - if (!x.isFinite() || x.isZero()) return new Ctor(x); - external = false; - - // Initial estimate. - s = x.s * Math.pow(x.s * x, 1 / 3); - - // Math.cbrt underflow/overflow? - // Pass x to Math.pow as integer, then adjust the exponent of the result. - if (!s || Math.abs(s) == 1 / 0) { - n = digitsToString(x.d); - e = x.e; - - // Adjust n exponent so it is a multiple of 3 away from x exponent. - if (s = (e - n.length + 1) % 3) n += (s == 1 || s == -2 ? '0' : '00'); - s = Math.pow(n, 1 / 3); - - // Rarely, e may be one less than the result exponent value. - e = mathfloor((e + 1) / 3) - (e % 3 == (e < 0 ? -1 : 2)); - - if (s == 1 / 0) { - n = '5e' + e; - } else { - n = s.toExponential(); - n = n.slice(0, n.indexOf('e') + 1) + e; - } - - r = new Ctor(n); - r.s = x.s; - } else { - r = new Ctor(s.toString()); - } - - sd = (e = Ctor.precision) + 3; - - // Halley's method. - // TODO? Compare Newton's method. - for (;;) { - t = r; - t3 = t.times(t).times(t); - t3plusx = t3.plus(x); - r = divide(t3plusx.plus(x).times(t), t3plusx.plus(t3), sd + 2, 1); - - // TODO? Replace with for-loop and checkRoundingDigits. - if (digitsToString(t.d).slice(0, sd) === (n = digitsToString(r.d)).slice(0, sd)) { - n = n.slice(sd - 3, sd + 1); - - // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or 4999 - // , i.e. approaching a rounding boundary, continue the iteration. - if (n == '9999' || !rep && n == '4999') { - - // On the first iteration only, check to see if rounding up gives the exact result as the - // nines may infinitely repeat. - if (!rep) { - finalise(t, e + 1, 0); - - if (t.times(t).times(t).eq(x)) { - r = t; - break; - } - } - - sd += 4; - rep = 1; - } else { - - // If the rounding digits are null, 0{0,4} or 50{0,3}, check for an exact result. - // If not, then there are further digits and m will be truthy. - if (!+n || !+n.slice(1) && n.charAt(0) == '5') { - - // Truncate to the first rounding digit. - finalise(r, e + 1, 1); - m = !r.times(r).times(r).eq(x); - } - - break; - } - } - } - - external = true; - - return finalise(r, e, Ctor.rounding, m); - }; - - - /* - * Return the number of decimal places of the value of this Decimal. - * - */ - P.decimalPlaces = P.dp = function () { - var w, - d = this.d, - n = NaN; - - if (d) { - w = d.length - 1; - n = (w - mathfloor(this.e / LOG_BASE)) * LOG_BASE; - - // Subtract the number of trailing zeros of the last word. - w = d[w]; - if (w) for (; w % 10 == 0; w /= 10) n--; - if (n < 0) n = 0; - } - - return n; - }; - - - /* - * n / 0 = I - * n / N = N - * n / I = 0 - * 0 / n = 0 - * 0 / 0 = N - * 0 / N = N - * 0 / I = 0 - * N / n = N - * N / 0 = N - * N / N = N - * N / I = N - * I / n = I - * I / 0 = I - * I / N = N - * I / I = N - * - * Return a new Decimal whose value is the value of this Decimal divided by `y`, rounded to - * `precision` significant digits using rounding mode `rounding`. - * - */ - P.dividedBy = P.div = function (y) { - return divide(this, new this.constructor(y)); - }; - - - /* - * Return a new Decimal whose value is the integer part of dividing the value of this Decimal - * by the value of `y`, rounded to `precision` significant digits using rounding mode `rounding`. - * - */ - P.dividedToIntegerBy = P.divToInt = function (y) { - var x = this, - Ctor = x.constructor; - return finalise(divide(x, new Ctor(y), 0, 1, 1), Ctor.precision, Ctor.rounding); - }; - - - /* - * Return true if the value of this Decimal is equal to the value of `y`, otherwise return false. - * - */ - P.equals = P.eq = function (y) { - return this.cmp(y) === 0; - }; - - - /* - * Return a new Decimal whose value is the value of this Decimal rounded to a whole number in the - * direction of negative Infinity. - * - */ - P.floor = function () { - return finalise(new this.constructor(this), this.e + 1, 3); - }; - - - /* - * Return true if the value of this Decimal is greater than the value of `y`, otherwise return - * false. - * - */ - P.greaterThan = P.gt = function (y) { - return this.cmp(y) > 0; - }; - - - /* - * Return true if the value of this Decimal is greater than or equal to the value of `y`, - * otherwise return false. - * - */ - P.greaterThanOrEqualTo = P.gte = function (y) { - var k = this.cmp(y); - return k == 1 || k === 0; - }; - - - /* - * Return a new Decimal whose value is the hyperbolic cosine of the value in radians of this - * Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [1, Infinity] - * - * cosh(x) = 1 + x^2/2! + x^4/4! + x^6/6! + ... - * - * cosh(0) = 1 - * cosh(-0) = 1 - * cosh(Infinity) = Infinity - * cosh(-Infinity) = Infinity - * cosh(NaN) = NaN - * - * x time taken (ms) result - * 1000 9 9.8503555700852349694e+433 - * 10000 25 4.4034091128314607936e+4342 - * 100000 171 1.4033316802130615897e+43429 - * 1000000 3817 1.5166076984010437725e+434294 - * 10000000 abandoned after 2 minute wait - * - * TODO? Compare performance of cosh(x) = 0.5 * (exp(x) + exp(-x)) - * - */ - P.hyperbolicCosine = P.cosh = function () { - var k, n, pr, rm, len, - x = this, - Ctor = x.constructor, - one = new Ctor(1); - - if (!x.isFinite()) return new Ctor(x.s ? 1 / 0 : NaN); - if (x.isZero()) return one; - - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + Math.max(x.e, x.sd()) + 4; - Ctor.rounding = 1; - len = x.d.length; - - // Argument reduction: cos(4x) = 1 - 8cos^2(x) + 8cos^4(x) + 1 - // i.e. cos(x) = 1 - cos^2(x/4)(8 - 8cos^2(x/4)) - - // Estimate the optimum number of times to use the argument reduction. - // TODO? Estimation reused from cosine() and may not be optimal here. - if (len < 32) { - k = Math.ceil(len / 3); - n = Math.pow(4, -k).toString(); - } else { - k = 16; - n = '2.3283064365386962890625e-10'; - } - - x = taylorSeries(Ctor, 1, x.times(n), new Ctor(1), true); - - // Reverse argument reduction - var cosh2_x, - i = k, - d8 = new Ctor(8); - for (; i--;) { - cosh2_x = x.times(x); - x = one.minus(cosh2_x.times(d8.minus(cosh2_x.times(d8)))); - } - - return finalise(x, Ctor.precision = pr, Ctor.rounding = rm, true); - }; - - - /* - * Return a new Decimal whose value is the hyperbolic sine of the value in radians of this - * Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-Infinity, Infinity] - * - * sinh(x) = x + x^3/3! + x^5/5! + x^7/7! + ... - * - * sinh(0) = 0 - * sinh(-0) = -0 - * sinh(Infinity) = Infinity - * sinh(-Infinity) = -Infinity - * sinh(NaN) = NaN - * - * x time taken (ms) - * 10 2 ms - * 100 5 ms - * 1000 14 ms - * 10000 82 ms - * 100000 886 ms 1.4033316802130615897e+43429 - * 200000 2613 ms - * 300000 5407 ms - * 400000 8824 ms - * 500000 13026 ms 8.7080643612718084129e+217146 - * 1000000 48543 ms - * - * TODO? Compare performance of sinh(x) = 0.5 * (exp(x) - exp(-x)) - * - */ - P.hyperbolicSine = P.sinh = function () { - var k, pr, rm, len, - x = this, - Ctor = x.constructor; - - if (!x.isFinite() || x.isZero()) return new Ctor(x); - - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + Math.max(x.e, x.sd()) + 4; - Ctor.rounding = 1; - len = x.d.length; - - if (len < 3) { - x = taylorSeries(Ctor, 2, x, x, true); - } else { - - // Alternative argument reduction: sinh(3x) = sinh(x)(3 + 4sinh^2(x)) - // i.e. sinh(x) = sinh(x/3)(3 + 4sinh^2(x/3)) - // 3 multiplications and 1 addition - - // Argument reduction: sinh(5x) = sinh(x)(5 + sinh^2(x)(20 + 16sinh^2(x))) - // i.e. sinh(x) = sinh(x/5)(5 + sinh^2(x/5)(20 + 16sinh^2(x/5))) - // 4 multiplications and 2 additions - - // Estimate the optimum number of times to use the argument reduction. - k = 1.4 * Math.sqrt(len); - k = k > 16 ? 16 : k | 0; - - x = x.times(Math.pow(5, -k)); - - x = taylorSeries(Ctor, 2, x, x, true); - - // Reverse argument reduction - var sinh2_x, - d5 = new Ctor(5), - d16 = new Ctor(16), - d20 = new Ctor(20); - for (; k--;) { - sinh2_x = x.times(x); - x = x.times(d5.plus(sinh2_x.times(d16.times(sinh2_x).plus(d20)))); - } - } - - Ctor.precision = pr; - Ctor.rounding = rm; - - return finalise(x, pr, rm, true); - }; - - - /* - * Return a new Decimal whose value is the hyperbolic tangent of the value in radians of this - * Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-1, 1] - * - * tanh(x) = sinh(x) / cosh(x) - * - * tanh(0) = 0 - * tanh(-0) = -0 - * tanh(Infinity) = 1 - * tanh(-Infinity) = -1 - * tanh(NaN) = NaN - * - */ - P.hyperbolicTangent = P.tanh = function () { - var pr, rm, - x = this, - Ctor = x.constructor; - - if (!x.isFinite()) return new Ctor(x.s); - if (x.isZero()) return new Ctor(x); - - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + 7; - Ctor.rounding = 1; - - return divide(x.sinh(), x.cosh(), Ctor.precision = pr, Ctor.rounding = rm); - }; - - - /* - * Return a new Decimal whose value is the arccosine (inverse cosine) in radians of the value of - * this Decimal. - * - * Domain: [-1, 1] - * Range: [0, pi] - * - * acos(x) = pi/2 - asin(x) - * - * acos(0) = pi/2 - * acos(-0) = pi/2 - * acos(1) = 0 - * acos(-1) = pi - * acos(1/2) = pi/3 - * acos(-1/2) = 2*pi/3 - * acos(|x| > 1) = NaN - * acos(NaN) = NaN - * - */ - P.inverseCosine = P.acos = function () { - var halfPi, - x = this, - Ctor = x.constructor, - k = x.abs().cmp(1), - pr = Ctor.precision, - rm = Ctor.rounding; - - if (k !== -1) { - return k === 0 - // |x| is 1 - ? x.isNeg() ? getPi(Ctor, pr, rm) : new Ctor(0) - // |x| > 1 or x is NaN - : new Ctor(NaN); - } - - if (x.isZero()) return getPi(Ctor, pr + 4, rm).times(0.5); - - // TODO? Special case acos(0.5) = pi/3 and acos(-0.5) = 2*pi/3 - - Ctor.precision = pr + 6; - Ctor.rounding = 1; - - x = x.asin(); - halfPi = getPi(Ctor, pr + 4, rm).times(0.5); - - Ctor.precision = pr; - Ctor.rounding = rm; - - return halfPi.minus(x); - }; - - - /* - * Return a new Decimal whose value is the inverse of the hyperbolic cosine in radians of the - * value of this Decimal. - * - * Domain: [1, Infinity] - * Range: [0, Infinity] - * - * acosh(x) = ln(x + sqrt(x^2 - 1)) - * - * acosh(x < 1) = NaN - * acosh(NaN) = NaN - * acosh(Infinity) = Infinity - * acosh(-Infinity) = NaN - * acosh(0) = NaN - * acosh(-0) = NaN - * acosh(1) = 0 - * acosh(-1) = NaN - * - */ - P.inverseHyperbolicCosine = P.acosh = function () { - var pr, rm, - x = this, - Ctor = x.constructor; - - if (x.lte(1)) return new Ctor(x.eq(1) ? 0 : NaN); - if (!x.isFinite()) return new Ctor(x); - - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + Math.max(Math.abs(x.e), x.sd()) + 4; - Ctor.rounding = 1; - external = false; - - x = x.times(x).minus(1).sqrt().plus(x); - - external = true; - Ctor.precision = pr; - Ctor.rounding = rm; - - return x.ln(); - }; - - - /* - * Return a new Decimal whose value is the inverse of the hyperbolic sine in radians of the value - * of this Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-Infinity, Infinity] - * - * asinh(x) = ln(x + sqrt(x^2 + 1)) - * - * asinh(NaN) = NaN - * asinh(Infinity) = Infinity - * asinh(-Infinity) = -Infinity - * asinh(0) = 0 - * asinh(-0) = -0 - * - */ - P.inverseHyperbolicSine = P.asinh = function () { - var pr, rm, - x = this, - Ctor = x.constructor; - - if (!x.isFinite() || x.isZero()) return new Ctor(x); - - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + 2 * Math.max(Math.abs(x.e), x.sd()) + 6; - Ctor.rounding = 1; - external = false; - - x = x.times(x).plus(1).sqrt().plus(x); - - external = true; - Ctor.precision = pr; - Ctor.rounding = rm; - - return x.ln(); - }; - - - /* - * Return a new Decimal whose value is the inverse of the hyperbolic tangent in radians of the - * value of this Decimal. - * - * Domain: [-1, 1] - * Range: [-Infinity, Infinity] - * - * atanh(x) = 0.5 * ln((1 + x) / (1 - x)) - * - * atanh(|x| > 1) = NaN - * atanh(NaN) = NaN - * atanh(Infinity) = NaN - * atanh(-Infinity) = NaN - * atanh(0) = 0 - * atanh(-0) = -0 - * atanh(1) = Infinity - * atanh(-1) = -Infinity - * - */ - P.inverseHyperbolicTangent = P.atanh = function () { - var pr, rm, wpr, xsd, - x = this, - Ctor = x.constructor; - - if (!x.isFinite()) return new Ctor(NaN); - if (x.e >= 0) return new Ctor(x.abs().eq(1) ? x.s / 0 : x.isZero() ? x : NaN); - - pr = Ctor.precision; - rm = Ctor.rounding; - xsd = x.sd(); - - if (Math.max(xsd, pr) < 2 * -x.e - 1) return finalise(new Ctor(x), pr, rm, true); - - Ctor.precision = wpr = xsd - x.e; - - x = divide(x.plus(1), new Ctor(1).minus(x), wpr + pr, 1); - - Ctor.precision = pr + 4; - Ctor.rounding = 1; - - x = x.ln(); - - Ctor.precision = pr; - Ctor.rounding = rm; - - return x.times(0.5); - }; - - - /* - * Return a new Decimal whose value is the arcsine (inverse sine) in radians of the value of this - * Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-pi/2, pi/2] - * - * asin(x) = 2*atan(x/(1 + sqrt(1 - x^2))) - * - * asin(0) = 0 - * asin(-0) = -0 - * asin(1/2) = pi/6 - * asin(-1/2) = -pi/6 - * asin(1) = pi/2 - * asin(-1) = -pi/2 - * asin(|x| > 1) = NaN - * asin(NaN) = NaN - * - * TODO? Compare performance of Taylor series. - * - */ - P.inverseSine = P.asin = function () { - var halfPi, k, - pr, rm, - x = this, - Ctor = x.constructor; - - if (x.isZero()) return new Ctor(x); - - k = x.abs().cmp(1); - pr = Ctor.precision; - rm = Ctor.rounding; - - if (k !== -1) { - - // |x| is 1 - if (k === 0) { - halfPi = getPi(Ctor, pr + 4, rm).times(0.5); - halfPi.s = x.s; - return halfPi; - } - - // |x| > 1 or x is NaN - return new Ctor(NaN); - } - - // TODO? Special case asin(1/2) = pi/6 and asin(-1/2) = -pi/6 - - Ctor.precision = pr + 6; - Ctor.rounding = 1; - - x = x.div(new Ctor(1).minus(x.times(x)).sqrt().plus(1)).atan(); - - Ctor.precision = pr; - Ctor.rounding = rm; - - return x.times(2); - }; - - - /* - * Return a new Decimal whose value is the arctangent (inverse tangent) in radians of the value - * of this Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-pi/2, pi/2] - * - * atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... - * - * atan(0) = 0 - * atan(-0) = -0 - * atan(1) = pi/4 - * atan(-1) = -pi/4 - * atan(Infinity) = pi/2 - * atan(-Infinity) = -pi/2 - * atan(NaN) = NaN - * - */ - P.inverseTangent = P.atan = function () { - var i, j, k, n, px, t, r, wpr, x2, - x = this, - Ctor = x.constructor, - pr = Ctor.precision, - rm = Ctor.rounding; - - if (!x.isFinite()) { - if (!x.s) return new Ctor(NaN); - if (pr + 4 <= PI_PRECISION) { - r = getPi(Ctor, pr + 4, rm).times(0.5); - r.s = x.s; - return r; - } - } else if (x.isZero()) { - return new Ctor(x); - } else if (x.abs().eq(1) && pr + 4 <= PI_PRECISION) { - r = getPi(Ctor, pr + 4, rm).times(0.25); - r.s = x.s; - return r; - } - - Ctor.precision = wpr = pr + 10; - Ctor.rounding = 1; - - // TODO? if (x >= 1 && pr <= PI_PRECISION) atan(x) = halfPi * x.s - atan(1 / x); - - // Argument reduction - // Ensure |x| < 0.42 - // atan(x) = 2 * atan(x / (1 + sqrt(1 + x^2))) - - k = Math.min(28, wpr / LOG_BASE + 2 | 0); - - for (i = k; i; --i) x = x.div(x.times(x).plus(1).sqrt().plus(1)); - - external = false; - - j = Math.ceil(wpr / LOG_BASE); - n = 1; - x2 = x.times(x); - r = new Ctor(x); - px = x; - - // atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... - for (; i !== -1;) { - px = px.times(x2); - t = r.minus(px.div(n += 2)); - - px = px.times(x2); - r = t.plus(px.div(n += 2)); - - if (r.d[j] !== void 0) for (i = j; r.d[i] === t.d[i] && i--;); - } - - if (k) r = r.times(2 << (k - 1)); - - external = true; - - return finalise(r, Ctor.precision = pr, Ctor.rounding = rm, true); - }; - - - /* - * Return true if the value of this Decimal is a finite number, otherwise return false. - * - */ - P.isFinite = function () { - return !!this.d; - }; - - - /* - * Return true if the value of this Decimal is an integer, otherwise return false. - * - */ - P.isInteger = P.isInt = function () { - return !!this.d && mathfloor(this.e / LOG_BASE) > this.d.length - 2; - }; - - - /* - * Return true if the value of this Decimal is NaN, otherwise return false. - * - */ - P.isNaN = function () { - return !this.s; - }; - - - /* - * Return true if the value of this Decimal is negative, otherwise return false. - * - */ - P.isNegative = P.isNeg = function () { - return this.s < 0; - }; - - - /* - * Return true if the value of this Decimal is positive, otherwise return false. - * - */ - P.isPositive = P.isPos = function () { - return this.s > 0; - }; - - - /* - * Return true if the value of this Decimal is 0 or -0, otherwise return false. - * - */ - P.isZero = function () { - return !!this.d && this.d[0] === 0; - }; - - - /* - * Return true if the value of this Decimal is less than `y`, otherwise return false. - * - */ - P.lessThan = P.lt = function (y) { - return this.cmp(y) < 0; - }; - - - /* - * Return true if the value of this Decimal is less than or equal to `y`, otherwise return false. - * - */ - P.lessThanOrEqualTo = P.lte = function (y) { - return this.cmp(y) < 1; - }; - - - /* - * Return the logarithm of the value of this Decimal to the specified base, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * If no base is specified, return log[10](arg). - * - * log[base](arg) = ln(arg) / ln(base) - * - * The result will always be correctly rounded if the base of the log is 10, and 'almost always' - * otherwise: - * - * Depending on the rounding mode, the result may be incorrectly rounded if the first fifteen - * rounding digits are [49]99999999999999 or [50]00000000000000. In that case, the maximum error - * between the result and the correctly rounded result will be one ulp (unit in the last place). - * - * log[-b](a) = NaN - * log[0](a) = NaN - * log[1](a) = NaN - * log[NaN](a) = NaN - * log[Infinity](a) = NaN - * log[b](0) = -Infinity - * log[b](-0) = -Infinity - * log[b](-a) = NaN - * log[b](1) = 0 - * log[b](Infinity) = Infinity - * log[b](NaN) = NaN - * - * [base] {number|string|Decimal} The base of the logarithm. - * - */ - P.logarithm = P.log = function (base) { - var isBase10, d, denominator, k, inf, num, sd, r, - arg = this, - Ctor = arg.constructor, - pr = Ctor.precision, - rm = Ctor.rounding, - guard = 5; - - // Default base is 10. - if (base == null) { - base = new Ctor(10); - isBase10 = true; - } else { - base = new Ctor(base); - d = base.d; - - // Return NaN if base is negative, or non-finite, or is 0 or 1. - if (base.s < 0 || !d || !d[0] || base.eq(1)) return new Ctor(NaN); - - isBase10 = base.eq(10); - } - - d = arg.d; - - // Is arg negative, non-finite, 0 or 1? - if (arg.s < 0 || !d || !d[0] || arg.eq(1)) { - return new Ctor(d && !d[0] ? -1 / 0 : arg.s != 1 ? NaN : d ? 0 : 1 / 0); - } - - // The result will have a non-terminating decimal expansion if base is 10 and arg is not an - // integer power of 10. - if (isBase10) { - if (d.length > 1) { - inf = true; - } else { - for (k = d[0]; k % 10 === 0;) k /= 10; - inf = k !== 1; - } - } - - external = false; - sd = pr + guard; - num = naturalLogarithm(arg, sd); - denominator = isBase10 ? getLn10(Ctor, sd + 10) : naturalLogarithm(base, sd); - - // The result will have 5 rounding digits. - r = divide(num, denominator, sd, 1); - - // If at a rounding boundary, i.e. the result's rounding digits are [49]9999 or [50]0000, - // calculate 10 further digits. - // - // If the result is known to have an infinite decimal expansion, repeat this until it is clear - // that the result is above or below the boundary. Otherwise, if after calculating the 10 - // further digits, the last 14 are nines, round up and assume the result is exact. - // Also assume the result is exact if the last 14 are zero. - // - // Example of a result that will be incorrectly rounded: - // log[1048576](4503599627370502) = 2.60000000000000009610279511444746... - // The above result correctly rounded using ROUND_CEIL to 1 decimal place should be 2.7, but it - // will be given as 2.6 as there are 15 zeros immediately after the requested decimal place, so - // the exact result would be assumed to be 2.6, which rounded using ROUND_CEIL to 1 decimal - // place is still 2.6. - if (checkRoundingDigits(r.d, k = pr, rm)) { - - do { - sd += 10; - num = naturalLogarithm(arg, sd); - denominator = isBase10 ? getLn10(Ctor, sd + 10) : naturalLogarithm(base, sd); - r = divide(num, denominator, sd, 1); - - if (!inf) { - - // Check for 14 nines from the 2nd rounding digit, as the first may be 4. - if (+digitsToString(r.d).slice(k + 1, k + 15) + 1 == 1e14) { - r = finalise(r, pr + 1, 0); - } - - break; - } - } while (checkRoundingDigits(r.d, k += 10, rm)); - } - - external = true; - - return finalise(r, pr, rm); - }; - - - /* - * Return a new Decimal whose value is the maximum of the arguments and the value of this Decimal. - * - * arguments {number|string|Decimal} - * - P.max = function () { - Array.prototype.push.call(arguments, this); - return maxOrMin(this.constructor, arguments, 'lt'); - }; - */ - - - /* - * Return a new Decimal whose value is the minimum of the arguments and the value of this Decimal. - * - * arguments {number|string|Decimal} - * - P.min = function () { - Array.prototype.push.call(arguments, this); - return maxOrMin(this.constructor, arguments, 'gt'); - }; - */ - - - /* - * n - 0 = n - * n - N = N - * n - I = -I - * 0 - n = -n - * 0 - 0 = 0 - * 0 - N = N - * 0 - I = -I - * N - n = N - * N - 0 = N - * N - N = N - * N - I = N - * I - n = I - * I - 0 = I - * I - N = N - * I - I = N - * - * Return a new Decimal whose value is the value of this Decimal minus `y`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - */ - P.minus = P.sub = function (y) { - var d, e, i, j, k, len, pr, rm, xd, xe, xLTy, yd, - x = this, - Ctor = x.constructor; - - y = new Ctor(y); - - // If either is not finite... - if (!x.d || !y.d) { - - // Return NaN if either is NaN. - if (!x.s || !y.s) y = new Ctor(NaN); - - // Return y negated if x is finite and y is ±Infinity. - else if (x.d) y.s = -y.s; - - // Return x if y is finite and x is ±Infinity. - // Return x if both are ±Infinity with different signs. - // Return NaN if both are ±Infinity with the same sign. - else y = new Ctor(y.d || x.s !== y.s ? x : NaN); - - return y; - } - - // If signs differ... - if (x.s != y.s) { - y.s = -y.s; - return x.plus(y); - } - - xd = x.d; - yd = y.d; - pr = Ctor.precision; - rm = Ctor.rounding; - - // If either is zero... - if (!xd[0] || !yd[0]) { - - // Return y negated if x is zero and y is non-zero. - if (yd[0]) y.s = -y.s; - - // Return x if y is zero and x is non-zero. - else if (xd[0]) y = new Ctor(x); - - // Return zero if both are zero. - // From IEEE 754 (2008) 6.3: 0 - 0 = -0 - -0 = -0 when rounding to -Infinity. - else return new Ctor(rm === 3 ? -0 : 0); - - return external ? finalise(y, pr, rm) : y; - } - - // x and y are finite, non-zero numbers with the same sign. - - // Calculate base 1e7 exponents. - e = mathfloor(y.e / LOG_BASE); - xe = mathfloor(x.e / LOG_BASE); - - xd = xd.slice(); - k = xe - e; - - // If base 1e7 exponents differ... - if (k) { - xLTy = k < 0; - - if (xLTy) { - d = xd; - k = -k; - len = yd.length; - } else { - d = yd; - e = xe; - len = xd.length; - } - - // Numbers with massively different exponents would result in a very high number of - // zeros needing to be prepended, but this can be avoided while still ensuring correct - // rounding by limiting the number of zeros to `Math.ceil(pr / LOG_BASE) + 2`. - i = Math.max(Math.ceil(pr / LOG_BASE), len) + 2; - - if (k > i) { - k = i; - d.length = 1; - } - - // Prepend zeros to equalise exponents. - d.reverse(); - for (i = k; i--;) d.push(0); - d.reverse(); - - // Base 1e7 exponents equal. - } else { - - // Check digits to determine which is the bigger number. - - i = xd.length; - len = yd.length; - xLTy = i < len; - if (xLTy) len = i; - - for (i = 0; i < len; i++) { - if (xd[i] != yd[i]) { - xLTy = xd[i] < yd[i]; - break; - } - } - - k = 0; - } - - if (xLTy) { - d = xd; - xd = yd; - yd = d; - y.s = -y.s; - } - - len = xd.length; - - // Append zeros to `xd` if shorter. - // Don't add zeros to `yd` if shorter as subtraction only needs to start at `yd` length. - for (i = yd.length - len; i > 0; --i) xd[len++] = 0; - - // Subtract yd from xd. - for (i = yd.length; i > k;) { - - if (xd[--i] < yd[i]) { - for (j = i; j && xd[--j] === 0;) xd[j] = BASE - 1; - --xd[j]; - xd[i] += BASE; - } - - xd[i] -= yd[i]; - } - - // Remove trailing zeros. - for (; xd[--len] === 0;) xd.pop(); - - // Remove leading zeros and adjust exponent accordingly. - for (; xd[0] === 0; xd.shift()) --e; - - // Zero? - if (!xd[0]) return new Ctor(rm === 3 ? -0 : 0); - - y.d = xd; - y.e = getBase10Exponent(xd, e); - - return external ? finalise(y, pr, rm) : y; - }; - - - /* - * n % 0 = N - * n % N = N - * n % I = n - * 0 % n = 0 - * -0 % n = -0 - * 0 % 0 = N - * 0 % N = N - * 0 % I = 0 - * N % n = N - * N % 0 = N - * N % N = N - * N % I = N - * I % n = N - * I % 0 = N - * I % N = N - * I % I = N - * - * Return a new Decimal whose value is the value of this Decimal modulo `y`, rounded to - * `precision` significant digits using rounding mode `rounding`. - * - * The result depends on the modulo mode. - * - */ - P.modulo = P.mod = function (y) { - var q, - x = this, - Ctor = x.constructor; - - y = new Ctor(y); - - // Return NaN if x is ±Infinity or NaN, or y is NaN or ±0. - if (!x.d || !y.s || y.d && !y.d[0]) return new Ctor(NaN); - - // Return x if y is ±Infinity or x is ±0. - if (!y.d || x.d && !x.d[0]) { - return finalise(new Ctor(x), Ctor.precision, Ctor.rounding); - } - - // Prevent rounding of intermediate calculations. - external = false; - - if (Ctor.modulo == 9) { - - // Euclidian division: q = sign(y) * floor(x / abs(y)) - // result = x - q * y where 0 <= result < abs(y) - q = divide(x, y.abs(), 0, 3, 1); - q.s *= y.s; - } else { - q = divide(x, y, 0, Ctor.modulo, 1); - } - - q = q.times(y); - - external = true; - - return x.minus(q); - }; - - - /* - * Return a new Decimal whose value is the natural exponential of the value of this Decimal, - * i.e. the base e raised to the power the value of this Decimal, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - */ - P.naturalExponential = P.exp = function () { - return naturalExponential(this); - }; - - - /* - * Return a new Decimal whose value is the natural logarithm of the value of this Decimal, - * rounded to `precision` significant digits using rounding mode `rounding`. - * - */ - P.naturalLogarithm = P.ln = function () { - return naturalLogarithm(this); - }; - - - /* - * Return a new Decimal whose value is the value of this Decimal negated, i.e. as if multiplied by - * -1. - * - */ - P.negated = P.neg = function () { - var x = new this.constructor(this); - x.s = -x.s; - return finalise(x); - }; - - - /* - * n + 0 = n - * n + N = N - * n + I = I - * 0 + n = n - * 0 + 0 = 0 - * 0 + N = N - * 0 + I = I - * N + n = N - * N + 0 = N - * N + N = N - * N + I = N - * I + n = I - * I + 0 = I - * I + N = N - * I + I = I - * - * Return a new Decimal whose value is the value of this Decimal plus `y`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - */ - P.plus = P.add = function (y) { - var carry, d, e, i, k, len, pr, rm, xd, yd, - x = this, - Ctor = x.constructor; - - y = new Ctor(y); - - // If either is not finite... - if (!x.d || !y.d) { - - // Return NaN if either is NaN. - if (!x.s || !y.s) y = new Ctor(NaN); - - // Return x if y is finite and x is ±Infinity. - // Return x if both are ±Infinity with the same sign. - // Return NaN if both are ±Infinity with different signs. - // Return y if x is finite and y is ±Infinity. - else if (!x.d) y = new Ctor(y.d || x.s === y.s ? x : NaN); - - return y; - } - - // If signs differ... - if (x.s != y.s) { - y.s = -y.s; - return x.minus(y); - } - - xd = x.d; - yd = y.d; - pr = Ctor.precision; - rm = Ctor.rounding; - - // If either is zero... - if (!xd[0] || !yd[0]) { - - // Return x if y is zero. - // Return y if y is non-zero. - if (!yd[0]) y = new Ctor(x); - - return external ? finalise(y, pr, rm) : y; - } - - // x and y are finite, non-zero numbers with the same sign. - - // Calculate base 1e7 exponents. - k = mathfloor(x.e / LOG_BASE); - e = mathfloor(y.e / LOG_BASE); - - xd = xd.slice(); - i = k - e; - - // If base 1e7 exponents differ... - if (i) { - - if (i < 0) { - d = xd; - i = -i; - len = yd.length; - } else { - d = yd; - e = k; - len = xd.length; - } - - // Limit number of zeros prepended to max(ceil(pr / LOG_BASE), len) + 1. - k = Math.ceil(pr / LOG_BASE); - len = k > len ? k + 1 : len + 1; - - if (i > len) { - i = len; - d.length = 1; - } - - // Prepend zeros to equalise exponents. Note: Faster to use reverse then do unshifts. - d.reverse(); - for (; i--;) d.push(0); - d.reverse(); - } - - len = xd.length; - i = yd.length; - - // If yd is longer than xd, swap xd and yd so xd points to the longer array. - if (len - i < 0) { - i = len; - d = yd; - yd = xd; - xd = d; - } - - // Only start adding at yd.length - 1 as the further digits of xd can be left as they are. - for (carry = 0; i;) { - carry = (xd[--i] = xd[i] + yd[i] + carry) / BASE | 0; - xd[i] %= BASE; - } - - if (carry) { - xd.unshift(carry); - ++e; - } - - // Remove trailing zeros. - // No need to check for zero, as +x + +y != 0 && -x + -y != 0 - for (len = xd.length; xd[--len] == 0;) xd.pop(); - - y.d = xd; - y.e = getBase10Exponent(xd, e); - - return external ? finalise(y, pr, rm) : y; - }; - - - /* - * Return the number of significant digits of the value of this Decimal. - * - * [z] {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0. - * - */ - P.precision = P.sd = function (z) { - var k, - x = this; - - if (z !== void 0 && z !== !!z && z !== 1 && z !== 0) throw Error(invalidArgument + z); - - if (x.d) { - k = getPrecision(x.d); - if (z && x.e + 1 > k) k = x.e + 1; - } else { - k = NaN; - } - - return k; - }; - - - /* - * Return a new Decimal whose value is the value of this Decimal rounded to a whole number using - * rounding mode `rounding`. - * - */ - P.round = function () { - var x = this, - Ctor = x.constructor; - - return finalise(new Ctor(x), x.e + 1, Ctor.rounding); - }; - - - /* - * Return a new Decimal whose value is the sine of the value in radians of this Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-1, 1] - * - * sin(x) = x - x^3/3! + x^5/5! - ... - * - * sin(0) = 0 - * sin(-0) = -0 - * sin(Infinity) = NaN - * sin(-Infinity) = NaN - * sin(NaN) = NaN - * - */ - P.sine = P.sin = function () { - var pr, rm, - x = this, - Ctor = x.constructor; - - if (!x.isFinite()) return new Ctor(NaN); - if (x.isZero()) return new Ctor(x); - - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + Math.max(x.e, x.sd()) + LOG_BASE; - Ctor.rounding = 1; - - x = sine(Ctor, toLessThanHalfPi(Ctor, x)); - - Ctor.precision = pr; - Ctor.rounding = rm; - - return finalise(quadrant > 2 ? x.neg() : x, pr, rm, true); - }; - - - /* - * Return a new Decimal whose value is the square root of this Decimal, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * sqrt(-n) = N - * sqrt(N) = N - * sqrt(-I) = N - * sqrt(I) = I - * sqrt(0) = 0 - * sqrt(-0) = -0 - * - */ - P.squareRoot = P.sqrt = function () { - var m, n, sd, r, rep, t, - x = this, - d = x.d, - e = x.e, - s = x.s, - Ctor = x.constructor; - - // Negative/NaN/Infinity/zero? - if (s !== 1 || !d || !d[0]) { - return new Ctor(!s || s < 0 && (!d || d[0]) ? NaN : d ? x : 1 / 0); - } - - external = false; - - // Initial estimate. - s = Math.sqrt(+x); - - // Math.sqrt underflow/overflow? - // Pass x to Math.sqrt as integer, then adjust the exponent of the result. - if (s == 0 || s == 1 / 0) { - n = digitsToString(d); - - if ((n.length + e) % 2 == 0) n += '0'; - s = Math.sqrt(n); - e = mathfloor((e + 1) / 2) - (e < 0 || e % 2); - - if (s == 1 / 0) { - n = '1e' + e; - } else { - n = s.toExponential(); - n = n.slice(0, n.indexOf('e') + 1) + e; - } - - r = new Ctor(n); - } else { - r = new Ctor(s.toString()); - } - - sd = (e = Ctor.precision) + 3; - - // Newton-Raphson iteration. - for (;;) { - t = r; - r = t.plus(divide(x, t, sd + 2, 1)).times(0.5); - - // TODO? Replace with for-loop and checkRoundingDigits. - if (digitsToString(t.d).slice(0, sd) === (n = digitsToString(r.d)).slice(0, sd)) { - n = n.slice(sd - 3, sd + 1); - - // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or - // 4999, i.e. approaching a rounding boundary, continue the iteration. - if (n == '9999' || !rep && n == '4999') { - - // On the first iteration only, check to see if rounding up gives the exact result as the - // nines may infinitely repeat. - if (!rep) { - finalise(t, e + 1, 0); - - if (t.times(t).eq(x)) { - r = t; - break; - } - } - - sd += 4; - rep = 1; - } else { - - // If the rounding digits are null, 0{0,4} or 50{0,3}, check for an exact result. - // If not, then there are further digits and m will be truthy. - if (!+n || !+n.slice(1) && n.charAt(0) == '5') { - - // Truncate to the first rounding digit. - finalise(r, e + 1, 1); - m = !r.times(r).eq(x); - } - - break; - } - } - } - - external = true; - - return finalise(r, e, Ctor.rounding, m); - }; - - - /* - * Return a new Decimal whose value is the tangent of the value in radians of this Decimal. - * - * Domain: [-Infinity, Infinity] - * Range: [-Infinity, Infinity] - * - * tan(0) = 0 - * tan(-0) = -0 - * tan(Infinity) = NaN - * tan(-Infinity) = NaN - * tan(NaN) = NaN - * - */ - P.tangent = P.tan = function () { - var pr, rm, - x = this, - Ctor = x.constructor; - - if (!x.isFinite()) return new Ctor(NaN); - if (x.isZero()) return new Ctor(x); - - pr = Ctor.precision; - rm = Ctor.rounding; - Ctor.precision = pr + 10; - Ctor.rounding = 1; - - x = x.sin(); - x.s = 1; - x = divide(x, new Ctor(1).minus(x.times(x)).sqrt(), pr + 10, 0); - - Ctor.precision = pr; - Ctor.rounding = rm; - - return finalise(quadrant == 2 || quadrant == 4 ? x.neg() : x, pr, rm, true); - }; - - - /* - * n * 0 = 0 - * n * N = N - * n * I = I - * 0 * n = 0 - * 0 * 0 = 0 - * 0 * N = N - * 0 * I = N - * N * n = N - * N * 0 = N - * N * N = N - * N * I = N - * I * n = I - * I * 0 = N - * I * N = N - * I * I = I - * - * Return a new Decimal whose value is this Decimal times `y`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - */ - P.times = P.mul = function (y) { - var carry, e, i, k, r, rL, t, xdL, ydL, - x = this, - Ctor = x.constructor, - xd = x.d, - yd = (y = new Ctor(y)).d; - - y.s *= x.s; - - // If either is NaN, ±Infinity or ±0... - if (!xd || !xd[0] || !yd || !yd[0]) { - - return new Ctor(!y.s || xd && !xd[0] && !yd || yd && !yd[0] && !xd - - // Return NaN if either is NaN. - // Return NaN if x is ±0 and y is ±Infinity, or y is ±0 and x is ±Infinity. - ? NaN - - // Return ±Infinity if either is ±Infinity. - // Return ±0 if either is ±0. - : !xd || !yd ? y.s / 0 : y.s * 0); - } - - e = mathfloor(x.e / LOG_BASE) + mathfloor(y.e / LOG_BASE); - xdL = xd.length; - ydL = yd.length; - - // Ensure xd points to the longer array. - if (xdL < ydL) { - r = xd; - xd = yd; - yd = r; - rL = xdL; - xdL = ydL; - ydL = rL; - } - - // Initialise the result array with zeros. - r = []; - rL = xdL + ydL; - for (i = rL; i--;) r.push(0); - - // Multiply! - for (i = ydL; --i >= 0;) { - carry = 0; - for (k = xdL + i; k > i;) { - t = r[k] + yd[i] * xd[k - i - 1] + carry; - r[k--] = t % BASE | 0; - carry = t / BASE | 0; - } - - r[k] = (r[k] + carry) % BASE | 0; - } - - // Remove trailing zeros. - for (; !r[--rL];) r.pop(); - - if (carry) ++e; - else r.shift(); - - y.d = r; - y.e = getBase10Exponent(r, e); - - return external ? finalise(y, Ctor.precision, Ctor.rounding) : y; - }; - - - /* - * Return a string representing the value of this Decimal in base 2, round to `sd` significant - * digits using rounding mode `rm`. - * - * If the optional `sd` argument is present then return binary exponential notation. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ - P.toBinary = function (sd, rm) { - return toStringBinary(this, 2, sd, rm); - }; - - - /* - * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `dp` - * decimal places using rounding mode `rm` or `rounding` if `rm` is omitted. - * - * If `dp` is omitted, return a new Decimal whose value is the value of this Decimal. - * - * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ - P.toDecimalPlaces = P.toDP = function (dp, rm) { - var x = this, - Ctor = x.constructor; - - x = new Ctor(x); - if (dp === void 0) return x; - - checkInt32(dp, 0, MAX_DIGITS); - - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); - - return finalise(x, dp + x.e + 1, rm); - }; - - - /* - * Return a string representing the value of this Decimal in exponential notation rounded to - * `dp` fixed decimal places using rounding mode `rounding`. - * - * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ - P.toExponential = function (dp, rm) { - var str, - x = this, - Ctor = x.constructor; - - if (dp === void 0) { - str = finiteToString(x, true); - } else { - checkInt32(dp, 0, MAX_DIGITS); - - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); - - x = finalise(new Ctor(x), dp + 1, rm); - str = finiteToString(x, true, dp + 1); - } - - return x.isNeg() && !x.isZero() ? '-' + str : str; - }; - - - /* - * Return a string representing the value of this Decimal in normal (fixed-point) notation to - * `dp` fixed decimal places and rounded using rounding mode `rm` or `rounding` if `rm` is - * omitted. - * - * As with JavaScript numbers, (-0).toFixed(0) is '0', but e.g. (-0.00001).toFixed(0) is '-0'. - * - * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - * (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'. - * (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'. - * (-0).toFixed(3) is '0.000'. - * (-0.5).toFixed(0) is '-0'. - * - */ - P.toFixed = function (dp, rm) { - var str, y, - x = this, - Ctor = x.constructor; - - if (dp === void 0) { - str = finiteToString(x); - } else { - checkInt32(dp, 0, MAX_DIGITS); - - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); - - y = finalise(new Ctor(x), dp + x.e + 1, rm); - str = finiteToString(y, false, dp + y.e + 1); - } - - // To determine whether to add the minus sign look at the value before it was rounded, - // i.e. look at `x` rather than `y`. - return x.isNeg() && !x.isZero() ? '-' + str : str; - }; - - - /* - * Return an array representing the value of this Decimal as a simple fraction with an integer - * numerator and an integer denominator. - * - * The denominator will be a positive non-zero value less than or equal to the specified maximum - * denominator. If a maximum denominator is not specified, the denominator will be the lowest - * value necessary to represent the number exactly. - * - * [maxD] {number|string|Decimal} Maximum denominator. Integer >= 1 and < Infinity. - * - */ - P.toFraction = function (maxD) { - var d, d0, d1, d2, e, k, n, n0, n1, pr, q, r, - x = this, - xd = x.d, - Ctor = x.constructor; - - if (!xd) return new Ctor(x); - - n1 = d0 = new Ctor(1); - d1 = n0 = new Ctor(0); - - d = new Ctor(d1); - e = d.e = getPrecision(xd) - x.e - 1; - k = e % LOG_BASE; - d.d[0] = mathpow(10, k < 0 ? LOG_BASE + k : k); - - if (maxD == null) { - - // d is 10**e, the minimum max-denominator needed. - maxD = e > 0 ? d : n1; - } else { - n = new Ctor(maxD); - if (!n.isInt() || n.lt(n1)) throw Error(invalidArgument + n); - maxD = n.gt(d) ? (e > 0 ? d : n1) : n; - } - - external = false; - n = new Ctor(digitsToString(xd)); - pr = Ctor.precision; - Ctor.precision = e = xd.length * LOG_BASE * 2; - - for (;;) { - q = divide(n, d, 0, 1, 1); - d2 = d0.plus(q.times(d1)); - if (d2.cmp(maxD) == 1) break; - d0 = d1; - d1 = d2; - d2 = n1; - n1 = n0.plus(q.times(d2)); - n0 = d2; - d2 = d; - d = n.minus(q.times(d2)); - n = d2; - } - - d2 = divide(maxD.minus(d0), d1, 0, 1, 1); - n0 = n0.plus(d2.times(n1)); - d0 = d0.plus(d2.times(d1)); - n0.s = n1.s = x.s; - - // Determine which fraction is closer to x, n0/d0 or n1/d1? - r = divide(n1, d1, e, 1).minus(x).abs().cmp(divide(n0, d0, e, 1).minus(x).abs()) < 1 - ? [n1, d1] : [n0, d0]; - - Ctor.precision = pr; - external = true; - - return r; - }; - - - /* - * Return a string representing the value of this Decimal in base 16, round to `sd` significant - * digits using rounding mode `rm`. - * - * If the optional `sd` argument is present then return binary exponential notation. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ - P.toHexadecimal = P.toHex = function (sd, rm) { - return toStringBinary(this, 16, sd, rm); - }; - - - - /* - * Returns a new Decimal whose value is the nearest multiple of the magnitude of `y` to the value - * of this Decimal. - * - * If the value of this Decimal is equidistant from two multiples of `y`, the rounding mode `rm`, - * or `Decimal.rounding` if `rm` is omitted, determines the direction of the nearest multiple. - * - * In the context of this method, rounding mode 4 (ROUND_HALF_UP) is the same as rounding mode 0 - * (ROUND_UP), and so on. - * - * The return value will always have the same sign as this Decimal, unless either this Decimal - * or `y` is NaN, in which case the return value will be also be NaN. - * - * The return value is not affected by the value of `precision`. - * - * y {number|string|Decimal} The magnitude to round to a multiple of. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - * 'toNearest() rounding mode not an integer: {rm}' - * 'toNearest() rounding mode out of range: {rm}' - * - */ - P.toNearest = function (y, rm) { - var x = this, - Ctor = x.constructor; - - x = new Ctor(x); - - if (y == null) { - - // If x is not finite, return x. - if (!x.d) return x; - - y = new Ctor(1); - rm = Ctor.rounding; - } else { - y = new Ctor(y); - if (rm !== void 0) checkInt32(rm, 0, 8); - - // If x is not finite, return x if y is not NaN, else NaN. - if (!x.d) return y.s ? x : y; - - // If y is not finite, return Infinity with the sign of x if y is Infinity, else NaN. - if (!y.d) { - if (y.s) y.s = x.s; - return y; - } - } - - // If y is not zero, calculate the nearest multiple of y to x. - if (y.d[0]) { - external = false; - if (rm < 4) rm = [4, 5, 7, 8][rm]; - x = divide(x, y, 0, rm, 1).times(y); - external = true; - finalise(x); - - // If y is zero, return zero with the sign of x. - } else { - y.s = x.s; - x = y; - } - - return x; - }; - - - /* - * Return the value of this Decimal converted to a number primitive. - * Zero keeps its sign. - * - */ - P.toNumber = function () { - return +this; - }; - - - /* - * Return a string representing the value of this Decimal in base 8, round to `sd` significant - * digits using rounding mode `rm`. - * - * If the optional `sd` argument is present then return binary exponential notation. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ - P.toOctal = function (sd, rm) { - return toStringBinary(this, 8, sd, rm); - }; - - - /* - * Return a new Decimal whose value is the value of this Decimal raised to the power `y`, rounded - * to `precision` significant digits using rounding mode `rounding`. - * - * ECMAScript compliant. - * - * pow(x, NaN) = NaN - * pow(x, ±0) = 1 - - * pow(NaN, non-zero) = NaN - * pow(abs(x) > 1, +Infinity) = +Infinity - * pow(abs(x) > 1, -Infinity) = +0 - * pow(abs(x) == 1, ±Infinity) = NaN - * pow(abs(x) < 1, +Infinity) = +0 - * pow(abs(x) < 1, -Infinity) = +Infinity - * pow(+Infinity, y > 0) = +Infinity - * pow(+Infinity, y < 0) = +0 - * pow(-Infinity, odd integer > 0) = -Infinity - * pow(-Infinity, even integer > 0) = +Infinity - * pow(-Infinity, odd integer < 0) = -0 - * pow(-Infinity, even integer < 0) = +0 - * pow(+0, y > 0) = +0 - * pow(+0, y < 0) = +Infinity - * pow(-0, odd integer > 0) = -0 - * pow(-0, even integer > 0) = +0 - * pow(-0, odd integer < 0) = -Infinity - * pow(-0, even integer < 0) = +Infinity - * pow(finite x < 0, finite non-integer) = NaN - * - * For non-integer or very large exponents pow(x, y) is calculated using - * - * x^y = exp(y*ln(x)) - * - * Assuming the first 15 rounding digits are each equally likely to be any digit 0-9, the - * probability of an incorrectly rounded result - * P([49]9{14} | [50]0{14}) = 2 * 0.2 * 10^-14 = 4e-15 = 1/2.5e+14 - * i.e. 1 in 250,000,000,000,000 - * - * If a result is incorrectly rounded the maximum error will be 1 ulp (unit in last place). - * - * y {number|string|Decimal} The power to which to raise this Decimal. - * - */ - P.toPower = P.pow = function (y) { - var e, k, pr, r, rm, s, - x = this, - Ctor = x.constructor, - yn = +(y = new Ctor(y)); - - // Either ±Infinity, NaN or ±0? - if (!x.d || !y.d || !x.d[0] || !y.d[0]) return new Ctor(mathpow(+x, yn)); - - x = new Ctor(x); - - if (x.eq(1)) return x; - - pr = Ctor.precision; - rm = Ctor.rounding; - - if (y.eq(1)) return finalise(x, pr, rm); - - // y exponent - e = mathfloor(y.e / LOG_BASE); - - // If y is a small integer use the 'exponentiation by squaring' algorithm. - if (e >= y.d.length - 1 && (k = yn < 0 ? -yn : yn) <= MAX_SAFE_INTEGER) { - r = intPow(Ctor, x, k, pr); - return y.s < 0 ? new Ctor(1).div(r) : finalise(r, pr, rm); - } - - s = x.s; - - // if x is negative - if (s < 0) { - - // if y is not an integer - if (e < y.d.length - 1) return new Ctor(NaN); - - // Result is positive if x is negative and the last digit of integer y is even. - if ((y.d[e] & 1) == 0) s = 1; - - // if x.eq(-1) - if (x.e == 0 && x.d[0] == 1 && x.d.length == 1) { - x.s = s; - return x; - } - } - - // Estimate result exponent. - // x^y = 10^e, where e = y * log10(x) - // log10(x) = log10(x_significand) + x_exponent - // log10(x_significand) = ln(x_significand) / ln(10) - k = mathpow(+x, yn); - e = k == 0 || !isFinite(k) - ? mathfloor(yn * (Math.log('0.' + digitsToString(x.d)) / Math.LN10 + x.e + 1)) - : new Ctor(k + '').e; - - // Exponent estimate may be incorrect e.g. x: 0.999999999999999999, y: 2.29, e: 0, r.e: -1. - - // Overflow/underflow? - if (e > Ctor.maxE + 1 || e < Ctor.minE - 1) return new Ctor(e > 0 ? s / 0 : 0); - - external = false; - Ctor.rounding = x.s = 1; - - // Estimate the extra guard digits needed to ensure five correct rounding digits from - // naturalLogarithm(x). Example of failure without these extra digits (precision: 10): - // new Decimal(2.32456).pow('2087987436534566.46411') - // should be 1.162377823e+764914905173815, but is 1.162355823e+764914905173815 - k = Math.min(12, (e + '').length); - - // r = x^y = exp(y*ln(x)) - r = naturalExponential(y.times(naturalLogarithm(x, pr + k)), pr); - - // r may be Infinity, e.g. (0.9999999999999999).pow(-1e+40) - if (r.d) { - - // Truncate to the required precision plus five rounding digits. - r = finalise(r, pr + 5, 1); - - // If the rounding digits are [49]9999 or [50]0000 increase the precision by 10 and recalculate - // the result. - if (checkRoundingDigits(r.d, pr, rm)) { - e = pr + 10; - - // Truncate to the increased precision plus five rounding digits. - r = finalise(naturalExponential(y.times(naturalLogarithm(x, e + k)), e), e + 5, 1); - - // Check for 14 nines from the 2nd rounding digit (the first rounding digit may be 4 or 9). - if (+digitsToString(r.d).slice(pr + 1, pr + 15) + 1 == 1e14) { - r = finalise(r, pr + 1, 0); - } - } - } - - r.s = s; - external = true; - Ctor.rounding = rm; - - return finalise(r, pr, rm); - }; - - - /* - * Return a string representing the value of this Decimal rounded to `sd` significant digits - * using rounding mode `rounding`. - * - * Return exponential notation if `sd` is less than the number of digits necessary to represent - * the integer part of the value in normal notation. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - */ - P.toPrecision = function (sd, rm) { - var str, - x = this, - Ctor = x.constructor; - - if (sd === void 0) { - str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos); - } else { - checkInt32(sd, 1, MAX_DIGITS); - - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); - - x = finalise(new Ctor(x), sd, rm); - str = finiteToString(x, sd <= x.e || x.e <= Ctor.toExpNeg, sd); - } - - return x.isNeg() && !x.isZero() ? '-' + str : str; - }; - - - /* - * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `sd` - * significant digits using rounding mode `rm`, or to `precision` and `rounding` respectively if - * omitted. - * - * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. - * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. - * - * 'toSD() digits out of range: {sd}' - * 'toSD() digits not an integer: {sd}' - * 'toSD() rounding mode not an integer: {rm}' - * 'toSD() rounding mode out of range: {rm}' - * - */ - P.toSignificantDigits = P.toSD = function (sd, rm) { - var x = this, - Ctor = x.constructor; - - if (sd === void 0) { - sd = Ctor.precision; - rm = Ctor.rounding; - } else { - checkInt32(sd, 1, MAX_DIGITS); - - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); - } - - return finalise(new Ctor(x), sd, rm); - }; - - - /* - * Return a string representing the value of this Decimal. - * - * Return exponential notation if this Decimal has a positive exponent equal to or greater than - * `toExpPos`, or a negative exponent equal to or less than `toExpNeg`. - * - */ - P.toString = function () { - var x = this, - Ctor = x.constructor, - str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos); - - return x.isNeg() && !x.isZero() ? '-' + str : str; - }; - - - /* - * Return a new Decimal whose value is the value of this Decimal truncated to a whole number. - * - */ - P.truncated = P.trunc = function () { - return finalise(new this.constructor(this), this.e + 1, 1); - }; - - - /* - * Return a string representing the value of this Decimal. - * Unlike `toString`, negative zero will include the minus sign. - * - */ - P.valueOf = P.toJSON = function () { - var x = this, - Ctor = x.constructor, - str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos); - - return x.isNeg() ? '-' + str : str; - }; - - - /* - // Add aliases to match BigDecimal method names. - // P.add = P.plus; - P.subtract = P.minus; - P.multiply = P.times; - P.divide = P.div; - P.remainder = P.mod; - P.compareTo = P.cmp; - P.negate = P.neg; - */ - - - // Helper functions for Decimal.prototype (P) and/or Decimal methods, and their callers. - - - /* - * digitsToString P.cubeRoot, P.logarithm, P.squareRoot, P.toFraction, P.toPower, - * finiteToString, naturalExponential, naturalLogarithm - * checkInt32 P.toDecimalPlaces, P.toExponential, P.toFixed, P.toNearest, - * P.toPrecision, P.toSignificantDigits, toStringBinary, random - * checkRoundingDigits P.logarithm, P.toPower, naturalExponential, naturalLogarithm - * convertBase toStringBinary, parseOther - * cos P.cos - * divide P.atanh, P.cubeRoot, P.dividedBy, P.dividedToIntegerBy, - * P.logarithm, P.modulo, P.squareRoot, P.tan, P.tanh, P.toFraction, - * P.toNearest, toStringBinary, naturalExponential, naturalLogarithm, - * taylorSeries, atan2, parseOther - * finalise P.absoluteValue, P.atan, P.atanh, P.ceil, P.cos, P.cosh, - * P.cubeRoot, P.dividedToIntegerBy, P.floor, P.logarithm, P.minus, - * P.modulo, P.negated, P.plus, P.round, P.sin, P.sinh, P.squareRoot, - * P.tan, P.times, P.toDecimalPlaces, P.toExponential, P.toFixed, - * P.toNearest, P.toPower, P.toPrecision, P.toSignificantDigits, - * P.truncated, divide, getLn10, getPi, naturalExponential, - * naturalLogarithm, ceil, floor, round, trunc - * finiteToString P.toExponential, P.toFixed, P.toPrecision, P.toString, P.valueOf, - * toStringBinary - * getBase10Exponent P.minus, P.plus, P.times, parseOther - * getLn10 P.logarithm, naturalLogarithm - * getPi P.acos, P.asin, P.atan, toLessThanHalfPi, atan2 - * getPrecision P.precision, P.toFraction - * getZeroString digitsToString, finiteToString - * intPow P.toPower, parseOther - * isOdd toLessThanHalfPi - * maxOrMin max, min - * naturalExponential P.naturalExponential, P.toPower - * naturalLogarithm P.acosh, P.asinh, P.atanh, P.logarithm, P.naturalLogarithm, - * P.toPower, naturalExponential - * nonFiniteToString finiteToString, toStringBinary - * parseDecimal Decimal - * parseOther Decimal - * sin P.sin - * taylorSeries P.cosh, P.sinh, cos, sin - * toLessThanHalfPi P.cos, P.sin - * toStringBinary P.toBinary, P.toHexadecimal, P.toOctal - * truncate intPow - * - * Throws: P.logarithm, P.precision, P.toFraction, checkInt32, getLn10, getPi, - * naturalLogarithm, config, parseOther, random, Decimal - */ - - - function digitsToString(d) { - var i, k, ws, - indexOfLastWord = d.length - 1, - str = '', - w = d[0]; - - if (indexOfLastWord > 0) { - str += w; - for (i = 1; i < indexOfLastWord; i++) { - ws = d[i] + ''; - k = LOG_BASE - ws.length; - if (k) str += getZeroString(k); - str += ws; - } - - w = d[i]; - ws = w + ''; - k = LOG_BASE - ws.length; - if (k) str += getZeroString(k); - } else if (w === 0) { - return '0'; - } - - // Remove trailing zeros of last w. - for (; w % 10 === 0;) w /= 10; - - return str + w; - } - - - function checkInt32(i, min, max) { - if (i !== ~~i || i < min || i > max) { - throw Error(invalidArgument + i); - } - } - - - /* - * Check 5 rounding digits if `repeating` is null, 4 otherwise. - * `repeating == null` if caller is `log` or `pow`, - * `repeating != null` if caller is `naturalLogarithm` or `naturalExponential`. - */ - function checkRoundingDigits(d, i, rm, repeating) { - var di, k, r, rd; - - // Get the length of the first word of the array d. - for (k = d[0]; k >= 10; k /= 10) --i; - - // Is the rounding digit in the first word of d? - if (--i < 0) { - i += LOG_BASE; - di = 0; - } else { - di = Math.ceil((i + 1) / LOG_BASE); - i %= LOG_BASE; - } - - // i is the index (0 - 6) of the rounding digit. - // E.g. if within the word 3487563 the first rounding digit is 5, - // then i = 4, k = 1000, rd = 3487563 % 1000 = 563 - k = mathpow(10, LOG_BASE - i); - rd = d[di] % k | 0; - - if (repeating == null) { - if (i < 3) { - if (i == 0) rd = rd / 100 | 0; - else if (i == 1) rd = rd / 10 | 0; - r = rm < 4 && rd == 99999 || rm > 3 && rd == 49999 || rd == 50000 || rd == 0; - } else { - r = (rm < 4 && rd + 1 == k || rm > 3 && rd + 1 == k / 2) && - (d[di + 1] / k / 100 | 0) == mathpow(10, i - 2) - 1 || - (rd == k / 2 || rd == 0) && (d[di + 1] / k / 100 | 0) == 0; - } - } else { - if (i < 4) { - if (i == 0) rd = rd / 1000 | 0; - else if (i == 1) rd = rd / 100 | 0; - else if (i == 2) rd = rd / 10 | 0; - r = (repeating || rm < 4) && rd == 9999 || !repeating && rm > 3 && rd == 4999; - } else { - r = ((repeating || rm < 4) && rd + 1 == k || - (!repeating && rm > 3) && rd + 1 == k / 2) && - (d[di + 1] / k / 1000 | 0) == mathpow(10, i - 3) - 1; - } - } - - return r; - } - - - // Convert string of `baseIn` to an array of numbers of `baseOut`. - // Eg. convertBase('255', 10, 16) returns [15, 15]. - // Eg. convertBase('ff', 16, 10) returns [2, 5, 5]. - function convertBase(str, baseIn, baseOut) { - var j, - arr = [0], - arrL, - i = 0, - strL = str.length; - - for (; i < strL;) { - for (arrL = arr.length; arrL--;) arr[arrL] *= baseIn; - arr[0] += NUMERALS.indexOf(str.charAt(i++)); - for (j = 0; j < arr.length; j++) { - if (arr[j] > baseOut - 1) { - if (arr[j + 1] === void 0) arr[j + 1] = 0; - arr[j + 1] += arr[j] / baseOut | 0; - arr[j] %= baseOut; - } - } - } - - return arr.reverse(); - } - - - /* - * cos(x) = 1 - x^2/2! + x^4/4! - ... - * |x| < pi/2 - * - */ - function cosine(Ctor, x) { - var k, y, - len = x.d.length; - - // Argument reduction: cos(4x) = 8*(cos^4(x) - cos^2(x)) + 1 - // i.e. cos(x) = 8*(cos^4(x/4) - cos^2(x/4)) + 1 - - // Estimate the optimum number of times to use the argument reduction. - if (len < 32) { - k = Math.ceil(len / 3); - y = Math.pow(4, -k).toString(); - } else { - k = 16; - y = '2.3283064365386962890625e-10'; - } - - Ctor.precision += k; - - x = taylorSeries(Ctor, 1, x.times(y), new Ctor(1)); - - // Reverse argument reduction - for (var i = k; i--;) { - var cos2x = x.times(x); - x = cos2x.times(cos2x).minus(cos2x).times(8).plus(1); - } - - Ctor.precision -= k; - - return x; - } - - - /* - * Perform division in the specified base. - */ - var divide = (function () { - - // Assumes non-zero x and k, and hence non-zero result. - function multiplyInteger(x, k, base) { - var temp, - carry = 0, - i = x.length; - - for (x = x.slice(); i--;) { - temp = x[i] * k + carry; - x[i] = temp % base | 0; - carry = temp / base | 0; - } - - if (carry) x.unshift(carry); - - return x; - } - - function compare(a, b, aL, bL) { - var i, r; - - if (aL != bL) { - r = aL > bL ? 1 : -1; - } else { - for (i = r = 0; i < aL; i++) { - if (a[i] != b[i]) { - r = a[i] > b[i] ? 1 : -1; - break; - } - } - } - - return r; - } - - function subtract(a, b, aL, base) { - var i = 0; - - // Subtract b from a. - for (; aL--;) { - a[aL] -= i; - i = a[aL] < b[aL] ? 1 : 0; - a[aL] = i * base + a[aL] - b[aL]; - } - - // Remove leading zeros. - for (; !a[0] && a.length > 1;) a.shift(); - } - - return function (x, y, pr, rm, dp, base) { - var cmp, e, i, k, logBase, more, prod, prodL, q, qd, rem, remL, rem0, sd, t, xi, xL, yd0, - yL, yz, - Ctor = x.constructor, - sign = x.s == y.s ? 1 : -1, - xd = x.d, - yd = y.d; - - // Either NaN, Infinity or 0? - if (!xd || !xd[0] || !yd || !yd[0]) { - - return new Ctor(// Return NaN if either NaN, or both Infinity or 0. - !x.s || !y.s || (xd ? yd && xd[0] == yd[0] : !yd) ? NaN : - - // Return ±0 if x is 0 or y is ±Infinity, or return ±Infinity as y is 0. - xd && xd[0] == 0 || !yd ? sign * 0 : sign / 0); - } - - if (base) { - logBase = 1; - e = x.e - y.e; - } else { - base = BASE; - logBase = LOG_BASE; - e = mathfloor(x.e / logBase) - mathfloor(y.e / logBase); - } - - yL = yd.length; - xL = xd.length; - q = new Ctor(sign); - qd = q.d = []; - - // Result exponent may be one less than e. - // The digit array of a Decimal from toStringBinary may have trailing zeros. - for (i = 0; yd[i] == (xd[i] || 0); i++); - - if (yd[i] > (xd[i] || 0)) e--; - - if (pr == null) { - sd = pr = Ctor.precision; - rm = Ctor.rounding; - } else if (dp) { - sd = pr + (x.e - y.e) + 1; - } else { - sd = pr; - } - - if (sd < 0) { - qd.push(1); - more = true; - } else { - - // Convert precision in number of base 10 digits to base 1e7 digits. - sd = sd / logBase + 2 | 0; - i = 0; - - // divisor < 1e7 - if (yL == 1) { - k = 0; - yd = yd[0]; - sd++; - - // k is the carry. - for (; (i < xL || k) && sd--; i++) { - t = k * base + (xd[i] || 0); - qd[i] = t / yd | 0; - k = t % yd | 0; - } - - more = k || i < xL; - - // divisor >= 1e7 - } else { - - // Normalise xd and yd so highest order digit of yd is >= base/2 - k = base / (yd[0] + 1) | 0; - - if (k > 1) { - yd = multiplyInteger(yd, k, base); - xd = multiplyInteger(xd, k, base); - yL = yd.length; - xL = xd.length; - } - - xi = yL; - rem = xd.slice(0, yL); - remL = rem.length; - - // Add zeros to make remainder as long as divisor. - for (; remL < yL;) rem[remL++] = 0; - - yz = yd.slice(); - yz.unshift(0); - yd0 = yd[0]; - - if (yd[1] >= base / 2) ++yd0; - - do { - k = 0; - - // Compare divisor and remainder. - cmp = compare(yd, rem, yL, remL); - - // If divisor < remainder. - if (cmp < 0) { - - // Calculate trial digit, k. - rem0 = rem[0]; - if (yL != remL) rem0 = rem0 * base + (rem[1] || 0); - - // k will be how many times the divisor goes into the current remainder. - k = rem0 / yd0 | 0; - - // Algorithm: - // 1. product = divisor * trial digit (k) - // 2. if product > remainder: product -= divisor, k-- - // 3. remainder -= product - // 4. if product was < remainder at 2: - // 5. compare new remainder and divisor - // 6. If remainder > divisor: remainder -= divisor, k++ - - if (k > 1) { - if (k >= base) k = base - 1; - - // product = divisor * trial digit. - prod = multiplyInteger(yd, k, base); - prodL = prod.length; - remL = rem.length; - - // Compare product and remainder. - cmp = compare(prod, rem, prodL, remL); - - // product > remainder. - if (cmp == 1) { - k--; - - // Subtract divisor from product. - subtract(prod, yL < prodL ? yz : yd, prodL, base); - } - } else { - - // cmp is -1. - // If k is 0, there is no need to compare yd and rem again below, so change cmp to 1 - // to avoid it. If k is 1 there is a need to compare yd and rem again below. - if (k == 0) cmp = k = 1; - prod = yd.slice(); - } - - prodL = prod.length; - if (prodL < remL) prod.unshift(0); - - // Subtract product from remainder. - subtract(rem, prod, remL, base); - - // If product was < previous remainder. - if (cmp == -1) { - remL = rem.length; - - // Compare divisor and new remainder. - cmp = compare(yd, rem, yL, remL); - - // If divisor < new remainder, subtract divisor from remainder. - if (cmp < 1) { - k++; - - // Subtract divisor from remainder. - subtract(rem, yL < remL ? yz : yd, remL, base); - } - } - - remL = rem.length; - } else if (cmp === 0) { - k++; - rem = [0]; - } // if cmp === 1, k will be 0 - - // Add the next digit, k, to the result array. - qd[i++] = k; - - // Update the remainder. - if (cmp && rem[0]) { - rem[remL++] = xd[xi] || 0; - } else { - rem = [xd[xi]]; - remL = 1; - } - - } while ((xi++ < xL || rem[0] !== void 0) && sd--); - - more = rem[0] !== void 0; - } - - // Leading zero? - if (!qd[0]) qd.shift(); - } - - // logBase is 1 when divide is being used for base conversion. - if (logBase == 1) { - q.e = e; - inexact = more; - } else { - - // To calculate q.e, first get the number of digits of qd[0]. - for (i = 1, k = qd[0]; k >= 10; k /= 10) i++; - q.e = i + e * logBase - 1; - - finalise(q, dp ? pr + q.e + 1 : pr, rm, more); - } - - return q; - }; - })(); - - - /* - * Round `x` to `sd` significant digits using rounding mode `rm`. - * Check for over/under-flow. - */ - function finalise(x, sd, rm, isTruncated) { - var digits, i, j, k, rd, roundUp, w, xd, xdi, - Ctor = x.constructor; - - // Don't round if sd is null or undefined. - out: if (sd != null) { - xd = x.d; - - // Infinity/NaN. - if (!xd) return x; - - // rd: the rounding digit, i.e. the digit after the digit that may be rounded up. - // w: the word of xd containing rd, a base 1e7 number. - // xdi: the index of w within xd. - // digits: the number of digits of w. - // i: what would be the index of rd within w if all the numbers were 7 digits long (i.e. if - // they had leading zeros) - // j: if > 0, the actual index of rd within w (if < 0, rd is a leading zero). - - // Get the length of the first word of the digits array xd. - for (digits = 1, k = xd[0]; k >= 10; k /= 10) digits++; - i = sd - digits; - - // Is the rounding digit in the first word of xd? - if (i < 0) { - i += LOG_BASE; - j = sd; - w = xd[xdi = 0]; - - // Get the rounding digit at index j of w. - rd = w / mathpow(10, digits - j - 1) % 10 | 0; - } else { - xdi = Math.ceil((i + 1) / LOG_BASE); - k = xd.length; - if (xdi >= k) { - if (isTruncated) { - - // Needed by `naturalExponential`, `naturalLogarithm` and `squareRoot`. - for (; k++ <= xdi;) xd.push(0); - w = rd = 0; - digits = 1; - i %= LOG_BASE; - j = i - LOG_BASE + 1; - } else { - break out; - } - } else { - w = k = xd[xdi]; - - // Get the number of digits of w. - for (digits = 1; k >= 10; k /= 10) digits++; - - // Get the index of rd within w. - i %= LOG_BASE; - - // Get the index of rd within w, adjusted for leading zeros. - // The number of leading zeros of w is given by LOG_BASE - digits. - j = i - LOG_BASE + digits; - - // Get the rounding digit at index j of w. - rd = j < 0 ? 0 : w / mathpow(10, digits - j - 1) % 10 | 0; - } - } - - // Are there any non-zero digits after the rounding digit? - isTruncated = isTruncated || sd < 0 || - xd[xdi + 1] !== void 0 || (j < 0 ? w : w % mathpow(10, digits - j - 1)); - - // The expression `w % mathpow(10, digits - j - 1)` returns all the digits of w to the right - // of the digit at (left-to-right) index j, e.g. if w is 908714 and j is 2, the expression - // will give 714. - - roundUp = rm < 4 - ? (rd || isTruncated) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) - : rd > 5 || rd == 5 && (rm == 4 || isTruncated || rm == 6 && - - // Check whether the digit to the left of the rounding digit is odd. - ((i > 0 ? j > 0 ? w / mathpow(10, digits - j) : 0 : xd[xdi - 1]) % 10) & 1 || - rm == (x.s < 0 ? 8 : 7)); - - if (sd < 1 || !xd[0]) { - xd.length = 0; - if (roundUp) { - - // Convert sd to decimal places. - sd -= x.e + 1; - - // 1, 0.1, 0.01, 0.001, 0.0001 etc. - xd[0] = mathpow(10, (LOG_BASE - sd % LOG_BASE) % LOG_BASE); - x.e = -sd || 0; - } else { - - // Zero. - xd[0] = x.e = 0; - } - - return x; - } - - // Remove excess digits. - if (i == 0) { - xd.length = xdi; - k = 1; - xdi--; - } else { - xd.length = xdi + 1; - k = mathpow(10, LOG_BASE - i); - - // E.g. 56700 becomes 56000 if 7 is the rounding digit. - // j > 0 means i > number of leading zeros of w. - xd[xdi] = j > 0 ? (w / mathpow(10, digits - j) % mathpow(10, j) | 0) * k : 0; - } - - if (roundUp) { - for (;;) { - - // Is the digit to be rounded up in the first word of xd? - if (xdi == 0) { - - // i will be the length of xd[0] before k is added. - for (i = 1, j = xd[0]; j >= 10; j /= 10) i++; - j = xd[0] += k; - for (k = 1; j >= 10; j /= 10) k++; - - // if i != k the length has increased. - if (i != k) { - x.e++; - if (xd[0] == BASE) xd[0] = 1; - } - - break; - } else { - xd[xdi] += k; - if (xd[xdi] != BASE) break; - xd[xdi--] = 0; - k = 1; - } - } - } - - // Remove trailing zeros. - for (i = xd.length; xd[--i] === 0;) xd.pop(); - } - - if (external) { - - // Overflow? - if (x.e > Ctor.maxE) { - - // Infinity. - x.d = null; - x.e = NaN; - - // Underflow? - } else if (x.e < Ctor.minE) { - - // Zero. - x.e = 0; - x.d = [0]; - // Ctor.underflow = true; - } // else Ctor.underflow = false; - } - - return x; - } - - - function finiteToString(x, isExp, sd) { - if (!x.isFinite()) return nonFiniteToString(x); - var k, - e = x.e, - str = digitsToString(x.d), - len = str.length; - - if (isExp) { - if (sd && (k = sd - len) > 0) { - str = str.charAt(0) + '.' + str.slice(1) + getZeroString(k); - } else if (len > 1) { - str = str.charAt(0) + '.' + str.slice(1); - } - - str = str + (x.e < 0 ? 'e' : 'e+') + x.e; - } else if (e < 0) { - str = '0.' + getZeroString(-e - 1) + str; - if (sd && (k = sd - len) > 0) str += getZeroString(k); - } else if (e >= len) { - str += getZeroString(e + 1 - len); - if (sd && (k = sd - e - 1) > 0) str = str + '.' + getZeroString(k); - } else { - if ((k = e + 1) < len) str = str.slice(0, k) + '.' + str.slice(k); - if (sd && (k = sd - len) > 0) { - if (e + 1 === len) str += '.'; - str += getZeroString(k); - } - } - - return str; - } - - - // Calculate the base 10 exponent from the base 1e7 exponent. - function getBase10Exponent(digits, e) { - var w = digits[0]; - - // Add the number of digits of the first word of the digits array. - for ( e *= LOG_BASE; w >= 10; w /= 10) e++; - return e; - } - - - function getLn10(Ctor, sd, pr) { - if (sd > LN10_PRECISION) { - - // Reset global state in case the exception is caught. - external = true; - if (pr) Ctor.precision = pr; - throw Error(precisionLimitExceeded); - } - return finalise(new Ctor(LN10), sd, 1, true); - } - - - function getPi(Ctor, sd, rm) { - if (sd > PI_PRECISION) throw Error(precisionLimitExceeded); - return finalise(new Ctor(PI), sd, rm, true); - } - - - function getPrecision(digits) { - var w = digits.length - 1, - len = w * LOG_BASE + 1; - - w = digits[w]; - - // If non-zero... - if (w) { - - // Subtract the number of trailing zeros of the last word. - for (; w % 10 == 0; w /= 10) len--; - - // Add the number of digits of the first word. - for (w = digits[0]; w >= 10; w /= 10) len++; - } - - return len; - } - - - function getZeroString(k) { - var zs = ''; - for (; k--;) zs += '0'; - return zs; - } - - - /* - * Return a new Decimal whose value is the value of Decimal `x` to the power `n`, where `n` is an - * integer of type number. - * - * Implements 'exponentiation by squaring'. Called by `pow` and `parseOther`. - * - */ - function intPow(Ctor, x, n, pr) { - var isTruncated, - r = new Ctor(1), - - // Max n of 9007199254740991 takes 53 loop iterations. - // Maximum digits array length; leaves [28, 34] guard digits. - k = Math.ceil(pr / LOG_BASE + 4); - - external = false; - - for (;;) { - if (n % 2) { - r = r.times(x); - if (truncate(r.d, k)) isTruncated = true; - } - - n = mathfloor(n / 2); - if (n === 0) { - - // To ensure correct rounding when r.d is truncated, increment the last word if it is zero. - n = r.d.length - 1; - if (isTruncated && r.d[n] === 0) ++r.d[n]; - break; - } - - x = x.times(x); - truncate(x.d, k); - } - - external = true; - - return r; - } - - - function isOdd(n) { - return n.d[n.d.length - 1] & 1; - } - - - /* - * Handle `max` and `min`. `ltgt` is 'lt' or 'gt'. - */ - function maxOrMin(Ctor, args, ltgt) { - var y, - x = new Ctor(args[0]), - i = 0; - - for (; ++i < args.length;) { - y = new Ctor(args[i]); - if (!y.s) { - x = y; - break; - } else if (x[ltgt](y)) { - x = y; - } - } - - return x; - } - - - /* - * Return a new Decimal whose value is the natural exponential of `x` rounded to `sd` significant - * digits. - * - * Taylor/Maclaurin series. - * - * exp(x) = x^0/0! + x^1/1! + x^2/2! + x^3/3! + ... - * - * Argument reduction: - * Repeat x = x / 32, k += 5, until |x| < 0.1 - * exp(x) = exp(x / 2^k)^(2^k) - * - * Previously, the argument was initially reduced by - * exp(x) = exp(r) * 10^k where r = x - k * ln10, k = floor(x / ln10) - * to first put r in the range [0, ln10], before dividing by 32 until |x| < 0.1, but this was - * found to be slower than just dividing repeatedly by 32 as above. - * - * Max integer argument: exp('20723265836946413') = 6.3e+9000000000000000 - * Min integer argument: exp('-20723265836946411') = 1.2e-9000000000000000 - * (Math object integer min/max: Math.exp(709) = 8.2e+307, Math.exp(-745) = 5e-324) - * - * exp(Infinity) = Infinity - * exp(-Infinity) = 0 - * exp(NaN) = NaN - * exp(±0) = 1 - * - * exp(x) is non-terminating for any finite, non-zero x. - * - * The result will always be correctly rounded. - * - */ - function naturalExponential(x, sd) { - var denominator, guard, j, pow, sum, t, wpr, - rep = 0, - i = 0, - k = 0, - Ctor = x.constructor, - rm = Ctor.rounding, - pr = Ctor.precision; - - // 0/NaN/Infinity? - if (!x.d || !x.d[0] || x.e > 17) { - - return new Ctor(x.d - ? !x.d[0] ? 1 : x.s < 0 ? 0 : 1 / 0 - : x.s ? x.s < 0 ? 0 : x : 0 / 0); - } - - if (sd == null) { - external = false; - wpr = pr; - } else { - wpr = sd; - } - - t = new Ctor(0.03125); - - // while abs(x) >= 0.1 - while (x.e > -2) { - - // x = x / 2^5 - x = x.times(t); - k += 5; - } - - // Use 2 * log10(2^k) + 5 (empirically derived) to estimate the increase in precision - // necessary to ensure the first 4 rounding digits are correct. - guard = Math.log(mathpow(2, k)) / Math.LN10 * 2 + 5 | 0; - wpr += guard; - denominator = pow = sum = new Ctor(1); - Ctor.precision = wpr; - - for (;;) { - pow = finalise(pow.times(x), wpr, 1); - denominator = denominator.times(++i); - t = sum.plus(divide(pow, denominator, wpr, 1)); - - if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { - j = k; - while (j--) sum = finalise(sum.times(sum), wpr, 1); - - // Check to see if the first 4 rounding digits are [49]999. - // If so, repeat the summation with a higher precision, otherwise - // e.g. with precision: 18, rounding: 1 - // exp(18.404272462595034083567793919843761) = 98372560.1229999999 (should be 98372560.123) - // `wpr - guard` is the index of first rounding digit. - if (sd == null) { - - if (rep < 3 && checkRoundingDigits(sum.d, wpr - guard, rm, rep)) { - Ctor.precision = wpr += 10; - denominator = pow = t = new Ctor(1); - i = 0; - rep++; - } else { - return finalise(sum, Ctor.precision = pr, rm, external = true); - } - } else { - Ctor.precision = pr; - return sum; - } - } - - sum = t; - } - } - - - /* - * Return a new Decimal whose value is the natural logarithm of `x` rounded to `sd` significant - * digits. - * - * ln(-n) = NaN - * ln(0) = -Infinity - * ln(-0) = -Infinity - * ln(1) = 0 - * ln(Infinity) = Infinity - * ln(-Infinity) = NaN - * ln(NaN) = NaN - * - * ln(n) (n != 1) is non-terminating. - * - */ - function naturalLogarithm(y, sd) { - var c, c0, denominator, e, numerator, rep, sum, t, wpr, x1, x2, - n = 1, - guard = 10, - x = y, - xd = x.d, - Ctor = x.constructor, - rm = Ctor.rounding, - pr = Ctor.precision; - - // Is x negative or Infinity, NaN, 0 or 1? - if (x.s < 0 || !xd || !xd[0] || !x.e && xd[0] == 1 && xd.length == 1) { - return new Ctor(xd && !xd[0] ? -1 / 0 : x.s != 1 ? NaN : xd ? 0 : x); - } - - if (sd == null) { - external = false; - wpr = pr; - } else { - wpr = sd; - } - - Ctor.precision = wpr += guard; - c = digitsToString(xd); - c0 = c.charAt(0); - - if (Math.abs(e = x.e) < 1.5e15) { - - // Argument reduction. - // The series converges faster the closer the argument is to 1, so using - // ln(a^b) = b * ln(a), ln(a) = ln(a^b) / b - // multiply the argument by itself until the leading digits of the significand are 7, 8, 9, - // 10, 11, 12 or 13, recording the number of multiplications so the sum of the series can - // later be divided by this number, then separate out the power of 10 using - // ln(a*10^b) = ln(a) + b*ln(10). - - // max n is 21 (gives 0.9, 1.0 or 1.1) (9e15 / 21 = 4.2e14). - //while (c0 < 9 && c0 != 1 || c0 == 1 && c.charAt(1) > 1) { - // max n is 6 (gives 0.7 - 1.3) - while (c0 < 7 && c0 != 1 || c0 == 1 && c.charAt(1) > 3) { - x = x.times(y); - c = digitsToString(x.d); - c0 = c.charAt(0); - n++; - } - - e = x.e; - - if (c0 > 1) { - x = new Ctor('0.' + c); - e++; - } else { - x = new Ctor(c0 + '.' + c.slice(1)); - } - } else { - - // The argument reduction method above may result in overflow if the argument y is a massive - // number with exponent >= 1500000000000000 (9e15 / 6 = 1.5e15), so instead recall this - // function using ln(x*10^e) = ln(x) + e*ln(10). - t = getLn10(Ctor, wpr + 2, pr).times(e + ''); - x = naturalLogarithm(new Ctor(c0 + '.' + c.slice(1)), wpr - guard).plus(t); - Ctor.precision = pr; - - return sd == null ? finalise(x, pr, rm, external = true) : x; - } - - // x1 is x reduced to a value near 1. - x1 = x; - - // Taylor series. - // ln(y) = ln((1 + x)/(1 - x)) = 2(x + x^3/3 + x^5/5 + x^7/7 + ...) - // where x = (y - 1)/(y + 1) (|x| < 1) - sum = numerator = x = divide(x.minus(1), x.plus(1), wpr, 1); - x2 = finalise(x.times(x), wpr, 1); - denominator = 3; - - for (;;) { - numerator = finalise(numerator.times(x2), wpr, 1); - t = sum.plus(divide(numerator, new Ctor(denominator), wpr, 1)); - - if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { - sum = sum.times(2); - - // Reverse the argument reduction. Check that e is not 0 because, besides preventing an - // unnecessary calculation, -0 + 0 = +0 and to ensure correct rounding -0 needs to stay -0. - if (e !== 0) sum = sum.plus(getLn10(Ctor, wpr + 2, pr).times(e + '')); - sum = divide(sum, new Ctor(n), wpr, 1); - - // Is rm > 3 and the first 4 rounding digits 4999, or rm < 4 (or the summation has - // been repeated previously) and the first 4 rounding digits 9999? - // If so, restart the summation with a higher precision, otherwise - // e.g. with precision: 12, rounding: 1 - // ln(135520028.6126091714265381533) = 18.7246299999 when it should be 18.72463. - // `wpr - guard` is the index of first rounding digit. - if (sd == null) { - if (checkRoundingDigits(sum.d, wpr - guard, rm, rep)) { - Ctor.precision = wpr += guard; - t = numerator = x = divide(x1.minus(1), x1.plus(1), wpr, 1); - x2 = finalise(x.times(x), wpr, 1); - denominator = rep = 1; - } else { - return finalise(sum, Ctor.precision = pr, rm, external = true); - } - } else { - Ctor.precision = pr; - return sum; - } - } - - sum = t; - denominator += 2; - } - } - - - // ±Infinity, NaN. - function nonFiniteToString(x) { - // Unsigned. - return String(x.s * x.s / 0); - } - - - /* - * Parse the value of a new Decimal `x` from string `str`. - */ - function parseDecimal(x, str) { - var e, i, len; - - // Decimal point? - if ((e = str.indexOf('.')) > -1) str = str.replace('.', ''); - - // Exponential form? - if ((i = str.search(/e/i)) > 0) { - - // Determine exponent. - if (e < 0) e = i; - e += +str.slice(i + 1); - str = str.substring(0, i); - } else if (e < 0) { - - // Integer. - e = str.length; - } - - // Determine leading zeros. - for (i = 0; str.charCodeAt(i) === 48; i++); - - // Determine trailing zeros. - for (len = str.length; str.charCodeAt(len - 1) === 48; --len); - str = str.slice(i, len); - - if (str) { - len -= i; - x.e = e = e - i - 1; - x.d = []; - - // Transform base - - // e is the base 10 exponent. - // i is where to slice str to get the first word of the digits array. - i = (e + 1) % LOG_BASE; - if (e < 0) i += LOG_BASE; - - if (i < len) { - if (i) x.d.push(+str.slice(0, i)); - for (len -= LOG_BASE; i < len;) x.d.push(+str.slice(i, i += LOG_BASE)); - str = str.slice(i); - i = LOG_BASE - str.length; - } else { - i -= len; - } - - for (; i--;) str += '0'; - x.d.push(+str); - - if (external) { - - // Overflow? - if (x.e > x.constructor.maxE) { - - // Infinity. - x.d = null; - x.e = NaN; - - // Underflow? - } else if (x.e < x.constructor.minE) { - - // Zero. - x.e = 0; - x.d = [0]; - // x.constructor.underflow = true; - } // else x.constructor.underflow = false; - } - } else { - - // Zero. - x.e = 0; - x.d = [0]; - } - - return x; - } - - - /* - * Parse the value of a new Decimal `x` from a string `str`, which is not a decimal value. - */ - function parseOther(x, str) { - var base, Ctor, divisor, i, isFloat, len, p, xd, xe; - - if (str === 'Infinity' || str === 'NaN') { - if (!+str) x.s = NaN; - x.e = NaN; - x.d = null; - return x; - } - - if (isHex.test(str)) { - base = 16; - str = str.toLowerCase(); - } else if (isBinary.test(str)) { - base = 2; - } else if (isOctal.test(str)) { - base = 8; - } else { - throw Error(invalidArgument + str); - } - - // Is there a binary exponent part? - i = str.search(/p/i); - - if (i > 0) { - p = +str.slice(i + 1); - str = str.substring(2, i); - } else { - str = str.slice(2); - } - - // Convert `str` as an integer then divide the result by `base` raised to a power such that the - // fraction part will be restored. - i = str.indexOf('.'); - isFloat = i >= 0; - Ctor = x.constructor; - - if (isFloat) { - str = str.replace('.', ''); - len = str.length; - i = len - i; - - // log[10](16) = 1.2041... , log[10](88) = 1.9444.... - divisor = intPow(Ctor, new Ctor(base), i, i * 2); - } - - xd = convertBase(str, base, BASE); - xe = xd.length - 1; - - // Remove trailing zeros. - for (i = xe; xd[i] === 0; --i) xd.pop(); - if (i < 0) return new Ctor(x.s * 0); - x.e = getBase10Exponent(xd, xe); - x.d = xd; - external = false; - - // At what precision to perform the division to ensure exact conversion? - // maxDecimalIntegerPartDigitCount = ceil(log[10](b) * otherBaseIntegerPartDigitCount) - // log[10](2) = 0.30103, log[10](8) = 0.90309, log[10](16) = 1.20412 - // E.g. ceil(1.2 * 3) = 4, so up to 4 decimal digits are needed to represent 3 hex int digits. - // maxDecimalFractionPartDigitCount = {Hex:4|Oct:3|Bin:1} * otherBaseFractionPartDigitCount - // Therefore using 4 * the number of digits of str will always be enough. - if (isFloat) x = divide(x, divisor, len * 4); - - // Multiply by the binary exponent part if present. - if (p) x = x.times(Math.abs(p) < 54 ? Math.pow(2, p) : Decimal.pow(2, p)); - external = true; - - return x; - } - - - /* - * sin(x) = x - x^3/3! + x^5/5! - ... - * |x| < pi/2 - * - */ - function sine(Ctor, x) { - var k, - len = x.d.length; - - if (len < 3) return taylorSeries(Ctor, 2, x, x); - - // Argument reduction: sin(5x) = 16*sin^5(x) - 20*sin^3(x) + 5*sin(x) - // i.e. sin(x) = 16*sin^5(x/5) - 20*sin^3(x/5) + 5*sin(x/5) - // and sin(x) = sin(x/5)(5 + sin^2(x/5)(16sin^2(x/5) - 20)) - - // Estimate the optimum number of times to use the argument reduction. - k = 1.4 * Math.sqrt(len); - k = k > 16 ? 16 : k | 0; - - // Max k before Math.pow precision loss is 22 - x = x.times(Math.pow(5, -k)); - x = taylorSeries(Ctor, 2, x, x); - - // Reverse argument reduction - var sin2_x, - d5 = new Ctor(5), - d16 = new Ctor(16), - d20 = new Ctor(20); - for (; k--;) { - sin2_x = x.times(x); - x = x.times(d5.plus(sin2_x.times(d16.times(sin2_x).minus(d20)))); - } - - return x; - } - - - // Calculate Taylor series for `cos`, `cosh`, `sin` and `sinh`. - function taylorSeries(Ctor, n, x, y, isHyperbolic) { - var j, t, u, x2, - i = 1, - pr = Ctor.precision, - k = Math.ceil(pr / LOG_BASE); - - external = false; - x2 = x.times(x); - u = new Ctor(y); - - for (;;) { - t = divide(u.times(x2), new Ctor(n++ * n++), pr, 1); - u = isHyperbolic ? y.plus(t) : y.minus(t); - y = divide(t.times(x2), new Ctor(n++ * n++), pr, 1); - t = u.plus(y); - - if (t.d[k] !== void 0) { - for (j = k; t.d[j] === u.d[j] && j--;); - if (j == -1) break; - } - - j = u; - u = y; - y = t; - t = j; - i++; - } - - external = true; - t.d.length = k + 1; - - return t; - } - - - // Return the absolute value of `x` reduced to less than or equal to half pi. - function toLessThanHalfPi(Ctor, x) { - var t, - isNeg = x.s < 0, - pi = getPi(Ctor, Ctor.precision, 1), - halfPi = pi.times(0.5); - - x = x.abs(); - - if (x.lte(halfPi)) { - quadrant = isNeg ? 4 : 1; - return x; - } - - t = x.divToInt(pi); - - if (t.isZero()) { - quadrant = isNeg ? 3 : 2; - } else { - x = x.minus(t.times(pi)); - - // 0 <= x < pi - if (x.lte(halfPi)) { - quadrant = isOdd(t) ? (isNeg ? 2 : 3) : (isNeg ? 4 : 1); - return x; - } - - quadrant = isOdd(t) ? (isNeg ? 1 : 4) : (isNeg ? 3 : 2); - } - - return x.minus(pi).abs(); - } - - - /* - * Return the value of Decimal `x` as a string in base `baseOut`. - * - * If the optional `sd` argument is present include a binary exponent suffix. - */ - function toStringBinary(x, baseOut, sd, rm) { - var base, e, i, k, len, roundUp, str, xd, y, - Ctor = x.constructor, - isExp = sd !== void 0; - - if (isExp) { - checkInt32(sd, 1, MAX_DIGITS); - if (rm === void 0) rm = Ctor.rounding; - else checkInt32(rm, 0, 8); - } else { - sd = Ctor.precision; - rm = Ctor.rounding; - } - - if (!x.isFinite()) { - str = nonFiniteToString(x); - } else { - str = finiteToString(x); - i = str.indexOf('.'); - - // Use exponential notation according to `toExpPos` and `toExpNeg`? No, but if required: - // maxBinaryExponent = floor((decimalExponent + 1) * log[2](10)) - // minBinaryExponent = floor(decimalExponent * log[2](10)) - // log[2](10) = 3.321928094887362347870319429489390175864 - - if (isExp) { - base = 2; - if (baseOut == 16) { - sd = sd * 4 - 3; - } else if (baseOut == 8) { - sd = sd * 3 - 2; - } - } else { - base = baseOut; - } - - // Convert the number as an integer then divide the result by its base raised to a power such - // that the fraction part will be restored. - - // Non-integer. - if (i >= 0) { - str = str.replace('.', ''); - y = new Ctor(1); - y.e = str.length - i; - y.d = convertBase(finiteToString(y), 10, base); - y.e = y.d.length; - } - - xd = convertBase(str, 10, base); - e = len = xd.length; - - // Remove trailing zeros. - for (; xd[--len] == 0;) xd.pop(); - - if (!xd[0]) { - str = isExp ? '0p+0' : '0'; - } else { - if (i < 0) { - e--; - } else { - x = new Ctor(x); - x.d = xd; - x.e = e; - x = divide(x, y, sd, rm, 0, base); - xd = x.d; - e = x.e; - roundUp = inexact; - } - - // The rounding digit, i.e. the digit after the digit that may be rounded up. - i = xd[sd]; - k = base / 2; - roundUp = roundUp || xd[sd + 1] !== void 0; - - roundUp = rm < 4 - ? (i !== void 0 || roundUp) && (rm === 0 || rm === (x.s < 0 ? 3 : 2)) - : i > k || i === k && (rm === 4 || roundUp || rm === 6 && xd[sd - 1] & 1 || - rm === (x.s < 0 ? 8 : 7)); - - xd.length = sd; - - if (roundUp) { - - // Rounding up may mean the previous digit has to be rounded up and so on. - for (; ++xd[--sd] > base - 1;) { - xd[sd] = 0; - if (!sd) { - ++e; - xd.unshift(1); - } - } - } - - // Determine trailing zeros. - for (len = xd.length; !xd[len - 1]; --len); - - // E.g. [4, 11, 15] becomes 4bf. - for (i = 0, str = ''; i < len; i++) str += NUMERALS.charAt(xd[i]); - - // Add binary exponent suffix? - if (isExp) { - if (len > 1) { - if (baseOut == 16 || baseOut == 8) { - i = baseOut == 16 ? 4 : 3; - for (--len; len % i; len++) str += '0'; - xd = convertBase(str, base, baseOut); - for (len = xd.length; !xd[len - 1]; --len); - - // xd[0] will always be be 1 - for (i = 1, str = '1.'; i < len; i++) str += NUMERALS.charAt(xd[i]); - } else { - str = str.charAt(0) + '.' + str.slice(1); - } - } - - str = str + (e < 0 ? 'p' : 'p+') + e; - } else if (e < 0) { - for (; ++e;) str = '0' + str; - str = '0.' + str; - } else { - if (++e > len) for (e -= len; e-- ;) str += '0'; - else if (e < len) str = str.slice(0, e) + '.' + str.slice(e); - } - } - - str = (baseOut == 16 ? '0x' : baseOut == 2 ? '0b' : baseOut == 8 ? '0o' : '') + str; - } - - return x.s < 0 ? '-' + str : str; - } - - - // Does not strip trailing zeros. - function truncate(arr, len) { - if (arr.length > len) { - arr.length = len; - return true; - } - } - - - // Decimal methods - - - /* - * abs - * acos - * acosh - * add - * asin - * asinh - * atan - * atanh - * atan2 - * cbrt - * ceil - * clone - * config - * cos - * cosh - * div - * exp - * floor - * hypot - * ln - * log - * log2 - * log10 - * max - * min - * mod - * mul - * pow - * random - * round - * set - * sign - * sin - * sinh - * sqrt - * sub - * tan - * tanh - * trunc - */ - - - /* - * Return a new Decimal whose value is the absolute value of `x`. - * - * x {number|string|Decimal} - * - */ - function abs(x) { - return new this(x).abs(); - } - - - /* - * Return a new Decimal whose value is the arccosine in radians of `x`. - * - * x {number|string|Decimal} - * - */ - function acos(x) { - return new this(x).acos(); - } - - - /* - * Return a new Decimal whose value is the inverse of the hyperbolic cosine of `x`, rounded to - * `precision` significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function acosh(x) { - return new this(x).acosh(); - } - - - /* - * Return a new Decimal whose value is the sum of `x` and `y`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * y {number|string|Decimal} - * - */ - function add(x, y) { - return new this(x).plus(y); - } - - - /* - * Return a new Decimal whose value is the arcsine in radians of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function asin(x) { - return new this(x).asin(); - } - - - /* - * Return a new Decimal whose value is the inverse of the hyperbolic sine of `x`, rounded to - * `precision` significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function asinh(x) { - return new this(x).asinh(); - } - - - /* - * Return a new Decimal whose value is the arctangent in radians of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function atan(x) { - return new this(x).atan(); - } - - - /* - * Return a new Decimal whose value is the inverse of the hyperbolic tangent of `x`, rounded to - * `precision` significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function atanh(x) { - return new this(x).atanh(); - } - - - /* - * Return a new Decimal whose value is the arctangent in radians of `y/x` in the range -pi to pi - * (inclusive), rounded to `precision` significant digits using rounding mode `rounding`. - * - * Domain: [-Infinity, Infinity] - * Range: [-pi, pi] - * - * y {number|string|Decimal} The y-coordinate. - * x {number|string|Decimal} The x-coordinate. - * - * atan2(±0, -0) = ±pi - * atan2(±0, +0) = ±0 - * atan2(±0, -x) = ±pi for x > 0 - * atan2(±0, x) = ±0 for x > 0 - * atan2(-y, ±0) = -pi/2 for y > 0 - * atan2(y, ±0) = pi/2 for y > 0 - * atan2(±y, -Infinity) = ±pi for finite y > 0 - * atan2(±y, +Infinity) = ±0 for finite y > 0 - * atan2(±Infinity, x) = ±pi/2 for finite x - * atan2(±Infinity, -Infinity) = ±3*pi/4 - * atan2(±Infinity, +Infinity) = ±pi/4 - * atan2(NaN, x) = NaN - * atan2(y, NaN) = NaN - * - */ - function atan2(y, x) { - y = new this(y); - x = new this(x); - var r, - pr = this.precision, - rm = this.rounding, - wpr = pr + 4; - - // Either NaN - if (!y.s || !x.s) { - r = new this(NaN); - - // Both ±Infinity - } else if (!y.d && !x.d) { - r = getPi(this, wpr, 1).times(x.s > 0 ? 0.25 : 0.75); - r.s = y.s; - - // x is ±Infinity or y is ±0 - } else if (!x.d || y.isZero()) { - r = x.s < 0 ? getPi(this, pr, rm) : new this(0); - r.s = y.s; - - // y is ±Infinity or x is ±0 - } else if (!y.d || x.isZero()) { - r = getPi(this, wpr, 1).times(0.5); - r.s = y.s; - - // Both non-zero and finite - } else if (x.s < 0) { - this.precision = wpr; - this.rounding = 1; - r = this.atan(divide(y, x, wpr, 1)); - x = getPi(this, wpr, 1); - this.precision = pr; - this.rounding = rm; - r = y.s < 0 ? r.minus(x) : r.plus(x); - } else { - r = this.atan(divide(y, x, wpr, 1)); - } - - return r; - } - - - /* - * Return a new Decimal whose value is the cube root of `x`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function cbrt(x) { - return new this(x).cbrt(); - } - - - /* - * Return a new Decimal whose value is `x` rounded to an integer using `ROUND_CEIL`. - * - * x {number|string|Decimal} - * - */ - function ceil(x) { - return finalise(x = new this(x), x.e + 1, 2); - } - - - /* - * Configure global settings for a Decimal constructor. - * - * `obj` is an object with one or more of the following properties, - * - * precision {number} - * rounding {number} - * toExpNeg {number} - * toExpPos {number} - * maxE {number} - * minE {number} - * modulo {number} - * crypto {boolean|number} - * - * E.g. Decimal.config({ precision: 20, rounding: 4 }) - * - */ - function config(obj) { - if (!obj || typeof obj !== 'object') throw Error(decimalError + 'Object expected'); - var i, p, v, - ps = [ - 'precision', 1, MAX_DIGITS, - 'rounding', 0, 8, - 'toExpNeg', -EXP_LIMIT, 0, - 'toExpPos', 0, EXP_LIMIT, - 'maxE', 0, EXP_LIMIT, - 'minE', -EXP_LIMIT, 0, - 'modulo', 0, 9 - ]; - - for (i = 0; i < ps.length; i += 3) { - if ((v = obj[p = ps[i]]) !== void 0) { - if (mathfloor(v) === v && v >= ps[i + 1] && v <= ps[i + 2]) this[p] = v; - else throw Error(invalidArgument + p + ': ' + v); - } - } - - if ((v = obj[p = 'crypto']) !== void 0) { - if (v === true || v === false || v === 0 || v === 1) { - if (v) { - if (typeof crypto != 'undefined' && crypto && - (crypto.getRandomValues || crypto.randomBytes)) { - this[p] = true; - } else { - throw Error(cryptoUnavailable); - } - } else { - this[p] = false; - } - } else { - throw Error(invalidArgument + p + ': ' + v); - } - } - - return this; - } - - - /* - * Return a new Decimal whose value is the cosine of `x`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function cos(x) { - return new this(x).cos(); - } - - - /* - * Return a new Decimal whose value is the hyperbolic cosine of `x`, rounded to precision - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function cosh(x) { - return new this(x).cosh(); - } - - - /* - * Create and return a Decimal constructor with the same configuration properties as this Decimal - * constructor. - * - */ - function clone(obj) { - var i, p, ps; - - /* - * The Decimal constructor and exported function. - * Return a new Decimal instance. - * - * v {number|string|Decimal} A numeric value. - * - */ - function Decimal(v) { - var e, i, t, - x = this; - - // Decimal called without new. - if (!(x instanceof Decimal)) return new Decimal(v); - - // Retain a reference to this Decimal constructor, and shadow Decimal.prototype.constructor - // which points to Object. - x.constructor = Decimal; - - // Duplicate. - if (v instanceof Decimal) { - x.s = v.s; - x.e = v.e; - x.d = (v = v.d) ? v.slice() : v; - return; - } - - t = typeof v; - - if (t === 'number') { - if (v === 0) { - x.s = 1 / v < 0 ? -1 : 1; - x.e = 0; - x.d = [0]; - return; - } - - if (v < 0) { - v = -v; - x.s = -1; - } else { - x.s = 1; - } - - // Fast path for small integers. - if (v === ~~v && v < 1e7) { - for (e = 0, i = v; i >= 10; i /= 10) e++; - x.e = e; - x.d = [v]; - return; - - // Infinity, NaN. - } else if (v * 0 !== 0) { - if (!v) x.s = NaN; - x.e = NaN; - x.d = null; - return; - } - - return parseDecimal(x, v.toString()); - - } else if (t !== 'string') { - throw Error(invalidArgument + v); - } - - // Minus sign? - if (v.charCodeAt(0) === 45) { - v = v.slice(1); - x.s = -1; - } else { - x.s = 1; - } - - return isDecimal.test(v) ? parseDecimal(x, v) : parseOther(x, v); - } - - Decimal.prototype = P; - - Decimal.ROUND_UP = 0; - Decimal.ROUND_DOWN = 1; - Decimal.ROUND_CEIL = 2; - Decimal.ROUND_FLOOR = 3; - Decimal.ROUND_HALF_UP = 4; - Decimal.ROUND_HALF_DOWN = 5; - Decimal.ROUND_HALF_EVEN = 6; - Decimal.ROUND_HALF_CEIL = 7; - Decimal.ROUND_HALF_FLOOR = 8; - Decimal.EUCLID = 9; - - Decimal.config = Decimal.set = config; - Decimal.clone = clone; - - Decimal.abs = abs; - Decimal.acos = acos; - Decimal.acosh = acosh; // ES6 - Decimal.add = add; - Decimal.asin = asin; - Decimal.asinh = asinh; // ES6 - Decimal.atan = atan; - Decimal.atanh = atanh; // ES6 - Decimal.atan2 = atan2; - Decimal.cbrt = cbrt; // ES6 - Decimal.ceil = ceil; - Decimal.cos = cos; - Decimal.cosh = cosh; // ES6 - Decimal.div = div; - Decimal.exp = exp; - Decimal.floor = floor; - Decimal.hypot = hypot; // ES6 - Decimal.ln = ln; - Decimal.log = log; - Decimal.log10 = log10; // ES6 - Decimal.log2 = log2; // ES6 - Decimal.max = max; - Decimal.min = min; - Decimal.mod = mod; - Decimal.mul = mul; - Decimal.pow = pow; - Decimal.random = random; - Decimal.round = round; - Decimal.sign = sign; // ES6 - Decimal.sin = sin; - Decimal.sinh = sinh; // ES6 - Decimal.sqrt = sqrt; - Decimal.sub = sub; - Decimal.tan = tan; - Decimal.tanh = tanh; // ES6 - Decimal.trunc = trunc; // ES6 - - if (obj === void 0) obj = {}; - if (obj) { - ps = ['precision', 'rounding', 'toExpNeg', 'toExpPos', 'maxE', 'minE', 'modulo', 'crypto']; - for (i = 0; i < ps.length;) if (!obj.hasOwnProperty(p = ps[i++])) obj[p] = this[p]; - } - - Decimal.config(obj); - - return Decimal; - } - - - /* - * Return a new Decimal whose value is `x` divided by `y`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * y {number|string|Decimal} - * - */ - function div(x, y) { - return new this(x).div(y); - } - - - /* - * Return a new Decimal whose value is the natural exponential of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} The power to which to raise the base of the natural log. - * - */ - function exp(x) { - return new this(x).exp(); - } - - - /* - * Return a new Decimal whose value is `x` round to an integer using `ROUND_FLOOR`. - * - * x {number|string|Decimal} - * - */ - function floor(x) { - return finalise(x = new this(x), x.e + 1, 3); - } - - - /* - * Return a new Decimal whose value is the square root of the sum of the squares of the arguments, - * rounded to `precision` significant digits using rounding mode `rounding`. - * - * hypot(a, b, ...) = sqrt(a^2 + b^2 + ...) - * - */ - function hypot() { - var i, n, - t = new this(0); - - external = false; - - for (i = 0; i < arguments.length;) { - n = new this(arguments[i++]); - if (!n.d) { - if (n.s) { - external = true; - return new this(1 / 0); - } - t = n; - } else if (t.d) { - t = t.plus(n.times(n)); - } - } - - external = true; - - return t.sqrt(); - } - - - /* - * Return a new Decimal whose value is the natural logarithm of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function ln(x) { - return new this(x).ln(); - } - - - /* - * Return a new Decimal whose value is the log of `x` to the base `y`, or to base 10 if no base - * is specified, rounded to `precision` significant digits using rounding mode `rounding`. - * - * log[y](x) - * - * x {number|string|Decimal} The argument of the logarithm. - * y {number|string|Decimal} The base of the logarithm. - * - */ - function log(x, y) { - return new this(x).log(y); - } - - - /* - * Return a new Decimal whose value is the base 2 logarithm of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function log2(x) { - return new this(x).log(2); - } - - - /* - * Return a new Decimal whose value is the base 10 logarithm of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function log10(x) { - return new this(x).log(10); - } - - - /* - * Return a new Decimal whose value is the maximum of the arguments. - * - * arguments {number|string|Decimal} - * - */ - function max() { - return maxOrMin(this, arguments, 'lt'); - } - - - /* - * Return a new Decimal whose value is the minimum of the arguments. - * - * arguments {number|string|Decimal} - * - */ - function min() { - return maxOrMin(this, arguments, 'gt'); - } - - - /* - * Return a new Decimal whose value is `x` modulo `y`, rounded to `precision` significant digits - * using rounding mode `rounding`. - * - * x {number|string|Decimal} - * y {number|string|Decimal} - * - */ - function mod(x, y) { - return new this(x).mod(y); - } - - - /* - * Return a new Decimal whose value is `x` multiplied by `y`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * y {number|string|Decimal} - * - */ - function mul(x, y) { - return new this(x).mul(y); - } - - - /* - * Return a new Decimal whose value is `x` raised to the power `y`, rounded to precision - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} The base. - * y {number|string|Decimal} The exponent. - * - */ - function pow(x, y) { - return new this(x).pow(y); - } - - - /* - * Returns a new Decimal with a random value equal to or greater than 0 and less than 1, and with - * `sd`, or `Decimal.precision` if `sd` is omitted, significant digits (or less if trailing zeros - * are produced). - * - * [sd] {number} Significant digits. Integer, 0 to MAX_DIGITS inclusive. - * - */ - function random(sd) { - var d, e, k, n, - i = 0, - r = new this(1), - rd = []; - - if (sd === void 0) sd = this.precision; - else checkInt32(sd, 1, MAX_DIGITS); - - k = Math.ceil(sd / LOG_BASE); - - if (!this.crypto) { - for (; i < k;) rd[i++] = Math.random() * 1e7 | 0; - - // Browsers supporting crypto.getRandomValues. - } else if (crypto.getRandomValues) { - d = crypto.getRandomValues(new Uint32Array(k)); - - for (; i < k;) { - n = d[i]; - - // 0 <= n < 4294967296 - // Probability n >= 4.29e9, is 4967296 / 4294967296 = 0.00116 (1 in 865). - if (n >= 4.29e9) { - d[i] = crypto.getRandomValues(new Uint32Array(1))[0]; - } else { - - // 0 <= n <= 4289999999 - // 0 <= (n % 1e7) <= 9999999 - rd[i++] = n % 1e7; - } - } - - // Node.js supporting crypto.randomBytes. - } else if (crypto.randomBytes) { - - // buffer - d = crypto.randomBytes(k *= 4); - - for (; i < k;) { - - // 0 <= n < 2147483648 - n = d[i] + (d[i + 1] << 8) + (d[i + 2] << 16) + ((d[i + 3] & 0x7f) << 24); - - // Probability n >= 2.14e9, is 7483648 / 2147483648 = 0.0035 (1 in 286). - if (n >= 2.14e9) { - crypto.randomBytes(4).copy(d, i); - } else { - - // 0 <= n <= 2139999999 - // 0 <= (n % 1e7) <= 9999999 - rd.push(n % 1e7); - i += 4; - } - } - - i = k / 4; - } else { - throw Error(cryptoUnavailable); - } - - k = rd[--i]; - sd %= LOG_BASE; - - // Convert trailing digits to zeros according to sd. - if (k && sd) { - n = mathpow(10, LOG_BASE - sd); - rd[i] = (k / n | 0) * n; - } - - // Remove trailing words which are zero. - for (; rd[i] === 0; i--) rd.pop(); - - // Zero? - if (i < 0) { - e = 0; - rd = [0]; - } else { - e = -1; - - // Remove leading words which are zero and adjust exponent accordingly. - for (; rd[0] === 0; e -= LOG_BASE) rd.shift(); - - // Count the digits of the first word of rd to determine leading zeros. - for (k = 1, n = rd[0]; n >= 10; n /= 10) k++; - - // Adjust the exponent for leading zeros of the first word of rd. - if (k < LOG_BASE) e -= LOG_BASE - k; - } - - r.e = e; - r.d = rd; - - return r; - } - - - /* - * Return a new Decimal whose value is `x` rounded to an integer using rounding mode `rounding`. - * - * To emulate `Math.round`, set rounding to 7 (ROUND_HALF_CEIL). - * - * x {number|string|Decimal} - * - */ - function round(x) { - return finalise(x = new this(x), x.e + 1, this.rounding); - } - - - /* - * Return - * 1 if x > 0, - * -1 if x < 0, - * 0 if x is 0, - * -0 if x is -0, - * NaN otherwise - * - */ - function sign(x) { - x = new this(x); - return x.d ? (x.d[0] ? x.s : 0 * x.s) : x.s || NaN; - } - - - /* - * Return a new Decimal whose value is the sine of `x`, rounded to `precision` significant digits - * using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function sin(x) { - return new this(x).sin(); - } - - - /* - * Return a new Decimal whose value is the hyperbolic sine of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function sinh(x) { - return new this(x).sinh(); - } - - - /* - * Return a new Decimal whose value is the square root of `x`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} - * - */ - function sqrt(x) { - return new this(x).sqrt(); - } - - - /* - * Return a new Decimal whose value is `x` minus `y`, rounded to `precision` significant digits - * using rounding mode `rounding`. - * - * x {number|string|Decimal} - * y {number|string|Decimal} - * - */ - function sub(x, y) { - return new this(x).sub(y); - } - - - /* - * Return a new Decimal whose value is the tangent of `x`, rounded to `precision` significant - * digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function tan(x) { - return new this(x).tan(); - } - - - /* - * Return a new Decimal whose value is the hyperbolic tangent of `x`, rounded to `precision` - * significant digits using rounding mode `rounding`. - * - * x {number|string|Decimal} A value in radians. - * - */ - function tanh(x) { - return new this(x).tanh(); - } - - - /* - * Return a new Decimal whose value is `x` truncated to an integer. - * - * x {number|string|Decimal} - * - */ - function trunc(x) { - return finalise(x = new this(x), x.e + 1, 1); - } - - - // Create and configure initial Decimal constructor. - Decimal = clone(Decimal); - - // Create the internal constants from their string values. - LN10 = new Decimal(LN10); - PI = new Decimal(PI); - - - // Export. - - - // AMD. - if (typeof define == 'function' && define.amd) { - define(function () { - return Decimal; - }); - - // Node and other environments that support module.exports. - } else if (typeof module != 'undefined' && module.exports) { - module.exports = Decimal['default'] = Decimal.Decimal = Decimal; - - // Browser. - } else { - if (!globalScope) { - globalScope = typeof self != 'undefined' && self && self.self == self - ? self : Function('return this')(); - } - - noConflict = globalScope.Decimal; - Decimal.noConflict = function () { - globalScope.Decimal = noConflict; - return Decimal; - }; - - globalScope.Decimal = Decimal; - } -})(this);