1 | /*! decimal.js v9.0.1 https://github.com/MikeMcl/decimal.js/LICENCE */ |
2 | ;(function (globalScope) { |
3 | 'use strict'; |
4 | |
5 | |
6 | /* |
7 | * decimal.js v9.0.1 |
8 | * An arbitrary-precision Decimal type for JavaScript. |
9 | * https://github.com/MikeMcl/decimal.js |
10 | * Copyright (c) 2017 Michael Mclaughlin <M8ch88l@gmail.com> |
11 | * MIT Licence |
12 | */ |
13 | |
14 | |
15 | // ----------------------------------- EDITABLE DEFAULTS ------------------------------------ // |
16 | |
17 | |
18 | // The maximum exponent magnitude. |
19 | // The limit on the value of `toExpNeg`, `toExpPos`, `minE` and `maxE`. |
20 | var EXP_LIMIT = 9e15, // 0 to 9e15 |
21 | |
22 | // The limit on the value of `precision`, and on the value of the first argument to |
23 | // `toDecimalPlaces`, `toExponential`, `toFixed`, `toPrecision` and `toSignificantDigits`. |
24 | MAX_DIGITS = 1e9, // 0 to 1e9 |
25 | |
26 | // Base conversion alphabet. |
27 | NUMERALS = '0123456789abcdef', |
28 | |
29 | // The natural logarithm of 10 (1025 digits). |
30 | LN10 = '2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840422862486334095254650828067566662873690987816894829072083255546808437998948262331985283935053089653777326288461633662222876982198867465436674744042432743651550489343149393914796194044002221051017141748003688084012647080685567743216228355220114804663715659121373450747856947683463616792101806445070648000277502684916746550586856935673420670581136429224554405758925724208241314695689016758940256776311356919292033376587141660230105703089634572075440370847469940168269282808481184289314848524948644871927809676271275775397027668605952496716674183485704422507197965004714951050492214776567636938662976979522110718264549734772662425709429322582798502585509785265383207606726317164309505995087807523710333101197857547331541421808427543863591778117054309827482385045648019095610299291824318237525357709750539565187697510374970888692180205189339507238539205144634197265287286965110862571492198849978748873771345686209167058', |
31 | |
32 | // Pi (1025 digits). |
33 | PI = '3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632789', |
34 | |
35 | |
36 | // The initial configuration properties of the Decimal constructor. |
37 | DEFAULTS = { |
38 | |
39 | // These values must be integers within the stated ranges (inclusive). |
40 | // Most of these values can be changed at run-time using the `Decimal.config` method. |
41 | |
42 | // The maximum number of significant digits of the result of a calculation or base conversion. |
43 | // E.g. `Decimal.config({ precision: 20 });` |
44 | precision: 20, // 1 to MAX_DIGITS |
45 | |
46 | // The rounding mode used when rounding to `precision`. |
47 | // |
48 | // ROUND_UP 0 Away from zero. |
49 | // ROUND_DOWN 1 Towards zero. |
50 | // ROUND_CEIL 2 Towards +Infinity. |
51 | // ROUND_FLOOR 3 Towards -Infinity. |
52 | // ROUND_HALF_UP 4 Towards nearest neighbour. If equidistant, up. |
53 | // ROUND_HALF_DOWN 5 Towards nearest neighbour. If equidistant, down. |
54 | // ROUND_HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour. |
55 | // ROUND_HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity. |
56 | // ROUND_HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity. |
57 | // |
58 | // E.g. |
59 | // `Decimal.rounding = 4;` |
60 | // `Decimal.rounding = Decimal.ROUND_HALF_UP;` |
61 | rounding: 4, // 0 to 8 |
62 | |
63 | // The modulo mode used when calculating the modulus: a mod n. |
64 | // The quotient (q = a / n) is calculated according to the corresponding rounding mode. |
65 | // The remainder (r) is calculated as: r = a - n * q. |
66 | // |
67 | // UP 0 The remainder is positive if the dividend is negative, else is negative. |
68 | // DOWN 1 The remainder has the same sign as the dividend (JavaScript %). |
69 | // FLOOR 3 The remainder has the same sign as the divisor (Python %). |
70 | // HALF_EVEN 6 The IEEE 754 remainder function. |
71 | // EUCLID 9 Euclidian division. q = sign(n) * floor(a / abs(n)). Always positive. |
72 | // |
73 | // Truncated division (1), floored division (3), the IEEE 754 remainder (6), and Euclidian |
74 | // division (9) are commonly used for the modulus operation. The other rounding modes can also |
75 | // be used, but they may not give useful results. |
76 | modulo: 1, // 0 to 9 |
77 | |
78 | // The exponent value at and beneath which `toString` returns exponential notation. |
79 | // JavaScript numbers: -7 |
80 | toExpNeg: -7, // 0 to -EXP_LIMIT |
81 | |
82 | // The exponent value at and above which `toString` returns exponential notation. |
83 | // JavaScript numbers: 21 |
84 | toExpPos: 21, // 0 to EXP_LIMIT |
85 | |
86 | // The minimum exponent value, beneath which underflow to zero occurs. |
87 | // JavaScript numbers: -324 (5e-324) |
88 | minE: -EXP_LIMIT, // -1 to -EXP_LIMIT |
89 | |
90 | // The maximum exponent value, above which overflow to Infinity occurs. |
91 | // JavaScript numbers: 308 (1.7976931348623157e+308) |
92 | maxE: EXP_LIMIT, // 1 to EXP_LIMIT |
93 | |
94 | // Whether to use cryptographically-secure random number generation, if available. |
95 | crypto: false // true/false |
96 | }, |
97 | |
98 | |
99 | // ----------------------------------- END OF EDITABLE DEFAULTS ------------------------------- // |
100 | |
101 | |
102 | Decimal, inexact, noConflict, quadrant, |
103 | external = true, |
104 | |
105 | decimalError = '[DecimalError] ', |
106 | invalidArgument = decimalError + 'Invalid argument: ', |
107 | precisionLimitExceeded = decimalError + 'Precision limit exceeded', |
108 | cryptoUnavailable = decimalError + 'crypto unavailable', |
109 | |
110 | mathfloor = Math.floor, |
111 | mathpow = Math.pow, |
112 | |
113 | isBinary = /^0b([01]+(\.[01]*)?|\.[01]+)(p[+-]?\d+)?$/i, |
114 | isHex = /^0x([0-9a-f]+(\.[0-9a-f]*)?|\.[0-9a-f]+)(p[+-]?\d+)?$/i, |
115 | isOctal = /^0o([0-7]+(\.[0-7]*)?|\.[0-7]+)(p[+-]?\d+)?$/i, |
116 | isDecimal = /^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i, |
117 | |
118 | BASE = 1e7, |
119 | LOG_BASE = 7, |
120 | MAX_SAFE_INTEGER = 9007199254740991, |
121 | |
122 | LN10_PRECISION = LN10.length - 1, |
123 | PI_PRECISION = PI.length - 1, |
124 | |
125 | // Decimal.prototype object |
126 | P = { name: '[object Decimal]' }; |
127 | |
128 | |
129 | // Decimal prototype methods |
130 | |
131 | |
132 | /* |
133 | * absoluteValue abs |
134 | * ceil |
135 | * comparedTo cmp |
136 | * cosine cos |
137 | * cubeRoot cbrt |
138 | * decimalPlaces dp |
139 | * dividedBy div |
140 | * dividedToIntegerBy divToInt |
141 | * equals eq |
142 | * floor |
143 | * greaterThan gt |
144 | * greaterThanOrEqualTo gte |
145 | * hyperbolicCosine cosh |
146 | * hyperbolicSine sinh |
147 | * hyperbolicTangent tanh |
148 | * inverseCosine acos |
149 | * inverseHyperbolicCosine acosh |
150 | * inverseHyperbolicSine asinh |
151 | * inverseHyperbolicTangent atanh |
152 | * inverseSine asin |
153 | * inverseTangent atan |
154 | * isFinite |
155 | * isInteger isInt |
156 | * isNaN |
157 | * isNegative isNeg |
158 | * isPositive isPos |
159 | * isZero |
160 | * lessThan lt |
161 | * lessThanOrEqualTo lte |
162 | * logarithm log |
163 | * [maximum] [max] |
164 | * [minimum] [min] |
165 | * minus sub |
166 | * modulo mod |
167 | * naturalExponential exp |
168 | * naturalLogarithm ln |
169 | * negated neg |
170 | * plus add |
171 | * precision sd |
172 | * round |
173 | * sine sin |
174 | * squareRoot sqrt |
175 | * tangent tan |
176 | * times mul |
177 | * toBinary |
178 | * toDecimalPlaces toDP |
179 | * toExponential |
180 | * toFixed |
181 | * toFraction |
182 | * toHexadecimal toHex |
183 | * toNearest |
184 | * toNumber |
185 | * toOctal |
186 | * toPower pow |
187 | * toPrecision |
188 | * toSignificantDigits toSD |
189 | * toString |
190 | * truncated trunc |
191 | * valueOf toJSON |
192 | */ |
193 | |
194 | |
195 | /* |
196 | * Return a new Decimal whose value is the absolute value of this Decimal. |
197 | * |
198 | */ |
199 | P.absoluteValue = P.abs = function () { |
200 | var x = new this.constructor(this); |
201 | if (x.s < 0) x.s = 1; |
202 | return finalise(x); |
203 | }; |
204 | |
205 | |
206 | /* |
207 | * Return a new Decimal whose value is the value of this Decimal rounded to a whole number in the |
208 | * direction of positive Infinity. |
209 | * |
210 | */ |
211 | P.ceil = function () { |
212 | return finalise(new this.constructor(this), this.e + 1, 2); |
213 | }; |
214 | |
215 | |
216 | /* |
217 | * Return |
218 | * 1 if the value of this Decimal is greater than the value of `y`, |
219 | * -1 if the value of this Decimal is less than the value of `y`, |
220 | * 0 if they have the same value, |
221 | * NaN if the value of either Decimal is NaN. |
222 | * |
223 | */ |
224 | P.comparedTo = P.cmp = function (y) { |
225 | var i, j, xdL, ydL, |
226 | x = this, |
227 | xd = x.d, |
228 | yd = (y = new x.constructor(y)).d, |
229 | xs = x.s, |
230 | ys = y.s; |
231 | |
232 | // Either NaN or ±Infinity? |
233 | if (!xd || !yd) { |
234 | return !xs || !ys ? NaN : xs !== ys ? xs : xd === yd ? 0 : !xd ^ xs < 0 ? 1 : -1; |
235 | } |
236 | |
237 | // Either zero? |
238 | if (!xd[0] || !yd[0]) return xd[0] ? xs : yd[0] ? -ys : 0; |
239 | |
240 | // Signs differ? |
241 | if (xs !== ys) return xs; |
242 | |
243 | // Compare exponents. |
244 | if (x.e !== y.e) return x.e > y.e ^ xs < 0 ? 1 : -1; |
245 | |
246 | xdL = xd.length; |
247 | ydL = yd.length; |
248 | |
249 | // Compare digit by digit. |
250 | for (i = 0, j = xdL < ydL ? xdL : ydL; i < j; ++i) { |
251 | if (xd[i] !== yd[i]) return xd[i] > yd[i] ^ xs < 0 ? 1 : -1; |
252 | } |
253 | |
254 | // Compare lengths. |
255 | return xdL === ydL ? 0 : xdL > ydL ^ xs < 0 ? 1 : -1; |
256 | }; |
257 | |
258 | |
259 | /* |
260 | * Return a new Decimal whose value is the cosine of the value in radians of this Decimal. |
261 | * |
262 | * Domain: [-Infinity, Infinity] |
263 | * Range: [-1, 1] |
264 | * |
265 | * cos(0) = 1 |
266 | * cos(-0) = 1 |
267 | * cos(Infinity) = NaN |
268 | * cos(-Infinity) = NaN |
269 | * cos(NaN) = NaN |
270 | * |
271 | */ |
272 | P.cosine = P.cos = function () { |
273 | var pr, rm, |
274 | x = this, |
275 | Ctor = x.constructor; |
276 | |
277 | if (!x.d) return new Ctor(NaN); |
278 | |
279 | // cos(0) = cos(-0) = 1 |
280 | if (!x.d[0]) return new Ctor(1); |
281 | |
282 | pr = Ctor.precision; |
283 | rm = Ctor.rounding; |
284 | Ctor.precision = pr + Math.max(x.e, x.sd()) + LOG_BASE; |
285 | Ctor.rounding = 1; |
286 | |
287 | x = cosine(Ctor, toLessThanHalfPi(Ctor, x)); |
288 | |
289 | Ctor.precision = pr; |
290 | Ctor.rounding = rm; |
291 | |
292 | return finalise(quadrant == 2 || quadrant == 3 ? x.neg() : x, pr, rm, true); |
293 | }; |
294 | |
295 | |
296 | /* |
297 | * |
298 | * Return a new Decimal whose value is the cube root of the value of this Decimal, rounded to |
299 | * `precision` significant digits using rounding mode `rounding`. |
300 | * |
301 | * cbrt(0) = 0 |
302 | * cbrt(-0) = -0 |
303 | * cbrt(1) = 1 |
304 | * cbrt(-1) = -1 |
305 | * cbrt(N) = N |
306 | * cbrt(-I) = -I |
307 | * cbrt(I) = I |
308 | * |
309 | * Math.cbrt(x) = (x < 0 ? -Math.pow(-x, 1/3) : Math.pow(x, 1/3)) |
310 | * |
311 | */ |
312 | P.cubeRoot = P.cbrt = function () { |
313 | var e, m, n, r, rep, s, sd, t, t3, t3plusx, |
314 | x = this, |
315 | Ctor = x.constructor; |
316 | |
317 | if (!x.isFinite() || x.isZero()) return new Ctor(x); |
318 | external = false; |
319 | |
320 | // Initial estimate. |
321 | s = x.s * Math.pow(x.s * x, 1 / 3); |
322 | |
323 | // Math.cbrt underflow/overflow? |
324 | // Pass x to Math.pow as integer, then adjust the exponent of the result. |
325 | if (!s || Math.abs(s) == 1 / 0) { |
326 | n = digitsToString(x.d); |
327 | e = x.e; |
328 | |
329 | // Adjust n exponent so it is a multiple of 3 away from x exponent. |
330 | if (s = (e - n.length + 1) % 3) n += (s == 1 || s == -2 ? '0' : '00'); |
331 | s = Math.pow(n, 1 / 3); |
332 | |
333 | // Rarely, e may be one less than the result exponent value. |
334 | e = mathfloor((e + 1) / 3) - (e % 3 == (e < 0 ? -1 : 2)); |
335 | |
336 | if (s == 1 / 0) { |
337 | n = '5e' + e; |
338 | } else { |
339 | n = s.toExponential(); |
340 | n = n.slice(0, n.indexOf('e') + 1) + e; |
341 | } |
342 | |
343 | r = new Ctor(n); |
344 | r.s = x.s; |
345 | } else { |
346 | r = new Ctor(s.toString()); |
347 | } |
348 | |
349 | sd = (e = Ctor.precision) + 3; |
350 | |
351 | // Halley's method. |
352 | // TODO? Compare Newton's method. |
353 | for (;;) { |
354 | t = r; |
355 | t3 = t.times(t).times(t); |
356 | t3plusx = t3.plus(x); |
357 | r = divide(t3plusx.plus(x).times(t), t3plusx.plus(t3), sd + 2, 1); |
358 | |
359 | // TODO? Replace with for-loop and checkRoundingDigits. |
360 | if (digitsToString(t.d).slice(0, sd) === (n = digitsToString(r.d)).slice(0, sd)) { |
361 | n = n.slice(sd - 3, sd + 1); |
362 | |
363 | // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or 4999 |
364 | // , i.e. approaching a rounding boundary, continue the iteration. |
365 | if (n == '9999' || !rep && n == '4999') { |
366 | |
367 | // On the first iteration only, check to see if rounding up gives the exact result as the |
368 | // nines may infinitely repeat. |
369 | if (!rep) { |
370 | finalise(t, e + 1, 0); |
371 | |
372 | if (t.times(t).times(t).eq(x)) { |
373 | r = t; |
374 | break; |
375 | } |
376 | } |
377 | |
378 | sd += 4; |
379 | rep = 1; |
380 | } else { |
381 | |
382 | // If the rounding digits are null, 0{0,4} or 50{0,3}, check for an exact result. |
383 | // If not, then there are further digits and m will be truthy. |
384 | if (!+n || !+n.slice(1) && n.charAt(0) == '5') { |
385 | |
386 | // Truncate to the first rounding digit. |
387 | finalise(r, e + 1, 1); |
388 | m = !r.times(r).times(r).eq(x); |
389 | } |
390 | |
391 | break; |
392 | } |
393 | } |
394 | } |
395 | |
396 | external = true; |
397 | |
398 | return finalise(r, e, Ctor.rounding, m); |
399 | }; |
400 | |
401 | |
402 | /* |
403 | * Return the number of decimal places of the value of this Decimal. |
404 | * |
405 | */ |
406 | P.decimalPlaces = P.dp = function () { |
407 | var w, |
408 | d = this.d, |
409 | n = NaN; |
410 | |
411 | if (d) { |
412 | w = d.length - 1; |
413 | n = (w - mathfloor(this.e / LOG_BASE)) * LOG_BASE; |
414 | |
415 | // Subtract the number of trailing zeros of the last word. |
416 | w = d[w]; |
417 | if (w) for (; w % 10 == 0; w /= 10) n--; |
418 | if (n < 0) n = 0; |
419 | } |
420 | |
421 | return n; |
422 | }; |
423 | |
424 | |
425 | /* |
426 | * n / 0 = I |
427 | * n / N = N |
428 | * n / I = 0 |
429 | * 0 / n = 0 |
430 | * 0 / 0 = N |
431 | * 0 / N = N |
432 | * 0 / I = 0 |
433 | * N / n = N |
434 | * N / 0 = N |
435 | * N / N = N |
436 | * N / I = N |
437 | * I / n = I |
438 | * I / 0 = I |
439 | * I / N = N |
440 | * I / I = N |
441 | * |
442 | * Return a new Decimal whose value is the value of this Decimal divided by `y`, rounded to |
443 | * `precision` significant digits using rounding mode `rounding`. |
444 | * |
445 | */ |
446 | P.dividedBy = P.div = function (y) { |
447 | return divide(this, new this.constructor(y)); |
448 | }; |
449 | |
450 | |
451 | /* |
452 | * Return a new Decimal whose value is the integer part of dividing the value of this Decimal |
453 | * by the value of `y`, rounded to `precision` significant digits using rounding mode `rounding`. |
454 | * |
455 | */ |
456 | P.dividedToIntegerBy = P.divToInt = function (y) { |
457 | var x = this, |
458 | Ctor = x.constructor; |
459 | return finalise(divide(x, new Ctor(y), 0, 1, 1), Ctor.precision, Ctor.rounding); |
460 | }; |
461 | |
462 | |
463 | /* |
464 | * Return true if the value of this Decimal is equal to the value of `y`, otherwise return false. |
465 | * |
466 | */ |
467 | P.equals = P.eq = function (y) { |
468 | return this.cmp(y) === 0; |
469 | }; |
470 | |
471 | |
472 | /* |
473 | * Return a new Decimal whose value is the value of this Decimal rounded to a whole number in the |
474 | * direction of negative Infinity. |
475 | * |
476 | */ |
477 | P.floor = function () { |
478 | return finalise(new this.constructor(this), this.e + 1, 3); |
479 | }; |
480 | |
481 | |
482 | /* |
483 | * Return true if the value of this Decimal is greater than the value of `y`, otherwise return |
484 | * false. |
485 | * |
486 | */ |
487 | P.greaterThan = P.gt = function (y) { |
488 | return this.cmp(y) > 0; |
489 | }; |
490 | |
491 | |
492 | /* |
493 | * Return true if the value of this Decimal is greater than or equal to the value of `y`, |
494 | * otherwise return false. |
495 | * |
496 | */ |
497 | P.greaterThanOrEqualTo = P.gte = function (y) { |
498 | var k = this.cmp(y); |
499 | return k == 1 || k === 0; |
500 | }; |
501 | |
502 | |
503 | /* |
504 | * Return a new Decimal whose value is the hyperbolic cosine of the value in radians of this |
505 | * Decimal. |
506 | * |
507 | * Domain: [-Infinity, Infinity] |
508 | * Range: [1, Infinity] |
509 | * |
510 | * cosh(x) = 1 + x^2/2! + x^4/4! + x^6/6! + ... |
511 | * |
512 | * cosh(0) = 1 |
513 | * cosh(-0) = 1 |
514 | * cosh(Infinity) = Infinity |
515 | * cosh(-Infinity) = Infinity |
516 | * cosh(NaN) = NaN |
517 | * |
518 | * x time taken (ms) result |
519 | * 1000 9 9.8503555700852349694e+433 |
520 | * 10000 25 4.4034091128314607936e+4342 |
521 | * 100000 171 1.4033316802130615897e+43429 |
522 | * 1000000 3817 1.5166076984010437725e+434294 |
523 | * 10000000 abandoned after 2 minute wait |
524 | * |
525 | * TODO? Compare performance of cosh(x) = 0.5 * (exp(x) + exp(-x)) |
526 | * |
527 | */ |
528 | P.hyperbolicCosine = P.cosh = function () { |
529 | var k, n, pr, rm, len, |
530 | x = this, |
531 | Ctor = x.constructor, |
532 | one = new Ctor(1); |
533 | |
534 | if (!x.isFinite()) return new Ctor(x.s ? 1 / 0 : NaN); |
535 | if (x.isZero()) return one; |
536 | |
537 | pr = Ctor.precision; |
538 | rm = Ctor.rounding; |
539 | Ctor.precision = pr + Math.max(x.e, x.sd()) + 4; |
540 | Ctor.rounding = 1; |
541 | len = x.d.length; |
542 | |
543 | // Argument reduction: cos(4x) = 1 - 8cos^2(x) + 8cos^4(x) + 1 |
544 | // i.e. cos(x) = 1 - cos^2(x/4)(8 - 8cos^2(x/4)) |
545 | |
546 | // Estimate the optimum number of times to use the argument reduction. |
547 | // TODO? Estimation reused from cosine() and may not be optimal here. |
548 | if (len < 32) { |
549 | k = Math.ceil(len / 3); |
550 | n = Math.pow(4, -k).toString(); |
551 | } else { |
552 | k = 16; |
553 | n = '2.3283064365386962890625e-10'; |
554 | } |
555 | |
556 | x = taylorSeries(Ctor, 1, x.times(n), new Ctor(1), true); |
557 | |
558 | // Reverse argument reduction |
559 | var cosh2_x, |
560 | i = k, |
561 | d8 = new Ctor(8); |
562 | for (; i--;) { |
563 | cosh2_x = x.times(x); |
564 | x = one.minus(cosh2_x.times(d8.minus(cosh2_x.times(d8)))); |
565 | } |
566 | |
567 | return finalise(x, Ctor.precision = pr, Ctor.rounding = rm, true); |
568 | }; |
569 | |
570 | |
571 | /* |
572 | * Return a new Decimal whose value is the hyperbolic sine of the value in radians of this |
573 | * Decimal. |
574 | * |
575 | * Domain: [-Infinity, Infinity] |
576 | * Range: [-Infinity, Infinity] |
577 | * |
578 | * sinh(x) = x + x^3/3! + x^5/5! + x^7/7! + ... |
579 | * |
580 | * sinh(0) = 0 |
581 | * sinh(-0) = -0 |
582 | * sinh(Infinity) = Infinity |
583 | * sinh(-Infinity) = -Infinity |
584 | * sinh(NaN) = NaN |
585 | * |
586 | * x time taken (ms) |
587 | * 10 2 ms |
588 | * 100 5 ms |
589 | * 1000 14 ms |
590 | * 10000 82 ms |
591 | * 100000 886 ms 1.4033316802130615897e+43429 |
592 | * 200000 2613 ms |
593 | * 300000 5407 ms |
594 | * 400000 8824 ms |
595 | * 500000 13026 ms 8.7080643612718084129e+217146 |
596 | * 1000000 48543 ms |
597 | * |
598 | * TODO? Compare performance of sinh(x) = 0.5 * (exp(x) - exp(-x)) |
599 | * |
600 | */ |
601 | P.hyperbolicSine = P.sinh = function () { |
602 | var k, pr, rm, len, |
603 | x = this, |
604 | Ctor = x.constructor; |
605 | |
606 | if (!x.isFinite() || x.isZero()) return new Ctor(x); |
607 | |
608 | pr = Ctor.precision; |
609 | rm = Ctor.rounding; |
610 | Ctor.precision = pr + Math.max(x.e, x.sd()) + 4; |
611 | Ctor.rounding = 1; |
612 | len = x.d.length; |
613 | |
614 | if (len < 3) { |
615 | x = taylorSeries(Ctor, 2, x, x, true); |
616 | } else { |
617 | |
618 | // Alternative argument reduction: sinh(3x) = sinh(x)(3 + 4sinh^2(x)) |
619 | // i.e. sinh(x) = sinh(x/3)(3 + 4sinh^2(x/3)) |
620 | // 3 multiplications and 1 addition |
621 | |
622 | // Argument reduction: sinh(5x) = sinh(x)(5 + sinh^2(x)(20 + 16sinh^2(x))) |
623 | // i.e. sinh(x) = sinh(x/5)(5 + sinh^2(x/5)(20 + 16sinh^2(x/5))) |
624 | // 4 multiplications and 2 additions |
625 | |
626 | // Estimate the optimum number of times to use the argument reduction. |
627 | k = 1.4 * Math.sqrt(len); |
628 | k = k > 16 ? 16 : k | 0; |
629 | |
630 | x = x.times(Math.pow(5, -k)); |
631 | |
632 | x = taylorSeries(Ctor, 2, x, x, true); |
633 | |
634 | // Reverse argument reduction |
635 | var sinh2_x, |
636 | d5 = new Ctor(5), |
637 | d16 = new Ctor(16), |
638 | d20 = new Ctor(20); |
639 | for (; k--;) { |
640 | sinh2_x = x.times(x); |
641 | x = x.times(d5.plus(sinh2_x.times(d16.times(sinh2_x).plus(d20)))); |
642 | } |
643 | } |
644 | |
645 | Ctor.precision = pr; |
646 | Ctor.rounding = rm; |
647 | |
648 | return finalise(x, pr, rm, true); |
649 | }; |
650 | |
651 | |
652 | /* |
653 | * Return a new Decimal whose value is the hyperbolic tangent of the value in radians of this |
654 | * Decimal. |
655 | * |
656 | * Domain: [-Infinity, Infinity] |
657 | * Range: [-1, 1] |
658 | * |
659 | * tanh(x) = sinh(x) / cosh(x) |
660 | * |
661 | * tanh(0) = 0 |
662 | * tanh(-0) = -0 |
663 | * tanh(Infinity) = 1 |
664 | * tanh(-Infinity) = -1 |
665 | * tanh(NaN) = NaN |
666 | * |
667 | */ |
668 | P.hyperbolicTangent = P.tanh = function () { |
669 | var pr, rm, |
670 | x = this, |
671 | Ctor = x.constructor; |
672 | |
673 | if (!x.isFinite()) return new Ctor(x.s); |
674 | if (x.isZero()) return new Ctor(x); |
675 | |
676 | pr = Ctor.precision; |
677 | rm = Ctor.rounding; |
678 | Ctor.precision = pr + 7; |
679 | Ctor.rounding = 1; |
680 | |
681 | return divide(x.sinh(), x.cosh(), Ctor.precision = pr, Ctor.rounding = rm); |
682 | }; |
683 | |
684 | |
685 | /* |
686 | * Return a new Decimal whose value is the arccosine (inverse cosine) in radians of the value of |
687 | * this Decimal. |
688 | * |
689 | * Domain: [-1, 1] |
690 | * Range: [0, pi] |
691 | * |
692 | * acos(x) = pi/2 - asin(x) |
693 | * |
694 | * acos(0) = pi/2 |
695 | * acos(-0) = pi/2 |
696 | * acos(1) = 0 |
697 | * acos(-1) = pi |
698 | * acos(1/2) = pi/3 |
699 | * acos(-1/2) = 2*pi/3 |
700 | * acos(|x| > 1) = NaN |
701 | * acos(NaN) = NaN |
702 | * |
703 | */ |
704 | P.inverseCosine = P.acos = function () { |
705 | var halfPi, |
706 | x = this, |
707 | Ctor = x.constructor, |
708 | k = x.abs().cmp(1), |
709 | pr = Ctor.precision, |
710 | rm = Ctor.rounding; |
711 | |
712 | if (k !== -1) { |
713 | return k === 0 |
714 | // |x| is 1 |
715 | ? x.isNeg() ? getPi(Ctor, pr, rm) : new Ctor(0) |
716 | // |x| > 1 or x is NaN |
717 | : new Ctor(NaN); |
718 | } |
719 | |
720 | if (x.isZero()) return getPi(Ctor, pr + 4, rm).times(0.5); |
721 | |
722 | // TODO? Special case acos(0.5) = pi/3 and acos(-0.5) = 2*pi/3 |
723 | |
724 | Ctor.precision = pr + 6; |
725 | Ctor.rounding = 1; |
726 | |
727 | x = x.asin(); |
728 | halfPi = getPi(Ctor, pr + 4, rm).times(0.5); |
729 | |
730 | Ctor.precision = pr; |
731 | Ctor.rounding = rm; |
732 | |
733 | return halfPi.minus(x); |
734 | }; |
735 | |
736 | |
737 | /* |
738 | * Return a new Decimal whose value is the inverse of the hyperbolic cosine in radians of the |
739 | * value of this Decimal. |
740 | * |
741 | * Domain: [1, Infinity] |
742 | * Range: [0, Infinity] |
743 | * |
744 | * acosh(x) = ln(x + sqrt(x^2 - 1)) |
745 | * |
746 | * acosh(x < 1) = NaN |
747 | * acosh(NaN) = NaN |
748 | * acosh(Infinity) = Infinity |
749 | * acosh(-Infinity) = NaN |
750 | * acosh(0) = NaN |
751 | * acosh(-0) = NaN |
752 | * acosh(1) = 0 |
753 | * acosh(-1) = NaN |
754 | * |
755 | */ |
756 | P.inverseHyperbolicCosine = P.acosh = function () { |
757 | var pr, rm, |
758 | x = this, |
759 | Ctor = x.constructor; |
760 | |
761 | if (x.lte(1)) return new Ctor(x.eq(1) ? 0 : NaN); |
762 | if (!x.isFinite()) return new Ctor(x); |
763 | |
764 | pr = Ctor.precision; |
765 | rm = Ctor.rounding; |
766 | Ctor.precision = pr + Math.max(Math.abs(x.e), x.sd()) + 4; |
767 | Ctor.rounding = 1; |
768 | external = false; |
769 | |
770 | x = x.times(x).minus(1).sqrt().plus(x); |
771 | |
772 | external = true; |
773 | Ctor.precision = pr; |
774 | Ctor.rounding = rm; |
775 | |
776 | return x.ln(); |
777 | }; |
778 | |
779 | |
780 | /* |
781 | * Return a new Decimal whose value is the inverse of the hyperbolic sine in radians of the value |
782 | * of this Decimal. |
783 | * |
784 | * Domain: [-Infinity, Infinity] |
785 | * Range: [-Infinity, Infinity] |
786 | * |
787 | * asinh(x) = ln(x + sqrt(x^2 + 1)) |
788 | * |
789 | * asinh(NaN) = NaN |
790 | * asinh(Infinity) = Infinity |
791 | * asinh(-Infinity) = -Infinity |
792 | * asinh(0) = 0 |
793 | * asinh(-0) = -0 |
794 | * |
795 | */ |
796 | P.inverseHyperbolicSine = P.asinh = function () { |
797 | var pr, rm, |
798 | x = this, |
799 | Ctor = x.constructor; |
800 | |
801 | if (!x.isFinite() || x.isZero()) return new Ctor(x); |
802 | |
803 | pr = Ctor.precision; |
804 | rm = Ctor.rounding; |
805 | Ctor.precision = pr + 2 * Math.max(Math.abs(x.e), x.sd()) + 6; |
806 | Ctor.rounding = 1; |
807 | external = false; |
808 | |
809 | x = x.times(x).plus(1).sqrt().plus(x); |
810 | |
811 | external = true; |
812 | Ctor.precision = pr; |
813 | Ctor.rounding = rm; |
814 | |
815 | return x.ln(); |
816 | }; |
817 | |
818 | |
819 | /* |
820 | * Return a new Decimal whose value is the inverse of the hyperbolic tangent in radians of the |
821 | * value of this Decimal. |
822 | * |
823 | * Domain: [-1, 1] |
824 | * Range: [-Infinity, Infinity] |
825 | * |
826 | * atanh(x) = 0.5 * ln((1 + x) / (1 - x)) |
827 | * |
828 | * atanh(|x| > 1) = NaN |
829 | * atanh(NaN) = NaN |
830 | * atanh(Infinity) = NaN |
831 | * atanh(-Infinity) = NaN |
832 | * atanh(0) = 0 |
833 | * atanh(-0) = -0 |
834 | * atanh(1) = Infinity |
835 | * atanh(-1) = -Infinity |
836 | * |
837 | */ |
838 | P.inverseHyperbolicTangent = P.atanh = function () { |
839 | var pr, rm, wpr, xsd, |
840 | x = this, |
841 | Ctor = x.constructor; |
842 | |
843 | if (!x.isFinite()) return new Ctor(NaN); |
844 | if (x.e >= 0) return new Ctor(x.abs().eq(1) ? x.s / 0 : x.isZero() ? x : NaN); |
845 | |
846 | pr = Ctor.precision; |
847 | rm = Ctor.rounding; |
848 | xsd = x.sd(); |
849 | |
850 | if (Math.max(xsd, pr) < 2 * -x.e - 1) return finalise(new Ctor(x), pr, rm, true); |
851 | |
852 | Ctor.precision = wpr = xsd - x.e; |
853 | |
854 | x = divide(x.plus(1), new Ctor(1).minus(x), wpr + pr, 1); |
855 | |
856 | Ctor.precision = pr + 4; |
857 | Ctor.rounding = 1; |
858 | |
859 | x = x.ln(); |
860 | |
861 | Ctor.precision = pr; |
862 | Ctor.rounding = rm; |
863 | |
864 | return x.times(0.5); |
865 | }; |
866 | |
867 | |
868 | /* |
869 | * Return a new Decimal whose value is the arcsine (inverse sine) in radians of the value of this |
870 | * Decimal. |
871 | * |
872 | * Domain: [-Infinity, Infinity] |
873 | * Range: [-pi/2, pi/2] |
874 | * |
875 | * asin(x) = 2*atan(x/(1 + sqrt(1 - x^2))) |
876 | * |
877 | * asin(0) = 0 |
878 | * asin(-0) = -0 |
879 | * asin(1/2) = pi/6 |
880 | * asin(-1/2) = -pi/6 |
881 | * asin(1) = pi/2 |
882 | * asin(-1) = -pi/2 |
883 | * asin(|x| > 1) = NaN |
884 | * asin(NaN) = NaN |
885 | * |
886 | * TODO? Compare performance of Taylor series. |
887 | * |
888 | */ |
889 | P.inverseSine = P.asin = function () { |
890 | var halfPi, k, |
891 | pr, rm, |
892 | x = this, |
893 | Ctor = x.constructor; |
894 | |
895 | if (x.isZero()) return new Ctor(x); |
896 | |
897 | k = x.abs().cmp(1); |
898 | pr = Ctor.precision; |
899 | rm = Ctor.rounding; |
900 | |
901 | if (k !== -1) { |
902 | |
903 | // |x| is 1 |
904 | if (k === 0) { |
905 | halfPi = getPi(Ctor, pr + 4, rm).times(0.5); |
906 | halfPi.s = x.s; |
907 | return halfPi; |
908 | } |
909 | |
910 | // |x| > 1 or x is NaN |
911 | return new Ctor(NaN); |
912 | } |
913 | |
914 | // TODO? Special case asin(1/2) = pi/6 and asin(-1/2) = -pi/6 |
915 | |
916 | Ctor.precision = pr + 6; |
917 | Ctor.rounding = 1; |
918 | |
919 | x = x.div(new Ctor(1).minus(x.times(x)).sqrt().plus(1)).atan(); |
920 | |
921 | Ctor.precision = pr; |
922 | Ctor.rounding = rm; |
923 | |
924 | return x.times(2); |
925 | }; |
926 | |
927 | |
928 | /* |
929 | * Return a new Decimal whose value is the arctangent (inverse tangent) in radians of the value |
930 | * of this Decimal. |
931 | * |
932 | * Domain: [-Infinity, Infinity] |
933 | * Range: [-pi/2, pi/2] |
934 | * |
935 | * atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... |
936 | * |
937 | * atan(0) = 0 |
938 | * atan(-0) = -0 |
939 | * atan(1) = pi/4 |
940 | * atan(-1) = -pi/4 |
941 | * atan(Infinity) = pi/2 |
942 | * atan(-Infinity) = -pi/2 |
943 | * atan(NaN) = NaN |
944 | * |
945 | */ |
946 | P.inverseTangent = P.atan = function () { |
947 | var i, j, k, n, px, t, r, wpr, x2, |
948 | x = this, |
949 | Ctor = x.constructor, |
950 | pr = Ctor.precision, |
951 | rm = Ctor.rounding; |
952 | |
953 | if (!x.isFinite()) { |
954 | if (!x.s) return new Ctor(NaN); |
955 | if (pr + 4 <= PI_PRECISION) { |
956 | r = getPi(Ctor, pr + 4, rm).times(0.5); |
957 | r.s = x.s; |
958 | return r; |
959 | } |
960 | } else if (x.isZero()) { |
961 | return new Ctor(x); |
962 | } else if (x.abs().eq(1) && pr + 4 <= PI_PRECISION) { |
963 | r = getPi(Ctor, pr + 4, rm).times(0.25); |
964 | r.s = x.s; |
965 | return r; |
966 | } |
967 | |
968 | Ctor.precision = wpr = pr + 10; |
969 | Ctor.rounding = 1; |
970 | |
971 | // TODO? if (x >= 1 && pr <= PI_PRECISION) atan(x) = halfPi * x.s - atan(1 / x); |
972 | |
973 | // Argument reduction |
974 | // Ensure |x| < 0.42 |
975 | // atan(x) = 2 * atan(x / (1 + sqrt(1 + x^2))) |
976 | |
977 | k = Math.min(28, wpr / LOG_BASE + 2 | 0); |
978 | |
979 | for (i = k; i; --i) x = x.div(x.times(x).plus(1).sqrt().plus(1)); |
980 | |
981 | external = false; |
982 | |
983 | j = Math.ceil(wpr / LOG_BASE); |
984 | n = 1; |
985 | x2 = x.times(x); |
986 | r = new Ctor(x); |
987 | px = x; |
988 | |
989 | // atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... |
990 | for (; i !== -1;) { |
991 | px = px.times(x2); |
992 | t = r.minus(px.div(n += 2)); |
993 | |
994 | px = px.times(x2); |
995 | r = t.plus(px.div(n += 2)); |
996 | |
997 | if (r.d[j] !== void 0) for (i = j; r.d[i] === t.d[i] && i--;); |
998 | } |
999 | |
1000 | if (k) r = r.times(2 << (k - 1)); |
1001 | |
1002 | external = true; |
1003 | |
1004 | return finalise(r, Ctor.precision = pr, Ctor.rounding = rm, true); |
1005 | }; |
1006 | |
1007 | |
1008 | /* |
1009 | * Return true if the value of this Decimal is a finite number, otherwise return false. |
1010 | * |
1011 | */ |
1012 | P.isFinite = function () { |
1013 | return !!this.d; |
1014 | }; |
1015 | |
1016 | |
1017 | /* |
1018 | * Return true if the value of this Decimal is an integer, otherwise return false. |
1019 | * |
1020 | */ |
1021 | P.isInteger = P.isInt = function () { |
1022 | return !!this.d && mathfloor(this.e / LOG_BASE) > this.d.length - 2; |
1023 | }; |
1024 | |
1025 | |
1026 | /* |
1027 | * Return true if the value of this Decimal is NaN, otherwise return false. |
1028 | * |
1029 | */ |
1030 | P.isNaN = function () { |
1031 | return !this.s; |
1032 | }; |
1033 | |
1034 | |
1035 | /* |
1036 | * Return true if the value of this Decimal is negative, otherwise return false. |
1037 | * |
1038 | */ |
1039 | P.isNegative = P.isNeg = function () { |
1040 | return this.s < 0; |
1041 | }; |
1042 | |
1043 | |
1044 | /* |
1045 | * Return true if the value of this Decimal is positive, otherwise return false. |
1046 | * |
1047 | */ |
1048 | P.isPositive = P.isPos = function () { |
1049 | return this.s > 0; |
1050 | }; |
1051 | |
1052 | |
1053 | /* |
1054 | * Return true if the value of this Decimal is 0 or -0, otherwise return false. |
1055 | * |
1056 | */ |
1057 | P.isZero = function () { |
1058 | return !!this.d && this.d[0] === 0; |
1059 | }; |
1060 | |
1061 | |
1062 | /* |
1063 | * Return true if the value of this Decimal is less than `y`, otherwise return false. |
1064 | * |
1065 | */ |
1066 | P.lessThan = P.lt = function (y) { |
1067 | return this.cmp(y) < 0; |
1068 | }; |
1069 | |
1070 | |
1071 | /* |
1072 | * Return true if the value of this Decimal is less than or equal to `y`, otherwise return false. |
1073 | * |
1074 | */ |
1075 | P.lessThanOrEqualTo = P.lte = function (y) { |
1076 | return this.cmp(y) < 1; |
1077 | }; |
1078 | |
1079 | |
1080 | /* |
1081 | * Return the logarithm of the value of this Decimal to the specified base, rounded to `precision` |
1082 | * significant digits using rounding mode `rounding`. |
1083 | * |
1084 | * If no base is specified, return log[10](arg). |
1085 | * |
1086 | * log[base](arg) = ln(arg) / ln(base) |
1087 | * |
1088 | * The result will always be correctly rounded if the base of the log is 10, and 'almost always' |
1089 | * otherwise: |
1090 | * |
1091 | * Depending on the rounding mode, the result may be incorrectly rounded if the first fifteen |
1092 | * rounding digits are [49]99999999999999 or [50]00000000000000. In that case, the maximum error |
1093 | * between the result and the correctly rounded result will be one ulp (unit in the last place). |
1094 | * |
1095 | * log[-b](a) = NaN |
1096 | * log[0](a) = NaN |
1097 | * log[1](a) = NaN |
1098 | * log[NaN](a) = NaN |
1099 | * log[Infinity](a) = NaN |
1100 | * log[b](0) = -Infinity |
1101 | * log[b](-0) = -Infinity |
1102 | * log[b](-a) = NaN |
1103 | * log[b](1) = 0 |
1104 | * log[b](Infinity) = Infinity |
1105 | * log[b](NaN) = NaN |
1106 | * |
1107 | * [base] {number|string|Decimal} The base of the logarithm. |
1108 | * |
1109 | */ |
1110 | P.logarithm = P.log = function (base) { |
1111 | var isBase10, d, denominator, k, inf, num, sd, r, |
1112 | arg = this, |
1113 | Ctor = arg.constructor, |
1114 | pr = Ctor.precision, |
1115 | rm = Ctor.rounding, |
1116 | guard = 5; |
1117 | |
1118 | // Default base is 10. |
1119 | if (base == null) { |
1120 | base = new Ctor(10); |
1121 | isBase10 = true; |
1122 | } else { |
1123 | base = new Ctor(base); |
1124 | d = base.d; |
1125 | |
1126 | // Return NaN if base is negative, or non-finite, or is 0 or 1. |
1127 | if (base.s < 0 || !d || !d[0] || base.eq(1)) return new Ctor(NaN); |
1128 | |
1129 | isBase10 = base.eq(10); |
1130 | } |
1131 | |
1132 | d = arg.d; |
1133 | |
1134 | // Is arg negative, non-finite, 0 or 1? |
1135 | if (arg.s < 0 || !d || !d[0] || arg.eq(1)) { |
1136 | return new Ctor(d && !d[0] ? -1 / 0 : arg.s != 1 ? NaN : d ? 0 : 1 / 0); |
1137 | } |
1138 | |
1139 | // The result will have a non-terminating decimal expansion if base is 10 and arg is not an |
1140 | // integer power of 10. |
1141 | if (isBase10) { |
1142 | if (d.length > 1) { |
1143 | inf = true; |
1144 | } else { |
1145 | for (k = d[0]; k % 10 === 0;) k /= 10; |
1146 | inf = k !== 1; |
1147 | } |
1148 | } |
1149 | |
1150 | external = false; |
1151 | sd = pr + guard; |
1152 | num = naturalLogarithm(arg, sd); |
1153 | denominator = isBase10 ? getLn10(Ctor, sd + 10) : naturalLogarithm(base, sd); |
1154 | |
1155 | // The result will have 5 rounding digits. |
1156 | r = divide(num, denominator, sd, 1); |
1157 | |
1158 | // If at a rounding boundary, i.e. the result's rounding digits are [49]9999 or [50]0000, |
1159 | // calculate 10 further digits. |
1160 | // |
1161 | // If the result is known to have an infinite decimal expansion, repeat this until it is clear |
1162 | // that the result is above or below the boundary. Otherwise, if after calculating the 10 |
1163 | // further digits, the last 14 are nines, round up and assume the result is exact. |
1164 | // Also assume the result is exact if the last 14 are zero. |
1165 | // |
1166 | // Example of a result that will be incorrectly rounded: |
1167 | // log[1048576](4503599627370502) = 2.60000000000000009610279511444746... |
1168 | // The above result correctly rounded using ROUND_CEIL to 1 decimal place should be 2.7, but it |
1169 | // will be given as 2.6 as there are 15 zeros immediately after the requested decimal place, so |
1170 | // the exact result would be assumed to be 2.6, which rounded using ROUND_CEIL to 1 decimal |
1171 | // place is still 2.6. |
1172 | if (checkRoundingDigits(r.d, k = pr, rm)) { |
1173 | |
1174 | do { |
1175 | sd += 10; |
1176 | num = naturalLogarithm(arg, sd); |
1177 | denominator = isBase10 ? getLn10(Ctor, sd + 10) : naturalLogarithm(base, sd); |
1178 | r = divide(num, denominator, sd, 1); |
1179 | |
1180 | if (!inf) { |
1181 | |
1182 | // Check for 14 nines from the 2nd rounding digit, as the first may be 4. |
1183 | if (+digitsToString(r.d).slice(k + 1, k + 15) + 1 == 1e14) { |
1184 | r = finalise(r, pr + 1, 0); |
1185 | } |
1186 | |
1187 | break; |
1188 | } |
1189 | } while (checkRoundingDigits(r.d, k += 10, rm)); |
1190 | } |
1191 | |
1192 | external = true; |
1193 | |
1194 | return finalise(r, pr, rm); |
1195 | }; |
1196 | |
1197 | |
1198 | /* |
1199 | * Return a new Decimal whose value is the maximum of the arguments and the value of this Decimal. |
1200 | * |
1201 | * arguments {number|string|Decimal} |
1202 | * |
1203 | P.max = function () { |
1204 | Array.prototype.push.call(arguments, this); |
1205 | return maxOrMin(this.constructor, arguments, 'lt'); |
1206 | }; |
1207 | */ |
1208 | |
1209 | |
1210 | /* |
1211 | * Return a new Decimal whose value is the minimum of the arguments and the value of this Decimal. |
1212 | * |
1213 | * arguments {number|string|Decimal} |
1214 | * |
1215 | P.min = function () { |
1216 | Array.prototype.push.call(arguments, this); |
1217 | return maxOrMin(this.constructor, arguments, 'gt'); |
1218 | }; |
1219 | */ |
1220 | |
1221 | |
1222 | /* |
1223 | * n - 0 = n |
1224 | * n - N = N |
1225 | * n - I = -I |
1226 | * 0 - n = -n |
1227 | * 0 - 0 = 0 |
1228 | * 0 - N = N |
1229 | * 0 - I = -I |
1230 | * N - n = N |
1231 | * N - 0 = N |
1232 | * N - N = N |
1233 | * N - I = N |
1234 | * I - n = I |
1235 | * I - 0 = I |
1236 | * I - N = N |
1237 | * I - I = N |
1238 | * |
1239 | * Return a new Decimal whose value is the value of this Decimal minus `y`, rounded to `precision` |
1240 | * significant digits using rounding mode `rounding`. |
1241 | * |
1242 | */ |
1243 | P.minus = P.sub = function (y) { |
1244 | var d, e, i, j, k, len, pr, rm, xd, xe, xLTy, yd, |
1245 | x = this, |
1246 | Ctor = x.constructor; |
1247 | |
1248 | y = new Ctor(y); |
1249 | |
1250 | // If either is not finite... |
1251 | if (!x.d || !y.d) { |
1252 | |
1253 | // Return NaN if either is NaN. |
1254 | if (!x.s || !y.s) y = new Ctor(NaN); |
1255 | |
1256 | // Return y negated if x is finite and y is ±Infinity. |
1257 | else if (x.d) y.s = -y.s; |
1258 | |
1259 | // Return x if y is finite and x is ±Infinity. |
1260 | // Return x if both are ±Infinity with different signs. |
1261 | // Return NaN if both are ±Infinity with the same sign. |
1262 | else y = new Ctor(y.d || x.s !== y.s ? x : NaN); |
1263 | |
1264 | return y; |
1265 | } |
1266 | |
1267 | // If signs differ... |
1268 | if (x.s != y.s) { |
1269 | y.s = -y.s; |
1270 | return x.plus(y); |
1271 | } |
1272 | |
1273 | xd = x.d; |
1274 | yd = y.d; |
1275 | pr = Ctor.precision; |
1276 | rm = Ctor.rounding; |
1277 | |
1278 | // If either is zero... |
1279 | if (!xd[0] || !yd[0]) { |
1280 | |
1281 | // Return y negated if x is zero and y is non-zero. |
1282 | if (yd[0]) y.s = -y.s; |
1283 | |
1284 | // Return x if y is zero and x is non-zero. |
1285 | else if (xd[0]) y = new Ctor(x); |
1286 | |
1287 | // Return zero if both are zero. |
1288 | // From IEEE 754 (2008) 6.3: 0 - 0 = -0 - -0 = -0 when rounding to -Infinity. |
1289 | else return new Ctor(rm === 3 ? -0 : 0); |
1290 | |
1291 | return external ? finalise(y, pr, rm) : y; |
1292 | } |
1293 | |
1294 | // x and y are finite, non-zero numbers with the same sign. |
1295 | |
1296 | // Calculate base 1e7 exponents. |
1297 | e = mathfloor(y.e / LOG_BASE); |
1298 | xe = mathfloor(x.e / LOG_BASE); |
1299 | |
1300 | xd = xd.slice(); |
1301 | k = xe - e; |
1302 | |
1303 | // If base 1e7 exponents differ... |
1304 | if (k) { |
1305 | xLTy = k < 0; |
1306 | |
1307 | if (xLTy) { |
1308 | d = xd; |
1309 | k = -k; |
1310 | len = yd.length; |
1311 | } else { |
1312 | d = yd; |
1313 | e = xe; |
1314 | len = xd.length; |
1315 | } |
1316 | |
1317 | // Numbers with massively different exponents would result in a very high number of |
1318 | // zeros needing to be prepended, but this can be avoided while still ensuring correct |
1319 | // rounding by limiting the number of zeros to `Math.ceil(pr / LOG_BASE) + 2`. |
1320 | i = Math.max(Math.ceil(pr / LOG_BASE), len) + 2; |
1321 | |
1322 | if (k > i) { |
1323 | k = i; |
1324 | d.length = 1; |
1325 | } |
1326 | |
1327 | // Prepend zeros to equalise exponents. |
1328 | d.reverse(); |
1329 | for (i = k; i--;) d.push(0); |
1330 | d.reverse(); |
1331 | |
1332 | // Base 1e7 exponents equal. |
1333 | } else { |
1334 | |
1335 | // Check digits to determine which is the bigger number. |
1336 | |
1337 | i = xd.length; |
1338 | len = yd.length; |
1339 | xLTy = i < len; |
1340 | if (xLTy) len = i; |
1341 | |
1342 | for (i = 0; i < len; i++) { |
1343 | if (xd[i] != yd[i]) { |
1344 | xLTy = xd[i] < yd[i]; |
1345 | break; |
1346 | } |
1347 | } |
1348 | |
1349 | k = 0; |
1350 | } |
1351 | |
1352 | if (xLTy) { |
1353 | d = xd; |
1354 | xd = yd; |
1355 | yd = d; |
1356 | y.s = -y.s; |
1357 | } |
1358 | |
1359 | len = xd.length; |
1360 | |
1361 | // Append zeros to `xd` if shorter. |
1362 | // Don't add zeros to `yd` if shorter as subtraction only needs to start at `yd` length. |
1363 | for (i = yd.length - len; i > 0; --i) xd[len++] = 0; |
1364 | |
1365 | // Subtract yd from xd. |
1366 | for (i = yd.length; i > k;) { |
1367 | |
1368 | if (xd[--i] < yd[i]) { |
1369 | for (j = i; j && xd[--j] === 0;) xd[j] = BASE - 1; |
1370 | --xd[j]; |
1371 | xd[i] += BASE; |
1372 | } |
1373 | |
1374 | xd[i] -= yd[i]; |
1375 | } |
1376 | |
1377 | // Remove trailing zeros. |
1378 | for (; xd[--len] === 0;) xd.pop(); |
1379 | |
1380 | // Remove leading zeros and adjust exponent accordingly. |
1381 | for (; xd[0] === 0; xd.shift()) --e; |
1382 | |
1383 | // Zero? |
1384 | if (!xd[0]) return new Ctor(rm === 3 ? -0 : 0); |
1385 | |
1386 | y.d = xd; |
1387 | y.e = getBase10Exponent(xd, e); |
1388 | |
1389 | return external ? finalise(y, pr, rm) : y; |
1390 | }; |
1391 | |
1392 | |
1393 | /* |
1394 | * n % 0 = N |
1395 | * n % N = N |
1396 | * n % I = n |
1397 | * 0 % n = 0 |
1398 | * -0 % n = -0 |
1399 | * 0 % 0 = N |
1400 | * 0 % N = N |
1401 | * 0 % I = 0 |
1402 | * N % n = N |
1403 | * N % 0 = N |
1404 | * N % N = N |
1405 | * N % I = N |
1406 | * I % n = N |
1407 | * I % 0 = N |
1408 | * I % N = N |
1409 | * I % I = N |
1410 | * |
1411 | * Return a new Decimal whose value is the value of this Decimal modulo `y`, rounded to |
1412 | * `precision` significant digits using rounding mode `rounding`. |
1413 | * |
1414 | * The result depends on the modulo mode. |
1415 | * |
1416 | */ |
1417 | P.modulo = P.mod = function (y) { |
1418 | var q, |
1419 | x = this, |
1420 | Ctor = x.constructor; |
1421 | |
1422 | y = new Ctor(y); |
1423 | |
1424 | // Return NaN if x is ±Infinity or NaN, or y is NaN or ±0. |
1425 | if (!x.d || !y.s || y.d && !y.d[0]) return new Ctor(NaN); |
1426 | |
1427 | // Return x if y is ±Infinity or x is ±0. |
1428 | if (!y.d || x.d && !x.d[0]) { |
1429 | return finalise(new Ctor(x), Ctor.precision, Ctor.rounding); |
1430 | } |
1431 | |
1432 | // Prevent rounding of intermediate calculations. |
1433 | external = false; |
1434 | |
1435 | if (Ctor.modulo == 9) { |
1436 | |
1437 | // Euclidian division: q = sign(y) * floor(x / abs(y)) |
1438 | // result = x - q * y where 0 <= result < abs(y) |
1439 | q = divide(x, y.abs(), 0, 3, 1); |
1440 | q.s *= y.s; |
1441 | } else { |
1442 | q = divide(x, y, 0, Ctor.modulo, 1); |
1443 | } |
1444 | |
1445 | q = q.times(y); |
1446 | |
1447 | external = true; |
1448 | |
1449 | return x.minus(q); |
1450 | }; |
1451 | |
1452 | |
1453 | /* |
1454 | * Return a new Decimal whose value is the natural exponential of the value of this Decimal, |
1455 | * i.e. the base e raised to the power the value of this Decimal, rounded to `precision` |
1456 | * significant digits using rounding mode `rounding`. |
1457 | * |
1458 | */ |
1459 | P.naturalExponential = P.exp = function () { |
1460 | return naturalExponential(this); |
1461 | }; |
1462 | |
1463 | |
1464 | /* |
1465 | * Return a new Decimal whose value is the natural logarithm of the value of this Decimal, |
1466 | * rounded to `precision` significant digits using rounding mode `rounding`. |
1467 | * |
1468 | */ |
1469 | P.naturalLogarithm = P.ln = function () { |
1470 | return naturalLogarithm(this); |
1471 | }; |
1472 | |
1473 | |
1474 | /* |
1475 | * Return a new Decimal whose value is the value of this Decimal negated, i.e. as if multiplied by |
1476 | * -1. |
1477 | * |
1478 | */ |
1479 | P.negated = P.neg = function () { |
1480 | var x = new this.constructor(this); |
1481 | x.s = -x.s; |
1482 | return finalise(x); |
1483 | }; |
1484 | |
1485 | |
1486 | /* |
1487 | * n + 0 = n |
1488 | * n + N = N |
1489 | * n + I = I |
1490 | * 0 + n = n |
1491 | * 0 + 0 = 0 |
1492 | * 0 + N = N |
1493 | * 0 + I = I |
1494 | * N + n = N |
1495 | * N + 0 = N |
1496 | * N + N = N |
1497 | * N + I = N |
1498 | * I + n = I |
1499 | * I + 0 = I |
1500 | * I + N = N |
1501 | * I + I = I |
1502 | * |
1503 | * Return a new Decimal whose value is the value of this Decimal plus `y`, rounded to `precision` |
1504 | * significant digits using rounding mode `rounding`. |
1505 | * |
1506 | */ |
1507 | P.plus = P.add = function (y) { |
1508 | var carry, d, e, i, k, len, pr, rm, xd, yd, |
1509 | x = this, |
1510 | Ctor = x.constructor; |
1511 | |
1512 | y = new Ctor(y); |
1513 | |
1514 | // If either is not finite... |
1515 | if (!x.d || !y.d) { |
1516 | |
1517 | // Return NaN if either is NaN. |
1518 | if (!x.s || !y.s) y = new Ctor(NaN); |
1519 | |
1520 | // Return x if y is finite and x is ±Infinity. |
1521 | // Return x if both are ±Infinity with the same sign. |
1522 | // Return NaN if both are ±Infinity with different signs. |
1523 | // Return y if x is finite and y is ±Infinity. |
1524 | else if (!x.d) y = new Ctor(y.d || x.s === y.s ? x : NaN); |
1525 | |
1526 | return y; |
1527 | } |
1528 | |
1529 | // If signs differ... |
1530 | if (x.s != y.s) { |
1531 | y.s = -y.s; |
1532 | return x.minus(y); |
1533 | } |
1534 | |
1535 | xd = x.d; |
1536 | yd = y.d; |
1537 | pr = Ctor.precision; |
1538 | rm = Ctor.rounding; |
1539 | |
1540 | // If either is zero... |
1541 | if (!xd[0] || !yd[0]) { |
1542 | |
1543 | // Return x if y is zero. |
1544 | // Return y if y is non-zero. |
1545 | if (!yd[0]) y = new Ctor(x); |
1546 | |
1547 | return external ? finalise(y, pr, rm) : y; |
1548 | } |
1549 | |
1550 | // x and y are finite, non-zero numbers with the same sign. |
1551 | |
1552 | // Calculate base 1e7 exponents. |
1553 | k = mathfloor(x.e / LOG_BASE); |
1554 | e = mathfloor(y.e / LOG_BASE); |
1555 | |
1556 | xd = xd.slice(); |
1557 | i = k - e; |
1558 | |
1559 | // If base 1e7 exponents differ... |
1560 | if (i) { |
1561 | |
1562 | if (i < 0) { |
1563 | d = xd; |
1564 | i = -i; |
1565 | len = yd.length; |
1566 | } else { |
1567 | d = yd; |
1568 | e = k; |
1569 | len = xd.length; |
1570 | } |
1571 | |
1572 | // Limit number of zeros prepended to max(ceil(pr / LOG_BASE), len) + 1. |
1573 | k = Math.ceil(pr / LOG_BASE); |
1574 | len = k > len ? k + 1 : len + 1; |
1575 | |
1576 | if (i > len) { |
1577 | i = len; |
1578 | d.length = 1; |
1579 | } |
1580 | |
1581 | // Prepend zeros to equalise exponents. Note: Faster to use reverse then do unshifts. |
1582 | d.reverse(); |
1583 | for (; i--;) d.push(0); |
1584 | d.reverse(); |
1585 | } |
1586 | |
1587 | len = xd.length; |
1588 | i = yd.length; |
1589 | |
1590 | // If yd is longer than xd, swap xd and yd so xd points to the longer array. |
1591 | if (len - i < 0) { |
1592 | i = len; |
1593 | d = yd; |
1594 | yd = xd; |
1595 | xd = d; |
1596 | } |
1597 | |
1598 | // Only start adding at yd.length - 1 as the further digits of xd can be left as they are. |
1599 | for (carry = 0; i;) { |
1600 | carry = (xd[--i] = xd[i] + yd[i] + carry) / BASE | 0; |
1601 | xd[i] %= BASE; |
1602 | } |
1603 | |
1604 | if (carry) { |
1605 | xd.unshift(carry); |
1606 | ++e; |
1607 | } |
1608 | |
1609 | // Remove trailing zeros. |
1610 | // No need to check for zero, as +x + +y != 0 && -x + -y != 0 |
1611 | for (len = xd.length; xd[--len] == 0;) xd.pop(); |
1612 | |
1613 | y.d = xd; |
1614 | y.e = getBase10Exponent(xd, e); |
1615 | |
1616 | return external ? finalise(y, pr, rm) : y; |
1617 | }; |
1618 | |
1619 | |
1620 | /* |
1621 | * Return the number of significant digits of the value of this Decimal. |
1622 | * |
1623 | * [z] {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0. |
1624 | * |
1625 | */ |
1626 | P.precision = P.sd = function (z) { |
1627 | var k, |
1628 | x = this; |
1629 | |
1630 | if (z !== void 0 && z !== !!z && z !== 1 && z !== 0) throw Error(invalidArgument + z); |
1631 | |
1632 | if (x.d) { |
1633 | k = getPrecision(x.d); |
1634 | if (z && x.e + 1 > k) k = x.e + 1; |
1635 | } else { |
1636 | k = NaN; |
1637 | } |
1638 | |
1639 | return k; |
1640 | }; |
1641 | |
1642 | |
1643 | /* |
1644 | * Return a new Decimal whose value is the value of this Decimal rounded to a whole number using |
1645 | * rounding mode `rounding`. |
1646 | * |
1647 | */ |
1648 | P.round = function () { |
1649 | var x = this, |
1650 | Ctor = x.constructor; |
1651 | |
1652 | return finalise(new Ctor(x), x.e + 1, Ctor.rounding); |
1653 | }; |
1654 | |
1655 | |
1656 | /* |
1657 | * Return a new Decimal whose value is the sine of the value in radians of this Decimal. |
1658 | * |
1659 | * Domain: [-Infinity, Infinity] |
1660 | * Range: [-1, 1] |
1661 | * |
1662 | * sin(x) = x - x^3/3! + x^5/5! - ... |
1663 | * |
1664 | * sin(0) = 0 |
1665 | * sin(-0) = -0 |
1666 | * sin(Infinity) = NaN |
1667 | * sin(-Infinity) = NaN |
1668 | * sin(NaN) = NaN |
1669 | * |
1670 | */ |
1671 | P.sine = P.sin = function () { |
1672 | var pr, rm, |
1673 | x = this, |
1674 | Ctor = x.constructor; |
1675 | |
1676 | if (!x.isFinite()) return new Ctor(NaN); |
1677 | if (x.isZero()) return new Ctor(x); |
1678 | |
1679 | pr = Ctor.precision; |
1680 | rm = Ctor.rounding; |
1681 | Ctor.precision = pr + Math.max(x.e, x.sd()) + LOG_BASE; |
1682 | Ctor.rounding = 1; |
1683 | |
1684 | x = sine(Ctor, toLessThanHalfPi(Ctor, x)); |
1685 | |
1686 | Ctor.precision = pr; |
1687 | Ctor.rounding = rm; |
1688 | |
1689 | return finalise(quadrant > 2 ? x.neg() : x, pr, rm, true); |
1690 | }; |
1691 | |
1692 | |
1693 | /* |
1694 | * Return a new Decimal whose value is the square root of this Decimal, rounded to `precision` |
1695 | * significant digits using rounding mode `rounding`. |
1696 | * |
1697 | * sqrt(-n) = N |
1698 | * sqrt(N) = N |
1699 | * sqrt(-I) = N |
1700 | * sqrt(I) = I |
1701 | * sqrt(0) = 0 |
1702 | * sqrt(-0) = -0 |
1703 | * |
1704 | */ |
1705 | P.squareRoot = P.sqrt = function () { |
1706 | var m, n, sd, r, rep, t, |
1707 | x = this, |
1708 | d = x.d, |
1709 | e = x.e, |
1710 | s = x.s, |
1711 | Ctor = x.constructor; |
1712 | |
1713 | // Negative/NaN/Infinity/zero? |
1714 | if (s !== 1 || !d || !d[0]) { |
1715 | return new Ctor(!s || s < 0 && (!d || d[0]) ? NaN : d ? x : 1 / 0); |
1716 | } |
1717 | |
1718 | external = false; |
1719 | |
1720 | // Initial estimate. |
1721 | s = Math.sqrt(+x); |
1722 | |
1723 | // Math.sqrt underflow/overflow? |
1724 | // Pass x to Math.sqrt as integer, then adjust the exponent of the result. |
1725 | if (s == 0 || s == 1 / 0) { |
1726 | n = digitsToString(d); |
1727 | |
1728 | if ((n.length + e) % 2 == 0) n += '0'; |
1729 | s = Math.sqrt(n); |
1730 | e = mathfloor((e + 1) / 2) - (e < 0 || e % 2); |
1731 | |
1732 | if (s == 1 / 0) { |
1733 | n = '1e' + e; |
1734 | } else { |
1735 | n = s.toExponential(); |
1736 | n = n.slice(0, n.indexOf('e') + 1) + e; |
1737 | } |
1738 | |
1739 | r = new Ctor(n); |
1740 | } else { |
1741 | r = new Ctor(s.toString()); |
1742 | } |
1743 | |
1744 | sd = (e = Ctor.precision) + 3; |
1745 | |
1746 | // Newton-Raphson iteration. |
1747 | for (;;) { |
1748 | t = r; |
1749 | r = t.plus(divide(x, t, sd + 2, 1)).times(0.5); |
1750 | |
1751 | // TODO? Replace with for-loop and checkRoundingDigits. |
1752 | if (digitsToString(t.d).slice(0, sd) === (n = digitsToString(r.d)).slice(0, sd)) { |
1753 | n = n.slice(sd - 3, sd + 1); |
1754 | |
1755 | // The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or |
1756 | // 4999, i.e. approaching a rounding boundary, continue the iteration. |
1757 | if (n == '9999' || !rep && n == '4999') { |
1758 | |
1759 | // On the first iteration only, check to see if rounding up gives the exact result as the |
1760 | // nines may infinitely repeat. |
1761 | if (!rep) { |
1762 | finalise(t, e + 1, 0); |
1763 | |
1764 | if (t.times(t).eq(x)) { |
1765 | r = t; |
1766 | break; |
1767 | } |
1768 | } |
1769 | |
1770 | sd += 4; |
1771 | rep = 1; |
1772 | } else { |
1773 | |
1774 | // If the rounding digits are null, 0{0,4} or 50{0,3}, check for an exact result. |
1775 | // If not, then there are further digits and m will be truthy. |
1776 | if (!+n || !+n.slice(1) && n.charAt(0) == '5') { |
1777 | |
1778 | // Truncate to the first rounding digit. |
1779 | finalise(r, e + 1, 1); |
1780 | m = !r.times(r).eq(x); |
1781 | } |
1782 | |
1783 | break; |
1784 | } |
1785 | } |
1786 | } |
1787 | |
1788 | external = true; |
1789 | |
1790 | return finalise(r, e, Ctor.rounding, m); |
1791 | }; |
1792 | |
1793 | |
1794 | /* |
1795 | * Return a new Decimal whose value is the tangent of the value in radians of this Decimal. |
1796 | * |
1797 | * Domain: [-Infinity, Infinity] |
1798 | * Range: [-Infinity, Infinity] |
1799 | * |
1800 | * tan(0) = 0 |
1801 | * tan(-0) = -0 |
1802 | * tan(Infinity) = NaN |
1803 | * tan(-Infinity) = NaN |
1804 | * tan(NaN) = NaN |
1805 | * |
1806 | */ |
1807 | P.tangent = P.tan = function () { |
1808 | var pr, rm, |
1809 | x = this, |
1810 | Ctor = x.constructor; |
1811 | |
1812 | if (!x.isFinite()) return new Ctor(NaN); |
1813 | if (x.isZero()) return new Ctor(x); |
1814 | |
1815 | pr = Ctor.precision; |
1816 | rm = Ctor.rounding; |
1817 | Ctor.precision = pr + 10; |
1818 | Ctor.rounding = 1; |
1819 | |
1820 | x = x.sin(); |
1821 | x.s = 1; |
1822 | x = divide(x, new Ctor(1).minus(x.times(x)).sqrt(), pr + 10, 0); |
1823 | |
1824 | Ctor.precision = pr; |
1825 | Ctor.rounding = rm; |
1826 | |
1827 | return finalise(quadrant == 2 || quadrant == 4 ? x.neg() : x, pr, rm, true); |
1828 | }; |
1829 | |
1830 | |
1831 | /* |
1832 | * n * 0 = 0 |
1833 | * n * N = N |
1834 | * n * I = I |
1835 | * 0 * n = 0 |
1836 | * 0 * 0 = 0 |
1837 | * 0 * N = N |
1838 | * 0 * I = N |
1839 | * N * n = N |
1840 | * N * 0 = N |
1841 | * N * N = N |
1842 | * N * I = N |
1843 | * I * n = I |
1844 | * I * 0 = N |
1845 | * I * N = N |
1846 | * I * I = I |
1847 | * |
1848 | * Return a new Decimal whose value is this Decimal times `y`, rounded to `precision` significant |
1849 | * digits using rounding mode `rounding`. |
1850 | * |
1851 | */ |
1852 | P.times = P.mul = function (y) { |
1853 | var carry, e, i, k, r, rL, t, xdL, ydL, |
1854 | x = this, |
1855 | Ctor = x.constructor, |
1856 | xd = x.d, |
1857 | yd = (y = new Ctor(y)).d; |
1858 | |
1859 | y.s *= x.s; |
1860 | |
1861 | // If either is NaN, ±Infinity or ±0... |
1862 | if (!xd || !xd[0] || !yd || !yd[0]) { |
1863 | |
1864 | return new Ctor(!y.s || xd && !xd[0] && !yd || yd && !yd[0] && !xd |
1865 | |
1866 | // Return NaN if either is NaN. |
1867 | // Return NaN if x is ±0 and y is ±Infinity, or y is ±0 and x is ±Infinity. |
1868 | ? NaN |
1869 | |
1870 | // Return ±Infinity if either is ±Infinity. |
1871 | // Return ±0 if either is ±0. |
1872 | : !xd || !yd ? y.s / 0 : y.s * 0); |
1873 | } |
1874 | |
1875 | e = mathfloor(x.e / LOG_BASE) + mathfloor(y.e / LOG_BASE); |
1876 | xdL = xd.length; |
1877 | ydL = yd.length; |
1878 | |
1879 | // Ensure xd points to the longer array. |
1880 | if (xdL < ydL) { |
1881 | r = xd; |
1882 | xd = yd; |
1883 | yd = r; |
1884 | rL = xdL; |
1885 | xdL = ydL; |
1886 | ydL = rL; |
1887 | } |
1888 | |
1889 | // Initialise the result array with zeros. |
1890 | r = []; |
1891 | rL = xdL + ydL; |
1892 | for (i = rL; i--;) r.push(0); |
1893 | |
1894 | // Multiply! |
1895 | for (i = ydL; --i >= 0;) { |
1896 | carry = 0; |
1897 | for (k = xdL + i; k > i;) { |
1898 | t = r[k] + yd[i] * xd[k - i - 1] + carry; |
1899 | r[k--] = t % BASE | 0; |
1900 | carry = t / BASE | 0; |
1901 | } |
1902 | |
1903 | r[k] = (r[k] + carry) % BASE | 0; |
1904 | } |
1905 | |
1906 | // Remove trailing zeros. |
1907 | for (; !r[--rL];) r.pop(); |
1908 | |
1909 | if (carry) ++e; |
1910 | else r.shift(); |
1911 | |
1912 | y.d = r; |
1913 | y.e = getBase10Exponent(r, e); |
1914 | |
1915 | return external ? finalise(y, Ctor.precision, Ctor.rounding) : y; |
1916 | }; |
1917 | |
1918 | |
1919 | /* |
1920 | * Return a string representing the value of this Decimal in base 2, round to `sd` significant |
1921 | * digits using rounding mode `rm`. |
1922 | * |
1923 | * If the optional `sd` argument is present then return binary exponential notation. |
1924 | * |
1925 | * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. |
1926 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. |
1927 | * |
1928 | */ |
1929 | P.toBinary = function (sd, rm) { |
1930 | return toStringBinary(this, 2, sd, rm); |
1931 | }; |
1932 | |
1933 | |
1934 | /* |
1935 | * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `dp` |
1936 | * decimal places using rounding mode `rm` or `rounding` if `rm` is omitted. |
1937 | * |
1938 | * If `dp` is omitted, return a new Decimal whose value is the value of this Decimal. |
1939 | * |
1940 | * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. |
1941 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. |
1942 | * |
1943 | */ |
1944 | P.toDecimalPlaces = P.toDP = function (dp, rm) { |
1945 | var x = this, |
1946 | Ctor = x.constructor; |
1947 | |
1948 | x = new Ctor(x); |
1949 | if (dp === void 0) return x; |
1950 | |
1951 | checkInt32(dp, 0, MAX_DIGITS); |
1952 | |
1953 | if (rm === void 0) rm = Ctor.rounding; |
1954 | else checkInt32(rm, 0, 8); |
1955 | |
1956 | return finalise(x, dp + x.e + 1, rm); |
1957 | }; |
1958 | |
1959 | |
1960 | /* |
1961 | * Return a string representing the value of this Decimal in exponential notation rounded to |
1962 | * `dp` fixed decimal places using rounding mode `rounding`. |
1963 | * |
1964 | * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. |
1965 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. |
1966 | * |
1967 | */ |
1968 | P.toExponential = function (dp, rm) { |
1969 | var str, |
1970 | x = this, |
1971 | Ctor = x.constructor; |
1972 | |
1973 | if (dp === void 0) { |
1974 | str = finiteToString(x, true); |
1975 | } else { |
1976 | checkInt32(dp, 0, MAX_DIGITS); |
1977 | |
1978 | if (rm === void 0) rm = Ctor.rounding; |
1979 | else checkInt32(rm, 0, 8); |
1980 | |
1981 | x = finalise(new Ctor(x), dp + 1, rm); |
1982 | str = finiteToString(x, true, dp + 1); |
1983 | } |
1984 | |
1985 | return x.isNeg() && !x.isZero() ? '-' + str : str; |
1986 | }; |
1987 | |
1988 | |
1989 | /* |
1990 | * Return a string representing the value of this Decimal in normal (fixed-point) notation to |
1991 | * `dp` fixed decimal places and rounded using rounding mode `rm` or `rounding` if `rm` is |
1992 | * omitted. |
1993 | * |
1994 | * As with JavaScript numbers, (-0).toFixed(0) is '0', but e.g. (-0.00001).toFixed(0) is '-0'. |
1995 | * |
1996 | * [dp] {number} Decimal places. Integer, 0 to MAX_DIGITS inclusive. |
1997 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. |
1998 | * |
1999 | * (-0).toFixed(0) is '0', but (-0.1).toFixed(0) is '-0'. |
2000 | * (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'. |
2001 | * (-0).toFixed(3) is '0.000'. |
2002 | * (-0.5).toFixed(0) is '-0'. |
2003 | * |
2004 | */ |
2005 | P.toFixed = function (dp, rm) { |
2006 | var str, y, |
2007 | x = this, |
2008 | Ctor = x.constructor; |
2009 | |
2010 | if (dp === void 0) { |
2011 | str = finiteToString(x); |
2012 | } else { |
2013 | checkInt32(dp, 0, MAX_DIGITS); |
2014 | |
2015 | if (rm === void 0) rm = Ctor.rounding; |
2016 | else checkInt32(rm, 0, 8); |
2017 | |
2018 | y = finalise(new Ctor(x), dp + x.e + 1, rm); |
2019 | str = finiteToString(y, false, dp + y.e + 1); |
2020 | } |
2021 | |
2022 | // To determine whether to add the minus sign look at the value before it was rounded, |
2023 | // i.e. look at `x` rather than `y`. |
2024 | return x.isNeg() && !x.isZero() ? '-' + str : str; |
2025 | }; |
2026 | |
2027 | |
2028 | /* |
2029 | * Return an array representing the value of this Decimal as a simple fraction with an integer |
2030 | * numerator and an integer denominator. |
2031 | * |
2032 | * The denominator will be a positive non-zero value less than or equal to the specified maximum |
2033 | * denominator. If a maximum denominator is not specified, the denominator will be the lowest |
2034 | * value necessary to represent the number exactly. |
2035 | * |
2036 | * [maxD] {number|string|Decimal} Maximum denominator. Integer >= 1 and < Infinity. |
2037 | * |
2038 | */ |
2039 | P.toFraction = function (maxD) { |
2040 | var d, d0, d1, d2, e, k, n, n0, n1, pr, q, r, |
2041 | x = this, |
2042 | xd = x.d, |
2043 | Ctor = x.constructor; |
2044 | |
2045 | if (!xd) return new Ctor(x); |
2046 | |
2047 | n1 = d0 = new Ctor(1); |
2048 | d1 = n0 = new Ctor(0); |
2049 | |
2050 | d = new Ctor(d1); |
2051 | e = d.e = getPrecision(xd) - x.e - 1; |
2052 | k = e % LOG_BASE; |
2053 | d.d[0] = mathpow(10, k < 0 ? LOG_BASE + k : k); |
2054 | |
2055 | if (maxD == null) { |
2056 | |
2057 | // d is 10**e, the minimum max-denominator needed. |
2058 | maxD = e > 0 ? d : n1; |
2059 | } else { |
2060 | n = new Ctor(maxD); |
2061 | if (!n.isInt() || n.lt(n1)) throw Error(invalidArgument + n); |
2062 | maxD = n.gt(d) ? (e > 0 ? d : n1) : n; |
2063 | } |
2064 | |
2065 | external = false; |
2066 | n = new Ctor(digitsToString(xd)); |
2067 | pr = Ctor.precision; |
2068 | Ctor.precision = e = xd.length * LOG_BASE * 2; |
2069 | |
2070 | for (;;) { |
2071 | q = divide(n, d, 0, 1, 1); |
2072 | d2 = d0.plus(q.times(d1)); |
2073 | if (d2.cmp(maxD) == 1) break; |
2074 | d0 = d1; |
2075 | d1 = d2; |
2076 | d2 = n1; |
2077 | n1 = n0.plus(q.times(d2)); |
2078 | n0 = d2; |
2079 | d2 = d; |
2080 | d = n.minus(q.times(d2)); |
2081 | n = d2; |
2082 | } |
2083 | |
2084 | d2 = divide(maxD.minus(d0), d1, 0, 1, 1); |
2085 | n0 = n0.plus(d2.times(n1)); |
2086 | d0 = d0.plus(d2.times(d1)); |
2087 | n0.s = n1.s = x.s; |
2088 | |
2089 | // Determine which fraction is closer to x, n0/d0 or n1/d1? |
2090 | r = divide(n1, d1, e, 1).minus(x).abs().cmp(divide(n0, d0, e, 1).minus(x).abs()) < 1 |
2091 | ? [n1, d1] : [n0, d0]; |
2092 | |
2093 | Ctor.precision = pr; |
2094 | external = true; |
2095 | |
2096 | return r; |
2097 | }; |
2098 | |
2099 | |
2100 | /* |
2101 | * Return a string representing the value of this Decimal in base 16, round to `sd` significant |
2102 | * digits using rounding mode `rm`. |
2103 | * |
2104 | * If the optional `sd` argument is present then return binary exponential notation. |
2105 | * |
2106 | * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. |
2107 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. |
2108 | * |
2109 | */ |
2110 | P.toHexadecimal = P.toHex = function (sd, rm) { |
2111 | return toStringBinary(this, 16, sd, rm); |
2112 | }; |
2113 | |
2114 | |
2115 | |
2116 | /* |
2117 | * Returns a new Decimal whose value is the nearest multiple of the magnitude of `y` to the value |
2118 | * of this Decimal. |
2119 | * |
2120 | * If the value of this Decimal is equidistant from two multiples of `y`, the rounding mode `rm`, |
2121 | * or `Decimal.rounding` if `rm` is omitted, determines the direction of the nearest multiple. |
2122 | * |
2123 | * In the context of this method, rounding mode 4 (ROUND_HALF_UP) is the same as rounding mode 0 |
2124 | * (ROUND_UP), and so on. |
2125 | * |
2126 | * The return value will always have the same sign as this Decimal, unless either this Decimal |
2127 | * or `y` is NaN, in which case the return value will be also be NaN. |
2128 | * |
2129 | * The return value is not affected by the value of `precision`. |
2130 | * |
2131 | * y {number|string|Decimal} The magnitude to round to a multiple of. |
2132 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. |
2133 | * |
2134 | * 'toNearest() rounding mode not an integer: {rm}' |
2135 | * 'toNearest() rounding mode out of range: {rm}' |
2136 | * |
2137 | */ |
2138 | P.toNearest = function (y, rm) { |
2139 | var x = this, |
2140 | Ctor = x.constructor; |
2141 | |
2142 | x = new Ctor(x); |
2143 | |
2144 | if (y == null) { |
2145 | |
2146 | // If x is not finite, return x. |
2147 | if (!x.d) return x; |
2148 | |
2149 | y = new Ctor(1); |
2150 | rm = Ctor.rounding; |
2151 | } else { |
2152 | y = new Ctor(y); |
2153 | if (rm === void 0) { |
2154 | rm = Ctor.rounding; |
2155 | } else { |
2156 | checkInt32(rm, 0, 8); |
2157 | } |
2158 | |
2159 | // If x is not finite, return x if y is not NaN, else NaN. |
2160 | if (!x.d) return y.s ? x : y; |
2161 | |
2162 | // If y is not finite, return Infinity with the sign of x if y is Infinity, else NaN. |
2163 | if (!y.d) { |
2164 | if (y.s) y.s = x.s; |
2165 | return y; |
2166 | } |
2167 | } |
2168 | |
2169 | // If y is not zero, calculate the nearest multiple of y to x. |
2170 | if (y.d[0]) { |
2171 | external = false; |
2172 | x = divide(x, y, 0, rm, 1).times(y); |
2173 | external = true; |
2174 | finalise(x); |
2175 | |
2176 | // If y is zero, return zero with the sign of x. |
2177 | } else { |
2178 | y.s = x.s; |
2179 | x = y; |
2180 | } |
2181 | |
2182 | return x; |
2183 | }; |
2184 | |
2185 | |
2186 | /* |
2187 | * Return the value of this Decimal converted to a number primitive. |
2188 | * Zero keeps its sign. |
2189 | * |
2190 | */ |
2191 | P.toNumber = function () { |
2192 | return +this; |
2193 | }; |
2194 | |
2195 | |
2196 | /* |
2197 | * Return a string representing the value of this Decimal in base 8, round to `sd` significant |
2198 | * digits using rounding mode `rm`. |
2199 | * |
2200 | * If the optional `sd` argument is present then return binary exponential notation. |
2201 | * |
2202 | * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. |
2203 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. |
2204 | * |
2205 | */ |
2206 | P.toOctal = function (sd, rm) { |
2207 | return toStringBinary(this, 8, sd, rm); |
2208 | }; |
2209 | |
2210 | |
2211 | /* |
2212 | * Return a new Decimal whose value is the value of this Decimal raised to the power `y`, rounded |
2213 | * to `precision` significant digits using rounding mode `rounding`. |
2214 | * |
2215 | * ECMAScript compliant. |
2216 | * |
2217 | * pow(x, NaN) = NaN |
2218 | * pow(x, ±0) = 1 |
2219 | |
2220 | * pow(NaN, non-zero) = NaN |
2221 | * pow(abs(x) > 1, +Infinity) = +Infinity |
2222 | * pow(abs(x) > 1, -Infinity) = +0 |
2223 | * pow(abs(x) == 1, ±Infinity) = NaN |
2224 | * pow(abs(x) < 1, +Infinity) = +0 |
2225 | * pow(abs(x) < 1, -Infinity) = +Infinity |
2226 | * pow(+Infinity, y > 0) = +Infinity |
2227 | * pow(+Infinity, y < 0) = +0 |
2228 | * pow(-Infinity, odd integer > 0) = -Infinity |
2229 | * pow(-Infinity, even integer > 0) = +Infinity |
2230 | * pow(-Infinity, odd integer < 0) = -0 |
2231 | * pow(-Infinity, even integer < 0) = +0 |
2232 | * pow(+0, y > 0) = +0 |
2233 | * pow(+0, y < 0) = +Infinity |
2234 | * pow(-0, odd integer > 0) = -0 |
2235 | * pow(-0, even integer > 0) = +0 |
2236 | * pow(-0, odd integer < 0) = -Infinity |
2237 | * pow(-0, even integer < 0) = +Infinity |
2238 | * pow(finite x < 0, finite non-integer) = NaN |
2239 | * |
2240 | * For non-integer or very large exponents pow(x, y) is calculated using |
2241 | * |
2242 | * x^y = exp(y*ln(x)) |
2243 | * |
2244 | * Assuming the first 15 rounding digits are each equally likely to be any digit 0-9, the |
2245 | * probability of an incorrectly rounded result |
2246 | * P([49]9{14} | [50]0{14}) = 2 * 0.2 * 10^-14 = 4e-15 = 1/2.5e+14 |
2247 | * i.e. 1 in 250,000,000,000,000 |
2248 | * |
2249 | * If a result is incorrectly rounded the maximum error will be 1 ulp (unit in last place). |
2250 | * |
2251 | * y {number|string|Decimal} The power to which to raise this Decimal. |
2252 | * |
2253 | */ |
2254 | P.toPower = P.pow = function (y) { |
2255 | var e, k, pr, r, rm, s, |
2256 | x = this, |
2257 | Ctor = x.constructor, |
2258 | yn = +(y = new Ctor(y)); |
2259 | |
2260 | // Either ±Infinity, NaN or ±0? |
2261 | if (!x.d || !y.d || !x.d[0] || !y.d[0]) return new Ctor(mathpow(+x, yn)); |
2262 | |
2263 | x = new Ctor(x); |
2264 | |
2265 | if (x.eq(1)) return x; |
2266 | |
2267 | pr = Ctor.precision; |
2268 | rm = Ctor.rounding; |
2269 | |
2270 | if (y.eq(1)) return finalise(x, pr, rm); |
2271 | |
2272 | // y exponent |
2273 | e = mathfloor(y.e / LOG_BASE); |
2274 | |
2275 | // If y is a small integer use the 'exponentiation by squaring' algorithm. |
2276 | if (e >= y.d.length - 1 && (k = yn < 0 ? -yn : yn) <= MAX_SAFE_INTEGER) { |
2277 | r = intPow(Ctor, x, k, pr); |
2278 | return y.s < 0 ? new Ctor(1).div(r) : finalise(r, pr, rm); |
2279 | } |
2280 | |
2281 | s = x.s; |
2282 | |
2283 | // if x is negative |
2284 | if (s < 0) { |
2285 | |
2286 | // if y is not an integer |
2287 | if (e < y.d.length - 1) return new Ctor(NaN); |
2288 | |
2289 | // Result is positive if x is negative and the last digit of integer y is even. |
2290 | if ((y.d[e] & 1) == 0) s = 1; |
2291 | |
2292 | // if x.eq(-1) |
2293 | if (x.e == 0 && x.d[0] == 1 && x.d.length == 1) { |
2294 | x.s = s; |
2295 | return x; |
2296 | } |
2297 | } |
2298 | |
2299 | // Estimate result exponent. |
2300 | // x^y = 10^e, where e = y * log10(x) |
2301 | // log10(x) = log10(x_significand) + x_exponent |
2302 | // log10(x_significand) = ln(x_significand) / ln(10) |
2303 | k = mathpow(+x, yn); |
2304 | e = k == 0 || !isFinite(k) |
2305 | ? mathfloor(yn * (Math.log('0.' + digitsToString(x.d)) / Math.LN10 + x.e + 1)) |
2306 | : new Ctor(k + '').e; |
2307 | |
2308 | // Exponent estimate may be incorrect e.g. x: 0.999999999999999999, y: 2.29, e: 0, r.e: -1. |
2309 | |
2310 | // Overflow/underflow? |
2311 | if (e > Ctor.maxE + 1 || e < Ctor.minE - 1) return new Ctor(e > 0 ? s / 0 : 0); |
2312 | |
2313 | external = false; |
2314 | Ctor.rounding = x.s = 1; |
2315 | |
2316 | // Estimate the extra guard digits needed to ensure five correct rounding digits from |
2317 | // naturalLogarithm(x). Example of failure without these extra digits (precision: 10): |
2318 | // new Decimal(2.32456).pow('2087987436534566.46411') |
2319 | // should be 1.162377823e+764914905173815, but is 1.162355823e+764914905173815 |
2320 | k = Math.min(12, (e + '').length); |
2321 | |
2322 | // r = x^y = exp(y*ln(x)) |
2323 | r = naturalExponential(y.times(naturalLogarithm(x, pr + k)), pr); |
2324 | |
2325 | // r may be Infinity, e.g. (0.9999999999999999).pow(-1e+40) |
2326 | if (r.d) { |
2327 | |
2328 | // Truncate to the required precision plus five rounding digits. |
2329 | r = finalise(r, pr + 5, 1); |
2330 | |
2331 | // If the rounding digits are [49]9999 or [50]0000 increase the precision by 10 and recalculate |
2332 | // the result. |
2333 | if (checkRoundingDigits(r.d, pr, rm)) { |
2334 | e = pr + 10; |
2335 | |
2336 | // Truncate to the increased precision plus five rounding digits. |
2337 | r = finalise(naturalExponential(y.times(naturalLogarithm(x, e + k)), e), e + 5, 1); |
2338 | |
2339 | // Check for 14 nines from the 2nd rounding digit (the first rounding digit may be 4 or 9). |
2340 | if (+digitsToString(r.d).slice(pr + 1, pr + 15) + 1 == 1e14) { |
2341 | r = finalise(r, pr + 1, 0); |
2342 | } |
2343 | } |
2344 | } |
2345 | |
2346 | r.s = s; |
2347 | external = true; |
2348 | Ctor.rounding = rm; |
2349 | |
2350 | return finalise(r, pr, rm); |
2351 | }; |
2352 | |
2353 | |
2354 | /* |
2355 | * Return a string representing the value of this Decimal rounded to `sd` significant digits |
2356 | * using rounding mode `rounding`. |
2357 | * |
2358 | * Return exponential notation if `sd` is less than the number of digits necessary to represent |
2359 | * the integer part of the value in normal notation. |
2360 | * |
2361 | * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. |
2362 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. |
2363 | * |
2364 | */ |
2365 | P.toPrecision = function (sd, rm) { |
2366 | var str, |
2367 | x = this, |
2368 | Ctor = x.constructor; |
2369 | |
2370 | if (sd === void 0) { |
2371 | str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos); |
2372 | } else { |
2373 | checkInt32(sd, 1, MAX_DIGITS); |
2374 | |
2375 | if (rm === void 0) rm = Ctor.rounding; |
2376 | else checkInt32(rm, 0, 8); |
2377 | |
2378 | x = finalise(new Ctor(x), sd, rm); |
2379 | str = finiteToString(x, sd <= x.e || x.e <= Ctor.toExpNeg, sd); |
2380 | } |
2381 | |
2382 | return x.isNeg() && !x.isZero() ? '-' + str : str; |
2383 | }; |
2384 | |
2385 | |
2386 | /* |
2387 | * Return a new Decimal whose value is the value of this Decimal rounded to a maximum of `sd` |
2388 | * significant digits using rounding mode `rm`, or to `precision` and `rounding` respectively if |
2389 | * omitted. |
2390 | * |
2391 | * [sd] {number} Significant digits. Integer, 1 to MAX_DIGITS inclusive. |
2392 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive. |
2393 | * |
2394 | * 'toSD() digits out of range: {sd}' |
2395 | * 'toSD() digits not an integer: {sd}' |
2396 | * 'toSD() rounding mode not an integer: {rm}' |
2397 | * 'toSD() rounding mode out of range: {rm}' |
2398 | * |
2399 | */ |
2400 | P.toSignificantDigits = P.toSD = function (sd, rm) { |
2401 | var x = this, |
2402 | Ctor = x.constructor; |
2403 | |
2404 | if (sd === void 0) { |
2405 | sd = Ctor.precision; |
2406 | rm = Ctor.rounding; |
2407 | } else { |
2408 | checkInt32(sd, 1, MAX_DIGITS); |
2409 | |
2410 | if (rm === void 0) rm = Ctor.rounding; |
2411 | else checkInt32(rm, 0, 8); |
2412 | } |
2413 | |
2414 | return finalise(new Ctor(x), sd, rm); |
2415 | }; |
2416 | |
2417 | |
2418 | /* |
2419 | * Return a string representing the value of this Decimal. |
2420 | * |
2421 | * Return exponential notation if this Decimal has a positive exponent equal to or greater than |
2422 | * `toExpPos`, or a negative exponent equal to or less than `toExpNeg`. |
2423 | * |
2424 | */ |
2425 | P.toString = function () { |
2426 | var x = this, |
2427 | Ctor = x.constructor, |
2428 | str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos); |
2429 | |
2430 | return x.isNeg() && !x.isZero() ? '-' + str : str; |
2431 | }; |
2432 | |
2433 | |
2434 | /* |
2435 | * Return a new Decimal whose value is the value of this Decimal truncated to a whole number. |
2436 | * |
2437 | */ |
2438 | P.truncated = P.trunc = function () { |
2439 | return finalise(new this.constructor(this), this.e + 1, 1); |
2440 | }; |
2441 | |
2442 | |
2443 | /* |
2444 | * Return a string representing the value of this Decimal. |
2445 | * Unlike `toString`, negative zero will include the minus sign. |
2446 | * |
2447 | */ |
2448 | P.valueOf = P.toJSON = function () { |
2449 | var x = this, |
2450 | Ctor = x.constructor, |
2451 | str = finiteToString(x, x.e <= Ctor.toExpNeg || x.e >= Ctor.toExpPos); |
2452 | |
2453 | return x.isNeg() ? '-' + str : str; |
2454 | }; |
2455 | |
2456 | |
2457 | /* |
2458 | // Add aliases to match BigDecimal method names. |
2459 | // P.add = P.plus; |
2460 | P.subtract = P.minus; |
2461 | P.multiply = P.times; |
2462 | P.divide = P.div; |
2463 | P.remainder = P.mod; |
2464 | P.compareTo = P.cmp; |
2465 | P.negate = P.neg; |
2466 | */ |
2467 | |
2468 | |
2469 | // Helper functions for Decimal.prototype (P) and/or Decimal methods, and their callers. |
2470 | |
2471 | |
2472 | /* |
2473 | * digitsToString P.cubeRoot, P.logarithm, P.squareRoot, P.toFraction, P.toPower, |
2474 | * finiteToString, naturalExponential, naturalLogarithm |
2475 | * checkInt32 P.toDecimalPlaces, P.toExponential, P.toFixed, P.toNearest, |
2476 | * P.toPrecision, P.toSignificantDigits, toStringBinary, random |
2477 | * checkRoundingDigits P.logarithm, P.toPower, naturalExponential, naturalLogarithm |
2478 | * convertBase toStringBinary, parseOther |
2479 | * cos P.cos |
2480 | * divide P.atanh, P.cubeRoot, P.dividedBy, P.dividedToIntegerBy, |
2481 | * P.logarithm, P.modulo, P.squareRoot, P.tan, P.tanh, P.toFraction, |
2482 | * P.toNearest, toStringBinary, naturalExponential, naturalLogarithm, |
2483 | * taylorSeries, atan2, parseOther |
2484 | * finalise P.absoluteValue, P.atan, P.atanh, P.ceil, P.cos, P.cosh, |
2485 | * P.cubeRoot, P.dividedToIntegerBy, P.floor, P.logarithm, P.minus, |
2486 | * P.modulo, P.negated, P.plus, P.round, P.sin, P.sinh, P.squareRoot, |
2487 | * P.tan, P.times, P.toDecimalPlaces, P.toExponential, P.toFixed, |
2488 | * P.toNearest, P.toPower, P.toPrecision, P.toSignificantDigits, |
2489 | * P.truncated, divide, getLn10, getPi, naturalExponential, |
2490 | * naturalLogarithm, ceil, floor, round, trunc |
2491 | * finiteToString P.toExponential, P.toFixed, P.toPrecision, P.toString, P.valueOf, |
2492 | * toStringBinary |
2493 | * getBase10Exponent P.minus, P.plus, P.times, parseOther |
2494 | * getLn10 P.logarithm, naturalLogarithm |
2495 | * getPi P.acos, P.asin, P.atan, toLessThanHalfPi, atan2 |
2496 | * getPrecision P.precision, P.toFraction |
2497 | * getZeroString digitsToString, finiteToString |
2498 | * intPow P.toPower, parseOther |
2499 | * isOdd toLessThanHalfPi |
2500 | * maxOrMin max, min |
2501 | * naturalExponential P.naturalExponential, P.toPower |
2502 | * naturalLogarithm P.acosh, P.asinh, P.atanh, P.logarithm, P.naturalLogarithm, |
2503 | * P.toPower, naturalExponential |
2504 | * nonFiniteToString finiteToString, toStringBinary |
2505 | * parseDecimal Decimal |
2506 | * parseOther Decimal |
2507 | * sin P.sin |
2508 | * taylorSeries P.cosh, P.sinh, cos, sin |
2509 | * toLessThanHalfPi P.cos, P.sin |
2510 | * toStringBinary P.toBinary, P.toHexadecimal, P.toOctal |
2511 | * truncate intPow |
2512 | * |
2513 | * Throws: P.logarithm, P.precision, P.toFraction, checkInt32, getLn10, getPi, |
2514 | * naturalLogarithm, config, parseOther, random, Decimal |
2515 | */ |
2516 | |
2517 | |
2518 | function digitsToString(d) { |
2519 | var i, k, ws, |
2520 | indexOfLastWord = d.length - 1, |
2521 | str = '', |
2522 | w = d[0]; |
2523 | |
2524 | if (indexOfLastWord > 0) { |
2525 | str += w; |
2526 | for (i = 1; i < indexOfLastWord; i++) { |
2527 | ws = d[i] + ''; |
2528 | k = LOG_BASE - ws.length; |
2529 | if (k) str += getZeroString(k); |
2530 | str += ws; |
2531 | } |
2532 | |
2533 | w = d[i]; |
2534 | ws = w + ''; |
2535 | k = LOG_BASE - ws.length; |
2536 | if (k) str += getZeroString(k); |
2537 | } else if (w === 0) { |
2538 | return '0'; |
2539 | } |
2540 | |
2541 | // Remove trailing zeros of last w. |
2542 | for (; w % 10 === 0;) w /= 10; |
2543 | |
2544 | return str + w; |
2545 | } |
2546 | |
2547 | |
2548 | function checkInt32(i, min, max) { |
2549 | if (i !== ~~i || i < min || i > max) { |
2550 | throw Error(invalidArgument + i); |
2551 | } |
2552 | } |
2553 | |
2554 | |
2555 | /* |
2556 | * Check 5 rounding digits if `repeating` is null, 4 otherwise. |
2557 | * `repeating == null` if caller is `log` or `pow`, |
2558 | * `repeating != null` if caller is `naturalLogarithm` or `naturalExponential`. |
2559 | */ |
2560 | function checkRoundingDigits(d, i, rm, repeating) { |
2561 | var di, k, r, rd; |
2562 | |
2563 | // Get the length of the first word of the array d. |
2564 | for (k = d[0]; k >= 10; k /= 10) --i; |
2565 | |
2566 | // Is the rounding digit in the first word of d? |
2567 | if (--i < 0) { |
2568 | i += LOG_BASE; |
2569 | di = 0; |
2570 | } else { |
2571 | di = Math.ceil((i + 1) / LOG_BASE); |
2572 | i %= LOG_BASE; |
2573 | } |
2574 | |
2575 | // i is the index (0 - 6) of the rounding digit. |
2576 | // E.g. if within the word 3487563 the first rounding digit is 5, |
2577 | // then i = 4, k = 1000, rd = 3487563 % 1000 = 563 |
2578 | k = mathpow(10, LOG_BASE - i); |
2579 | rd = d[di] % k | 0; |
2580 | |
2581 | if (repeating == null) { |
2582 | if (i < 3) { |
2583 | if (i == 0) rd = rd / 100 | 0; |
2584 | else if (i == 1) rd = rd / 10 | 0; |
2585 | r = rm < 4 && rd == 99999 || rm > 3 && rd == 49999 || rd == 50000 || rd == 0; |
2586 | } else { |
2587 | r = (rm < 4 && rd + 1 == k || rm > 3 && rd + 1 == k / 2) && |
2588 | (d[di + 1] / k / 100 | 0) == mathpow(10, i - 2) - 1 || |
2589 | (rd == k / 2 || rd == 0) && (d[di + 1] / k / 100 | 0) == 0; |
2590 | } |
2591 | } else { |
2592 | if (i < 4) { |
2593 | if (i == 0) rd = rd / 1000 | 0; |
2594 | else if (i == 1) rd = rd / 100 | 0; |
2595 | else if (i == 2) rd = rd / 10 | 0; |
2596 | r = (repeating || rm < 4) && rd == 9999 || !repeating && rm > 3 && rd == 4999; |
2597 | } else { |
2598 | r = ((repeating || rm < 4) && rd + 1 == k || |
2599 | (!repeating && rm > 3) && rd + 1 == k / 2) && |
2600 | (d[di + 1] / k / 1000 | 0) == mathpow(10, i - 3) - 1; |
2601 | } |
2602 | } |
2603 | |
2604 | return r; |
2605 | } |
2606 | |
2607 | |
2608 | // Convert string of `baseIn` to an array of numbers of `baseOut`. |
2609 | // Eg. convertBase('255', 10, 16) returns [15, 15]. |
2610 | // Eg. convertBase('ff', 16, 10) returns [2, 5, 5]. |
2611 | function convertBase(str, baseIn, baseOut) { |
2612 | var j, |
2613 | arr = [0], |
2614 | arrL, |
2615 | i = 0, |
2616 | strL = str.length; |
2617 | |
2618 | for (; i < strL;) { |
2619 | for (arrL = arr.length; arrL--;) arr[arrL] *= baseIn; |
2620 | arr[0] += NUMERALS.indexOf(str.charAt(i++)); |
2621 | for (j = 0; j < arr.length; j++) { |
2622 | if (arr[j] > baseOut - 1) { |
2623 | if (arr[j + 1] === void 0) arr[j + 1] = 0; |
2624 | arr[j + 1] += arr[j] / baseOut | 0; |
2625 | arr[j] %= baseOut; |
2626 | } |
2627 | } |
2628 | } |
2629 | |
2630 | return arr.reverse(); |
2631 | } |
2632 | |
2633 | |
2634 | /* |
2635 | * cos(x) = 1 - x^2/2! + x^4/4! - ... |
2636 | * |x| < pi/2 |
2637 | * |
2638 | */ |
2639 | function cosine(Ctor, x) { |
2640 | var k, y, |
2641 | len = x.d.length; |
2642 | |
2643 | // Argument reduction: cos(4x) = 8*(cos^4(x) - cos^2(x)) + 1 |
2644 | // i.e. cos(x) = 8*(cos^4(x/4) - cos^2(x/4)) + 1 |
2645 | |
2646 | // Estimate the optimum number of times to use the argument reduction. |
2647 | if (len < 32) { |
2648 | k = Math.ceil(len / 3); |
2649 | y = Math.pow(4, -k).toString(); |
2650 | } else { |
2651 | k = 16; |
2652 | y = '2.3283064365386962890625e-10'; |
2653 | } |
2654 | |
2655 | Ctor.precision += k; |
2656 | |
2657 | x = taylorSeries(Ctor, 1, x.times(y), new Ctor(1)); |
2658 | |
2659 | // Reverse argument reduction |
2660 | for (var i = k; i--;) { |
2661 | var cos2x = x.times(x); |
2662 | x = cos2x.times(cos2x).minus(cos2x).times(8).plus(1); |
2663 | } |
2664 | |
2665 | Ctor.precision -= k; |
2666 | |
2667 | return x; |
2668 | } |
2669 | |
2670 | |
2671 | /* |
2672 | * Perform division in the specified base. |
2673 | */ |
2674 | var divide = (function () { |
2675 | |
2676 | // Assumes non-zero x and k, and hence non-zero result. |
2677 | function multiplyInteger(x, k, base) { |
2678 | var temp, |
2679 | carry = 0, |
2680 | i = x.length; |
2681 | |
2682 | for (x = x.slice(); i--;) { |
2683 | temp = x[i] * k + carry; |
2684 | x[i] = temp % base | 0; |
2685 | carry = temp / base | 0; |
2686 | } |
2687 | |
2688 | if (carry) x.unshift(carry); |
2689 | |
2690 | return x; |
2691 | } |
2692 | |
2693 | function compare(a, b, aL, bL) { |
2694 | var i, r; |
2695 | |
2696 | if (aL != bL) { |
2697 | r = aL > bL ? 1 : -1; |
2698 | } else { |
2699 | for (i = r = 0; i < aL; i++) { |
2700 | if (a[i] != b[i]) { |
2701 | r = a[i] > b[i] ? 1 : -1; |
2702 | break; |
2703 | } |
2704 | } |
2705 | } |
2706 | |
2707 | return r; |
2708 | } |
2709 | |
2710 | function subtract(a, b, aL, base) { |
2711 | var i = 0; |
2712 | |
2713 | // Subtract b from a. |
2714 | for (; aL--;) { |
2715 | a[aL] -= i; |
2716 | i = a[aL] < b[aL] ? 1 : 0; |
2717 | a[aL] = i * base + a[aL] - b[aL]; |
2718 | } |
2719 | |
2720 | // Remove leading zeros. |
2721 | for (; !a[0] && a.length > 1;) a.shift(); |
2722 | } |
2723 | |
2724 | return function (x, y, pr, rm, dp, base) { |
2725 | var cmp, e, i, k, logBase, more, prod, prodL, q, qd, rem, remL, rem0, sd, t, xi, xL, yd0, |
2726 | yL, yz, |
2727 | Ctor = x.constructor, |
2728 | sign = x.s == y.s ? 1 : -1, |
2729 | xd = x.d, |
2730 | yd = y.d; |
2731 | |
2732 | // Either NaN, Infinity or 0? |
2733 | if (!xd || !xd[0] || !yd || !yd[0]) { |
2734 | |
2735 | return new Ctor(// Return NaN if either NaN, or both Infinity or 0. |
2736 | !x.s || !y.s || (xd ? yd && xd[0] == yd[0] : !yd) ? NaN : |
2737 | |
2738 | // Return ±0 if x is 0 or y is ±Infinity, or return ±Infinity as y is 0. |
2739 | xd && xd[0] == 0 || !yd ? sign * 0 : sign / 0); |
2740 | } |
2741 | |
2742 | if (base) { |
2743 | logBase = 1; |
2744 | e = x.e - y.e; |
2745 | } else { |
2746 | base = BASE; |
2747 | logBase = LOG_BASE; |
2748 | e = mathfloor(x.e / logBase) - mathfloor(y.e / logBase); |
2749 | } |
2750 | |
2751 | yL = yd.length; |
2752 | xL = xd.length; |
2753 | q = new Ctor(sign); |
2754 | qd = q.d = []; |
2755 | |
2756 | // Result exponent may be one less than e. |
2757 | // The digit array of a Decimal from toStringBinary may have trailing zeros. |
2758 | for (i = 0; yd[i] == (xd[i] || 0); i++); |
2759 | |
2760 | if (yd[i] > (xd[i] || 0)) e--; |
2761 | |
2762 | if (pr == null) { |
2763 | sd = pr = Ctor.precision; |
2764 | rm = Ctor.rounding; |
2765 | } else if (dp) { |
2766 | sd = pr + (x.e - y.e) + 1; |
2767 | } else { |
2768 | sd = pr; |
2769 | } |
2770 | |
2771 | if (sd < 0) { |
2772 | qd.push(1); |
2773 | more = true; |
2774 | } else { |
2775 | |
2776 | // Convert precision in number of base 10 digits to base 1e7 digits. |
2777 | sd = sd / logBase + 2 | 0; |
2778 | i = 0; |
2779 | |
2780 | // divisor < 1e7 |
2781 | if (yL == 1) { |
2782 | k = 0; |
2783 | yd = yd[0]; |
2784 | sd++; |
2785 | |
2786 | // k is the carry. |
2787 | for (; (i < xL || k) && sd--; i++) { |
2788 | t = k * base + (xd[i] || 0); |
2789 | qd[i] = t / yd | 0; |
2790 | k = t % yd | 0; |
2791 | } |
2792 | |
2793 | more = k || i < xL; |
2794 | |
2795 | // divisor >= 1e7 |
2796 | } else { |
2797 | |
2798 | // Normalise xd and yd so highest order digit of yd is >= base/2 |
2799 | k = base / (yd[0] + 1) | 0; |
2800 | |
2801 | if (k > 1) { |
2802 | yd = multiplyInteger(yd, k, base); |
2803 | xd = multiplyInteger(xd, k, base); |
2804 | yL = yd.length; |
2805 | xL = xd.length; |
2806 | } |
2807 | |
2808 | xi = yL; |
2809 | rem = xd.slice(0, yL); |
2810 | remL = rem.length; |
2811 | |
2812 | // Add zeros to make remainder as long as divisor. |
2813 | for (; remL < yL;) rem[remL++] = 0; |
2814 | |
2815 | yz = yd.slice(); |
2816 | yz.unshift(0); |
2817 | yd0 = yd[0]; |
2818 | |
2819 | if (yd[1] >= base / 2) ++yd0; |
2820 | |
2821 | do { |
2822 | k = 0; |
2823 | |
2824 | // Compare divisor and remainder. |
2825 | cmp = compare(yd, rem, yL, remL); |
2826 | |
2827 | // If divisor < remainder. |
2828 | if (cmp < 0) { |
2829 | |
2830 | // Calculate trial digit, k. |
2831 | rem0 = rem[0]; |
2832 | if (yL != remL) rem0 = rem0 * base + (rem[1] || 0); |
2833 | |
2834 | // k will be how many times the divisor goes into the current remainder. |
2835 | k = rem0 / yd0 | 0; |
2836 | |
2837 | // Algorithm: |
2838 | // 1. product = divisor * trial digit (k) |
2839 | // 2. if product > remainder: product -= divisor, k-- |
2840 | // 3. remainder -= product |
2841 | // 4. if product was < remainder at 2: |
2842 | // 5. compare new remainder and divisor |
2843 | // 6. If remainder > divisor: remainder -= divisor, k++ |
2844 | |
2845 | if (k > 1) { |
2846 | if (k >= base) k = base - 1; |
2847 | |
2848 | // product = divisor * trial digit. |
2849 | prod = multiplyInteger(yd, k, base); |
2850 | prodL = prod.length; |
2851 | remL = rem.length; |
2852 | |
2853 | // Compare product and remainder. |
2854 | cmp = compare(prod, rem, prodL, remL); |
2855 | |
2856 | // product > remainder. |
2857 | if (cmp == 1) { |
2858 | k--; |
2859 | |
2860 | // Subtract divisor from product. |
2861 | subtract(prod, yL < prodL ? yz : yd, prodL, base); |
2862 | } |
2863 | } else { |
2864 | |
2865 | // cmp is -1. |
2866 | // If k is 0, there is no need to compare yd and rem again below, so change cmp to 1 |
2867 | // to avoid it. If k is 1 there is a need to compare yd and rem again below. |
2868 | if (k == 0) cmp = k = 1; |
2869 | prod = yd.slice(); |
2870 | } |
2871 | |
2872 | prodL = prod.length; |
2873 | if (prodL < remL) prod.unshift(0); |
2874 | |
2875 | // Subtract product from remainder. |
2876 | subtract(rem, prod, remL, base); |
2877 | |
2878 | // If product was < previous remainder. |
2879 | if (cmp == -1) { |
2880 | remL = rem.length; |
2881 | |
2882 | // Compare divisor and new remainder. |
2883 | cmp = compare(yd, rem, yL, remL); |
2884 | |
2885 | // If divisor < new remainder, subtract divisor from remainder. |
2886 | if (cmp < 1) { |
2887 | k++; |
2888 | |
2889 | // Subtract divisor from remainder. |
2890 | subtract(rem, yL < remL ? yz : yd, remL, base); |
2891 | } |
2892 | } |
2893 | |
2894 | remL = rem.length; |
2895 | } else if (cmp === 0) { |
2896 | k++; |
2897 | rem = [0]; |
2898 | } // if cmp === 1, k will be 0 |
2899 | |
2900 | // Add the next digit, k, to the result array. |
2901 | qd[i++] = k; |
2902 | |
2903 | // Update the remainder. |
2904 | if (cmp && rem[0]) { |
2905 | rem[remL++] = xd[xi] || 0; |
2906 | } else { |
2907 | rem = [xd[xi]]; |
2908 | remL = 1; |
2909 | } |
2910 | |
2911 | } while ((xi++ < xL || rem[0] !== void 0) && sd--); |
2912 | |
2913 | more = rem[0] !== void 0; |
2914 | } |
2915 | |
2916 | // Leading zero? |
2917 | if (!qd[0]) qd.shift(); |
2918 | } |
2919 | |
2920 | // logBase is 1 when divide is being used for base conversion. |
2921 | if (logBase == 1) { |
2922 | q.e = e; |
2923 | inexact = more; |
2924 | } else { |
2925 | |
2926 | // To calculate q.e, first get the number of digits of qd[0]. |
2927 | for (i = 1, k = qd[0]; k >= 10; k /= 10) i++; |
2928 | q.e = i + e * logBase - 1; |
2929 | |
2930 | finalise(q, dp ? pr + q.e + 1 : pr, rm, more); |
2931 | } |
2932 | |
2933 | return q; |
2934 | }; |
2935 | })(); |
2936 | |
2937 | |
2938 | /* |
2939 | * Round `x` to `sd` significant digits using rounding mode `rm`. |
2940 | * Check for over/under-flow. |
2941 | */ |
2942 | function finalise(x, sd, rm, isTruncated) { |
2943 | var digits, i, j, k, rd, roundUp, w, xd, xdi, |
2944 | Ctor = x.constructor; |
2945 | |
2946 | // Don't round if sd is null or undefined. |
2947 | out: if (sd != null) { |
2948 | xd = x.d; |
2949 | |
2950 | // Infinity/NaN. |
2951 | if (!xd) return x; |
2952 | |
2953 | // rd: the rounding digit, i.e. the digit after the digit that may be rounded up. |
2954 | // w: the word of xd containing rd, a base 1e7 number. |
2955 | // xdi: the index of w within xd. |
2956 | // digits: the number of digits of w. |
2957 | // i: what would be the index of rd within w if all the numbers were 7 digits long (i.e. if |
2958 | // they had leading zeros) |
2959 | // j: if > 0, the actual index of rd within w (if < 0, rd is a leading zero). |
2960 | |
2961 | // Get the length of the first word of the digits array xd. |
2962 | for (digits = 1, k = xd[0]; k >= 10; k /= 10) digits++; |
2963 | i = sd - digits; |
2964 | |
2965 | // Is the rounding digit in the first word of xd? |
2966 | if (i < 0) { |
2967 | i += LOG_BASE; |
2968 | j = sd; |
2969 | w = xd[xdi = 0]; |
2970 | |
2971 | // Get the rounding digit at index j of w. |
2972 | rd = w / mathpow(10, digits - j - 1) % 10 | 0; |
2973 | } else { |
2974 | xdi = Math.ceil((i + 1) / LOG_BASE); |
2975 | k = xd.length; |
2976 | if (xdi >= k) { |
2977 | if (isTruncated) { |
2978 | |
2979 | // Needed by `naturalExponential`, `naturalLogarithm` and `squareRoot`. |
2980 | for (; k++ <= xdi;) xd.push(0); |
2981 | w = rd = 0; |
2982 | digits = 1; |
2983 | i %= LOG_BASE; |
2984 | j = i - LOG_BASE + 1; |
2985 | } else { |
2986 | break out; |
2987 | } |
2988 | } else { |
2989 | w = k = xd[xdi]; |
2990 | |
2991 | // Get the number of digits of w. |
2992 | for (digits = 1; k >= 10; k /= 10) digits++; |
2993 | |
2994 | // Get the index of rd within w. |
2995 | i %= LOG_BASE; |
2996 | |
2997 | // Get the index of rd within w, adjusted for leading zeros. |
2998 | // The number of leading zeros of w is given by LOG_BASE - digits. |
2999 | j = i - LOG_BASE + digits; |
3000 | |
3001 | // Get the rounding digit at index j of w. |
3002 | rd = j < 0 ? 0 : w / mathpow(10, digits - j - 1) % 10 | 0; |
3003 | } |
3004 | } |
3005 | |
3006 | // Are there any non-zero digits after the rounding digit? |
3007 | isTruncated = isTruncated || sd < 0 || |
3008 | xd[xdi + 1] !== void 0 || (j < 0 ? w : w % mathpow(10, digits - j - 1)); |
3009 | |
3010 | // The expression `w % mathpow(10, digits - j - 1)` returns all the digits of w to the right |
3011 | // of the digit at (left-to-right) index j, e.g. if w is 908714 and j is 2, the expression |
3012 | // will give 714. |
3013 | |
3014 | roundUp = rm < 4 |
3015 | ? (rd || isTruncated) && (rm == 0 || rm == (x.s < 0 ? 3 : 2)) |
3016 | : rd > 5 || rd == 5 && (rm == 4 || isTruncated || rm == 6 && |
3017 | |
3018 | // Check whether the digit to the left of the rounding digit is odd. |
3019 | ((i > 0 ? j > 0 ? w / mathpow(10, digits - j) : 0 : xd[xdi - 1]) % 10) & 1 || |
3020 | rm == (x.s < 0 ? 8 : 7)); |
3021 | |
3022 | if (sd < 1 || !xd[0]) { |
3023 | xd.length = 0; |
3024 | if (roundUp) { |
3025 | |
3026 | // Convert sd to decimal places. |
3027 | sd -= x.e + 1; |
3028 | |
3029 | // 1, 0.1, 0.01, 0.001, 0.0001 etc. |
3030 | xd[0] = mathpow(10, (LOG_BASE - sd % LOG_BASE) % LOG_BASE); |
3031 | x.e = -sd || 0; |
3032 | } else { |
3033 | |
3034 | // Zero. |
3035 | xd[0] = x.e = 0; |
3036 | } |
3037 | |
3038 | return x; |
3039 | } |
3040 | |
3041 | // Remove excess digits. |
3042 | if (i == 0) { |
3043 | xd.length = xdi; |
3044 | k = 1; |
3045 | xdi--; |
3046 | } else { |
3047 | xd.length = xdi + 1; |
3048 | k = mathpow(10, LOG_BASE - i); |
3049 | |
3050 | // E.g. 56700 becomes 56000 if 7 is the rounding digit. |
3051 | // j > 0 means i > number of leading zeros of w. |
3052 | xd[xdi] = j > 0 ? (w / mathpow(10, digits - j) % mathpow(10, j) | 0) * k : 0; |
3053 | } |
3054 | |
3055 | if (roundUp) { |
3056 | for (;;) { |
3057 | |
3058 | // Is the digit to be rounded up in the first word of xd? |
3059 | if (xdi == 0) { |
3060 | |
3061 | // i will be the length of xd[0] before k is added. |
3062 | for (i = 1, j = xd[0]; j >= 10; j /= 10) i++; |
3063 | j = xd[0] += k; |
3064 | for (k = 1; j >= 10; j /= 10) k++; |
3065 | |
3066 | // if i != k the length has increased. |
3067 | if (i != k) { |
3068 | x.e++; |
3069 | if (xd[0] == BASE) xd[0] = 1; |
3070 | } |
3071 | |
3072 | break; |
3073 | } else { |
3074 | xd[xdi] += k; |
3075 | if (xd[xdi] != BASE) break; |
3076 | xd[xdi--] = 0; |
3077 | k = 1; |
3078 | } |
3079 | } |
3080 | } |
3081 | |
3082 | // Remove trailing zeros. |
3083 | for (i = xd.length; xd[--i] === 0;) xd.pop(); |
3084 | } |
3085 | |
3086 | if (external) { |
3087 | |
3088 | // Overflow? |
3089 | if (x.e > Ctor.maxE) { |
3090 | |
3091 | // Infinity. |
3092 | x.d = null; |
3093 | x.e = NaN; |
3094 | |
3095 | // Underflow? |
3096 | } else if (x.e < Ctor.minE) { |
3097 | |
3098 | // Zero. |
3099 | x.e = 0; |
3100 | x.d = [0]; |
3101 | // Ctor.underflow = true; |
3102 | } // else Ctor.underflow = false; |
3103 | } |
3104 | |
3105 | return x; |
3106 | } |
3107 | |
3108 | |
3109 | function finiteToString(x, isExp, sd) { |
3110 | if (!x.isFinite()) return nonFiniteToString(x); |
3111 | var k, |
3112 | e = x.e, |
3113 | str = digitsToString(x.d), |
3114 | len = str.length; |
3115 | |
3116 | if (isExp) { |
3117 | if (sd && (k = sd - len) > 0) { |
3118 | str = str.charAt(0) + '.' + str.slice(1) + getZeroString(k); |
3119 | } else if (len > 1) { |
3120 | str = str.charAt(0) + '.' + str.slice(1); |
3121 | } |
3122 | |
3123 | str = str + (x.e < 0 ? 'e' : 'e+') + x.e; |
3124 | } else if (e < 0) { |
3125 | str = '0.' + getZeroString(-e - 1) + str; |
3126 | if (sd && (k = sd - len) > 0) str += getZeroString(k); |
3127 | } else if (e >= len) { |
3128 | str += getZeroString(e + 1 - len); |
3129 | if (sd && (k = sd - e - 1) > 0) str = str + '.' + getZeroString(k); |
3130 | } else { |
3131 | if ((k = e + 1) < len) str = str.slice(0, k) + '.' + str.slice(k); |
3132 | if (sd && (k = sd - len) > 0) { |
3133 | if (e + 1 === len) str += '.'; |
3134 | str += getZeroString(k); |
3135 | } |
3136 | } |
3137 | |
3138 | return str; |
3139 | } |
3140 | |
3141 | |
3142 | // Calculate the base 10 exponent from the base 1e7 exponent. |
3143 | function getBase10Exponent(digits, e) { |
3144 | var w = digits[0]; |
3145 | |
3146 | // Add the number of digits of the first word of the digits array. |
3147 | for ( e *= LOG_BASE; w >= 10; w /= 10) e++; |
3148 | return e; |
3149 | } |
3150 | |
3151 | |
3152 | function getLn10(Ctor, sd, pr) { |
3153 | if (sd > LN10_PRECISION) { |
3154 | |
3155 | // Reset global state in case the exception is caught. |
3156 | external = true; |
3157 | if (pr) Ctor.precision = pr; |
3158 | throw Error(precisionLimitExceeded); |
3159 | } |
3160 | return finalise(new Ctor(LN10), sd, 1, true); |
3161 | } |
3162 | |
3163 | |
3164 | function getPi(Ctor, sd, rm) { |
3165 | if (sd > PI_PRECISION) throw Error(precisionLimitExceeded); |
3166 | return finalise(new Ctor(PI), sd, rm, true); |
3167 | } |
3168 | |
3169 | |
3170 | function getPrecision(digits) { |
3171 | var w = digits.length - 1, |
3172 | len = w * LOG_BASE + 1; |
3173 | |
3174 | w = digits[w]; |
3175 | |
3176 | // If non-zero... |
3177 | if (w) { |
3178 | |
3179 | // Subtract the number of trailing zeros of the last word. |
3180 | for (; w % 10 == 0; w /= 10) len--; |
3181 | |
3182 | // Add the number of digits of the first word. |
3183 | for (w = digits[0]; w >= 10; w /= 10) len++; |
3184 | } |
3185 | |
3186 | return len; |
3187 | } |
3188 | |
3189 | |
3190 | function getZeroString(k) { |
3191 | var zs = ''; |
3192 | for (; k--;) zs += '0'; |
3193 | return zs; |
3194 | } |
3195 | |
3196 | |
3197 | /* |
3198 | * Return a new Decimal whose value is the value of Decimal `x` to the power `n`, where `n` is an |
3199 | * integer of type number. |
3200 | * |
3201 | * Implements 'exponentiation by squaring'. Called by `pow` and `parseOther`. |
3202 | * |
3203 | */ |
3204 | function intPow(Ctor, x, n, pr) { |
3205 | var isTruncated, |
3206 | r = new Ctor(1), |
3207 | |
3208 | // Max n of 9007199254740991 takes 53 loop iterations. |
3209 | // Maximum digits array length; leaves [28, 34] guard digits. |
3210 | k = Math.ceil(pr / LOG_BASE + 4); |
3211 | |
3212 | external = false; |
3213 | |
3214 | for (;;) { |
3215 | if (n % 2) { |
3216 | r = r.times(x); |
3217 | if (truncate(r.d, k)) isTruncated = true; |
3218 | } |
3219 | |
3220 | n = mathfloor(n / 2); |
3221 | if (n === 0) { |
3222 | |
3223 | // To ensure correct rounding when r.d is truncated, increment the last word if it is zero. |
3224 | n = r.d.length - 1; |
3225 | if (isTruncated && r.d[n] === 0) ++r.d[n]; |
3226 | break; |
3227 | } |
3228 | |
3229 | x = x.times(x); |
3230 | truncate(x.d, k); |
3231 | } |
3232 | |
3233 | external = true; |
3234 | |
3235 | return r; |
3236 | } |
3237 | |
3238 | |
3239 | function isOdd(n) { |
3240 | return n.d[n.d.length - 1] & 1; |
3241 | } |
3242 | |
3243 | |
3244 | /* |
3245 | * Handle `max` and `min`. `ltgt` is 'lt' or 'gt'. |
3246 | */ |
3247 | function maxOrMin(Ctor, args, ltgt) { |
3248 | var y, |
3249 | x = new Ctor(args[0]), |
3250 | i = 0; |
3251 | |
3252 | for (; ++i < args.length;) { |
3253 | y = new Ctor(args[i]); |
3254 | if (!y.s) { |
3255 | x = y; |
3256 | break; |
3257 | } else if (x[ltgt](y)) { |
3258 | x = y; |
3259 | } |
3260 | } |
3261 | |
3262 | return x; |
3263 | } |
3264 | |
3265 | |
3266 | /* |
3267 | * Return a new Decimal whose value is the natural exponential of `x` rounded to `sd` significant |
3268 | * digits. |
3269 | * |
3270 | * Taylor/Maclaurin series. |
3271 | * |
3272 | * exp(x) = x^0/0! + x^1/1! + x^2/2! + x^3/3! + ... |
3273 | * |
3274 | * Argument reduction: |
3275 | * Repeat x = x / 32, k += 5, until |x| < 0.1 |
3276 | * exp(x) = exp(x / 2^k)^(2^k) |
3277 | * |
3278 | * Previously, the argument was initially reduced by |
3279 | * exp(x) = exp(r) * 10^k where r = x - k * ln10, k = floor(x / ln10) |
3280 | * to first put r in the range [0, ln10], before dividing by 32 until |x| < 0.1, but this was |
3281 | * found to be slower than just dividing repeatedly by 32 as above. |
3282 | * |
3283 | * Max integer argument: exp('20723265836946413') = 6.3e+9000000000000000 |
3284 | * Min integer argument: exp('-20723265836946411') = 1.2e-9000000000000000 |
3285 | * (Math object integer min/max: Math.exp(709) = 8.2e+307, Math.exp(-745) = 5e-324) |
3286 | * |
3287 | * exp(Infinity) = Infinity |
3288 | * exp(-Infinity) = 0 |
3289 | * exp(NaN) = NaN |
3290 | * exp(±0) = 1 |
3291 | * |
3292 | * exp(x) is non-terminating for any finite, non-zero x. |
3293 | * |
3294 | * The result will always be correctly rounded. |
3295 | * |
3296 | */ |
3297 | function naturalExponential(x, sd) { |
3298 | var denominator, guard, j, pow, sum, t, wpr, |
3299 | rep = 0, |
3300 | i = 0, |
3301 | k = 0, |
3302 | Ctor = x.constructor, |
3303 | rm = Ctor.rounding, |
3304 | pr = Ctor.precision; |
3305 | |
3306 | // 0/NaN/Infinity? |
3307 | if (!x.d || !x.d[0] || x.e > 17) { |
3308 | |
3309 | return new Ctor(x.d |
3310 | ? !x.d[0] ? 1 : x.s < 0 ? 0 : 1 / 0 |
3311 | : x.s ? x.s < 0 ? 0 : x : 0 / 0); |
3312 | } |
3313 | |
3314 | if (sd == null) { |
3315 | external = false; |
3316 | wpr = pr; |
3317 | } else { |
3318 | wpr = sd; |
3319 | } |
3320 | |
3321 | t = new Ctor(0.03125); |
3322 | |
3323 | // while abs(x) >= 0.1 |
3324 | while (x.e > -2) { |
3325 | |
3326 | // x = x / 2^5 |
3327 | x = x.times(t); |
3328 | k += 5; |
3329 | } |
3330 | |
3331 | // Use 2 * log10(2^k) + 5 (empirically derived) to estimate the increase in precision |
3332 | // necessary to ensure the first 4 rounding digits are correct. |
3333 | guard = Math.log(mathpow(2, k)) / Math.LN10 * 2 + 5 | 0; |
3334 | wpr += guard; |
3335 | denominator = pow = sum = new Ctor(1); |
3336 | Ctor.precision = wpr; |
3337 | |
3338 | for (;;) { |
3339 | pow = finalise(pow.times(x), wpr, 1); |
3340 | denominator = denominator.times(++i); |
3341 | t = sum.plus(divide(pow, denominator, wpr, 1)); |
3342 | |
3343 | if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { |
3344 | j = k; |
3345 | while (j--) sum = finalise(sum.times(sum), wpr, 1); |
3346 | |
3347 | // Check to see if the first 4 rounding digits are [49]999. |
3348 | // If so, repeat the summation with a higher precision, otherwise |
3349 | // e.g. with precision: 18, rounding: 1 |
3350 | // exp(18.404272462595034083567793919843761) = 98372560.1229999999 (should be 98372560.123) |
3351 | // `wpr - guard` is the index of first rounding digit. |
3352 | if (sd == null) { |
3353 | |
3354 | if (rep < 3 && checkRoundingDigits(sum.d, wpr - guard, rm, rep)) { |
3355 | Ctor.precision = wpr += 10; |
3356 | denominator = pow = t = new Ctor(1); |
3357 | i = 0; |
3358 | rep++; |
3359 | } else { |
3360 | return finalise(sum, Ctor.precision = pr, rm, external = true); |
3361 | } |
3362 | } else { |
3363 | Ctor.precision = pr; |
3364 | return sum; |
3365 | } |
3366 | } |
3367 | |
3368 | sum = t; |
3369 | } |
3370 | } |
3371 | |
3372 | |
3373 | /* |
3374 | * Return a new Decimal whose value is the natural logarithm of `x` rounded to `sd` significant |
3375 | * digits. |
3376 | * |
3377 | * ln(-n) = NaN |
3378 | * ln(0) = -Infinity |
3379 | * ln(-0) = -Infinity |
3380 | * ln(1) = 0 |
3381 | * ln(Infinity) = Infinity |
3382 | * ln(-Infinity) = NaN |
3383 | * ln(NaN) = NaN |
3384 | * |
3385 | * ln(n) (n != 1) is non-terminating. |
3386 | * |
3387 | */ |
3388 | function naturalLogarithm(y, sd) { |
3389 | var c, c0, denominator, e, numerator, rep, sum, t, wpr, x1, x2, |
3390 | n = 1, |
3391 | guard = 10, |
3392 | x = y, |
3393 | xd = x.d, |
3394 | Ctor = x.constructor, |
3395 | rm = Ctor.rounding, |
3396 | pr = Ctor.precision; |
3397 | |
3398 | // Is x negative or Infinity, NaN, 0 or 1? |
3399 | if (x.s < 0 || !xd || !xd[0] || !x.e && xd[0] == 1 && xd.length == 1) { |
3400 | return new Ctor(xd && !xd[0] ? -1 / 0 : x.s != 1 ? NaN : xd ? 0 : x); |
3401 | } |
3402 | |
3403 | if (sd == null) { |
3404 | external = false; |
3405 | wpr = pr; |
3406 | } else { |
3407 | wpr = sd; |
3408 | } |
3409 | |
3410 | Ctor.precision = wpr += guard; |
3411 | c = digitsToString(xd); |
3412 | c0 = c.charAt(0); |
3413 | |
3414 | if (Math.abs(e = x.e) < 1.5e15) { |
3415 | |
3416 | // Argument reduction. |
3417 | // The series converges faster the closer the argument is to 1, so using |
3418 | // ln(a^b) = b * ln(a), ln(a) = ln(a^b) / b |
3419 | // multiply the argument by itself until the leading digits of the significand are 7, 8, 9, |
3420 | // 10, 11, 12 or 13, recording the number of multiplications so the sum of the series can |
3421 | // later be divided by this number, then separate out the power of 10 using |
3422 | // ln(a*10^b) = ln(a) + b*ln(10). |
3423 | |
3424 | // max n is 21 (gives 0.9, 1.0 or 1.1) (9e15 / 21 = 4.2e14). |
3425 | //while (c0 < 9 && c0 != 1 || c0 == 1 && c.charAt(1) > 1) { |
3426 | // max n is 6 (gives 0.7 - 1.3) |
3427 | while (c0 < 7 && c0 != 1 || c0 == 1 && c.charAt(1) > 3) { |
3428 | x = x.times(y); |
3429 | c = digitsToString(x.d); |
3430 | c0 = c.charAt(0); |
3431 | n++; |
3432 | } |
3433 | |
3434 | e = x.e; |
3435 | |
3436 | if (c0 > 1) { |
3437 | x = new Ctor('0.' + c); |
3438 | e++; |
3439 | } else { |
3440 | x = new Ctor(c0 + '.' + c.slice(1)); |
3441 | } |
3442 | } else { |
3443 | |
3444 | // The argument reduction method above may result in overflow if the argument y is a massive |
3445 | // number with exponent >= 1500000000000000 (9e15 / 6 = 1.5e15), so instead recall this |
3446 | // function using ln(x*10^e) = ln(x) + e*ln(10). |
3447 | t = getLn10(Ctor, wpr + 2, pr).times(e + ''); |
3448 | x = naturalLogarithm(new Ctor(c0 + '.' + c.slice(1)), wpr - guard).plus(t); |
3449 | Ctor.precision = pr; |
3450 | |
3451 | return sd == null ? finalise(x, pr, rm, external = true) : x; |
3452 | } |
3453 | |
3454 | // x1 is x reduced to a value near 1. |
3455 | x1 = x; |
3456 | |
3457 | // Taylor series. |
3458 | // ln(y) = ln((1 + x)/(1 - x)) = 2(x + x^3/3 + x^5/5 + x^7/7 + ...) |
3459 | // where x = (y - 1)/(y + 1) (|x| < 1) |
3460 | sum = numerator = x = divide(x.minus(1), x.plus(1), wpr, 1); |
3461 | x2 = finalise(x.times(x), wpr, 1); |
3462 | denominator = 3; |
3463 | |
3464 | for (;;) { |
3465 | numerator = finalise(numerator.times(x2), wpr, 1); |
3466 | t = sum.plus(divide(numerator, new Ctor(denominator), wpr, 1)); |
3467 | |
3468 | if (digitsToString(t.d).slice(0, wpr) === digitsToString(sum.d).slice(0, wpr)) { |
3469 | sum = sum.times(2); |
3470 | |
3471 | // Reverse the argument reduction. Check that e is not 0 because, besides preventing an |
3472 | // unnecessary calculation, -0 + 0 = +0 and to ensure correct rounding -0 needs to stay -0. |
3473 | if (e !== 0) sum = sum.plus(getLn10(Ctor, wpr + 2, pr).times(e + '')); |
3474 | sum = divide(sum, new Ctor(n), wpr, 1); |
3475 | |
3476 | // Is rm > 3 and the first 4 rounding digits 4999, or rm < 4 (or the summation has |
3477 | // been repeated previously) and the first 4 rounding digits 9999? |
3478 | // If so, restart the summation with a higher precision, otherwise |
3479 | // e.g. with precision: 12, rounding: 1 |
3480 | // ln(135520028.6126091714265381533) = 18.7246299999 when it should be 18.72463. |
3481 | // `wpr - guard` is the index of first rounding digit. |
3482 | if (sd == null) { |
3483 | if (checkRoundingDigits(sum.d, wpr - guard, rm, rep)) { |
3484 | Ctor.precision = wpr += guard; |
3485 | t = numerator = x = divide(x1.minus(1), x1.plus(1), wpr, 1); |
3486 | x2 = finalise(x.times(x), wpr, 1); |
3487 | denominator = rep = 1; |
3488 | } else { |
3489 | return finalise(sum, Ctor.precision = pr, rm, external = true); |
3490 | } |
3491 | } else { |
3492 | Ctor.precision = pr; |
3493 | return sum; |
3494 | } |
3495 | } |
3496 | |
3497 | sum = t; |
3498 | denominator += 2; |
3499 | } |
3500 | } |
3501 | |
3502 | |
3503 | // ±Infinity, NaN. |
3504 | function nonFiniteToString(x) { |
3505 | // Unsigned. |
3506 | return String(x.s * x.s / 0); |
3507 | } |
3508 | |
3509 | |
3510 | /* |
3511 | * Parse the value of a new Decimal `x` from string `str`. |
3512 | */ |
3513 | function parseDecimal(x, str) { |
3514 | var e, i, len; |
3515 | |
3516 | // Decimal point? |
3517 | if ((e = str.indexOf('.')) > -1) str = str.replace('.', ''); |
3518 | |
3519 | // Exponential form? |
3520 | if ((i = str.search(/e/i)) > 0) { |
3521 | |
3522 | // Determine exponent. |
3523 | if (e < 0) e = i; |
3524 | e += +str.slice(i + 1); |
3525 | str = str.substring(0, i); |
3526 | } else if (e < 0) { |
3527 | |
3528 | // Integer. |
3529 | e = str.length; |
3530 | } |
3531 | |
3532 | // Determine leading zeros. |
3533 | for (i = 0; str.charCodeAt(i) === 48; i++); |
3534 | |
3535 | // Determine trailing zeros. |
3536 | for (len = str.length; str.charCodeAt(len - 1) === 48; --len); |
3537 | str = str.slice(i, len); |
3538 | |
3539 | if (str) { |
3540 | len -= i; |
3541 | x.e = e = e - i - 1; |
3542 | x.d = []; |
3543 | |
3544 | // Transform base |
3545 | |
3546 | // e is the base 10 exponent. |
3547 | // i is where to slice str to get the first word of the digits array. |
3548 | i = (e + 1) % LOG_BASE; |
3549 | if (e < 0) i += LOG_BASE; |
3550 | |
3551 | if (i < len) { |
3552 | if (i) x.d.push(+str.slice(0, i)); |
3553 | for (len -= LOG_BASE; i < len;) x.d.push(+str.slice(i, i += LOG_BASE)); |
3554 | str = str.slice(i); |
3555 | i = LOG_BASE - str.length; |
3556 | } else { |
3557 | i -= len; |
3558 | } |
3559 | |
3560 | for (; i--;) str += '0'; |
3561 | x.d.push(+str); |
3562 | |
3563 | if (external) { |
3564 | |
3565 | // Overflow? |
3566 | if (x.e > x.constructor.maxE) { |
3567 | |
3568 | // Infinity. |
3569 | x.d = null; |
3570 | x.e = NaN; |
3571 | |
3572 | // Underflow? |
3573 | } else if (x.e < x.constructor.minE) { |
3574 | |
3575 | // Zero. |
3576 | x.e = 0; |
3577 | x.d = [0]; |
3578 | // x.constructor.underflow = true; |
3579 | } // else x.constructor.underflow = false; |
3580 | } |
3581 | } else { |
3582 | |
3583 | // Zero. |
3584 | x.e = 0; |
3585 | x.d = [0]; |
3586 | } |
3587 | |
3588 | return x; |
3589 | } |
3590 | |
3591 | |
3592 | /* |
3593 | * Parse the value of a new Decimal `x` from a string `str`, which is not a decimal value. |
3594 | */ |
3595 | function parseOther(x, str) { |
3596 | var base, Ctor, divisor, i, isFloat, len, p, xd, xe; |
3597 | |
3598 | if (str === 'Infinity' || str === 'NaN') { |
3599 | if (!+str) x.s = NaN; |
3600 | x.e = NaN; |
3601 | x.d = null; |
3602 | return x; |
3603 | } |
3604 | |
3605 | if (isHex.test(str)) { |
3606 | base = 16; |
3607 | str = str.toLowerCase(); |
3608 | } else if (isBinary.test(str)) { |
3609 | base = 2; |
3610 | } else if (isOctal.test(str)) { |
3611 | base = 8; |
3612 | } else { |
3613 | throw Error(invalidArgument + str); |
3614 | } |
3615 | |
3616 | // Is there a binary exponent part? |
3617 | i = str.search(/p/i); |
3618 | |
3619 | if (i > 0) { |
3620 | p = +str.slice(i + 1); |
3621 | str = str.substring(2, i); |
3622 | } else { |
3623 | str = str.slice(2); |
3624 | } |
3625 | |
3626 | // Convert `str` as an integer then divide the result by `base` raised to a power such that the |
3627 | // fraction part will be restored. |
3628 | i = str.indexOf('.'); |
3629 | isFloat = i >= 0; |
3630 | Ctor = x.constructor; |
3631 | |
3632 | if (isFloat) { |
3633 | str = str.replace('.', ''); |
3634 | len = str.length; |
3635 | i = len - i; |
3636 | |
3637 | // log[10](16) = 1.2041... , log[10](88) = 1.9444.... |
3638 | divisor = intPow(Ctor, new Ctor(base), i, i * 2); |
3639 | } |
3640 | |
3641 | xd = convertBase(str, base, BASE); |
3642 | xe = xd.length - 1; |
3643 | |
3644 | // Remove trailing zeros. |
3645 | for (i = xe; xd[i] === 0; --i) xd.pop(); |
3646 | if (i < 0) return new Ctor(x.s * 0); |
3647 | x.e = getBase10Exponent(xd, xe); |
3648 | x.d = xd; |
3649 | external = false; |
3650 | |
3651 | // At what precision to perform the division to ensure exact conversion? |
3652 | // maxDecimalIntegerPartDigitCount = ceil(log[10](b) * otherBaseIntegerPartDigitCount) |
3653 | // log[10](2) = 0.30103, log[10](8) = 0.90309, log[10](16) = 1.20412 |
3654 | // E.g. ceil(1.2 * 3) = 4, so up to 4 decimal digits are needed to represent 3 hex int digits. |
3655 | // maxDecimalFractionPartDigitCount = {Hex:4|Oct:3|Bin:1} * otherBaseFractionPartDigitCount |
3656 | // Therefore using 4 * the number of digits of str will always be enough. |
3657 | if (isFloat) x = divide(x, divisor, len * 4); |
3658 | |
3659 | // Multiply by the binary exponent part if present. |
3660 | if (p) x = x.times(Math.abs(p) < 54 ? Math.pow(2, p) : Decimal.pow(2, p)); |
3661 | external = true; |
3662 | |
3663 | return x; |
3664 | } |
3665 | |
3666 | |
3667 | /* |
3668 | * sin(x) = x - x^3/3! + x^5/5! - ... |
3669 | * |x| < pi/2 |
3670 | * |
3671 | */ |
3672 | function sine(Ctor, x) { |
3673 | var k, |
3674 | len = x.d.length; |
3675 | |
3676 | if (len < 3) return taylorSeries(Ctor, 2, x, x); |
3677 | |
3678 | // Argument reduction: sin(5x) = 16*sin^5(x) - 20*sin^3(x) + 5*sin(x) |
3679 | // i.e. sin(x) = 16*sin^5(x/5) - 20*sin^3(x/5) + 5*sin(x/5) |
3680 | // and sin(x) = sin(x/5)(5 + sin^2(x/5)(16sin^2(x/5) - 20)) |
3681 | |
3682 | // Estimate the optimum number of times to use the argument reduction. |
3683 | k = 1.4 * Math.sqrt(len); |
3684 | k = k > 16 ? 16 : k | 0; |
3685 | |
3686 | // Max k before Math.pow precision loss is 22 |
3687 | x = x.times(Math.pow(5, -k)); |
3688 | x = taylorSeries(Ctor, 2, x, x); |
3689 | |
3690 | // Reverse argument reduction |
3691 | var sin2_x, |
3692 | d5 = new Ctor(5), |
3693 | d16 = new Ctor(16), |
3694 | d20 = new Ctor(20); |
3695 | for (; k--;) { |
3696 | sin2_x = x.times(x); |
3697 | x = x.times(d5.plus(sin2_x.times(d16.times(sin2_x).minus(d20)))); |
3698 | } |
3699 | |
3700 | return x; |
3701 | } |
3702 | |
3703 | |
3704 | // Calculate Taylor series for `cos`, `cosh`, `sin` and `sinh`. |
3705 | function taylorSeries(Ctor, n, x, y, isHyperbolic) { |
3706 | var j, t, u, x2, |
3707 | i = 1, |
3708 | pr = Ctor.precision, |
3709 | k = Math.ceil(pr / LOG_BASE); |
3710 | |
3711 | external = false; |
3712 | x2 = x.times(x); |
3713 | u = new Ctor(y); |
3714 | |
3715 | for (;;) { |
3716 | t = divide(u.times(x2), new Ctor(n++ * n++), pr, 1); |
3717 | u = isHyperbolic ? y.plus(t) : y.minus(t); |
3718 | y = divide(t.times(x2), new Ctor(n++ * n++), pr, 1); |
3719 | t = u.plus(y); |
3720 | |
3721 | if (t.d[k] !== void 0) { |
3722 | for (j = k; t.d[j] === u.d[j] && j--;); |
3723 | if (j == -1) break; |
3724 | } |
3725 | |
3726 | j = u; |
3727 | u = y; |
3728 | y = t; |
3729 | t = j; |
3730 | i++; |
3731 | } |
3732 | |
3733 | external = true; |
3734 | t.d.length = k + 1; |
3735 | |
3736 | return t; |
3737 | } |
3738 | |
3739 | |
3740 | // Return the absolute value of `x` reduced to less than or equal to half pi. |
3741 | function toLessThanHalfPi(Ctor, x) { |
3742 | var t, |
3743 | isNeg = x.s < 0, |
3744 | pi = getPi(Ctor, Ctor.precision, 1), |
3745 | halfPi = pi.times(0.5); |
3746 | |
3747 | x = x.abs(); |
3748 | |
3749 | if (x.lte(halfPi)) { |
3750 | quadrant = isNeg ? 4 : 1; |
3751 | return x; |
3752 | } |
3753 | |
3754 | t = x.divToInt(pi); |
3755 | |
3756 | if (t.isZero()) { |
3757 | quadrant = isNeg ? 3 : 2; |
3758 | } else { |
3759 | x = x.minus(t.times(pi)); |
3760 | |
3761 | // 0 <= x < pi |
3762 | if (x.lte(halfPi)) { |
3763 | quadrant = isOdd(t) ? (isNeg ? 2 : 3) : (isNeg ? 4 : 1); |
3764 | return x; |
3765 | } |
3766 | |
3767 | quadrant = isOdd(t) ? (isNeg ? 1 : 4) : (isNeg ? 3 : 2); |
3768 | } |
3769 | |
3770 | return x.minus(pi).abs(); |
3771 | } |
3772 | |
3773 | |
3774 | /* |
3775 | * Return the value of Decimal `x` as a string in base `baseOut`. |
3776 | * |
3777 | * If the optional `sd` argument is present include a binary exponent suffix. |
3778 | */ |
3779 | function toStringBinary(x, baseOut, sd, rm) { |
3780 | var base, e, i, k, len, roundUp, str, xd, y, |
3781 | Ctor = x.constructor, |
3782 | isExp = sd !== void 0; |
3783 | |
3784 | if (isExp) { |
3785 | checkInt32(sd, 1, MAX_DIGITS); |
3786 | if (rm === void 0) rm = Ctor.rounding; |
3787 | else checkInt32(rm, 0, 8); |
3788 | } else { |
3789 | sd = Ctor.precision; |
3790 | rm = Ctor.rounding; |
3791 | } |
3792 | |
3793 | if (!x.isFinite()) { |
3794 | str = nonFiniteToString(x); |
3795 | } else { |
3796 | str = finiteToString(x); |
3797 | i = str.indexOf('.'); |
3798 | |
3799 | // Use exponential notation according to `toExpPos` and `toExpNeg`? No, but if required: |
3800 | // maxBinaryExponent = floor((decimalExponent + 1) * log[2](10)) |
3801 | // minBinaryExponent = floor(decimalExponent * log[2](10)) |
3802 | // log[2](10) = 3.321928094887362347870319429489390175864 |
3803 | |
3804 | if (isExp) { |
3805 | base = 2; |
3806 | if (baseOut == 16) { |
3807 | sd = sd * 4 - 3; |
3808 | } else if (baseOut == 8) { |
3809 | sd = sd * 3 - 2; |
3810 | } |
3811 | } else { |
3812 | base = baseOut; |
3813 | } |
3814 | |
3815 | // Convert the number as an integer then divide the result by its base raised to a power such |
3816 | // that the fraction part will be restored. |
3817 | |
3818 | // Non-integer. |
3819 | if (i >= 0) { |
3820 | str = str.replace('.', ''); |
3821 | y = new Ctor(1); |
3822 | y.e = str.length - i; |
3823 | y.d = convertBase(finiteToString(y), 10, base); |
3824 | y.e = y.d.length; |
3825 | } |
3826 | |
3827 | xd = convertBase(str, 10, base); |
3828 | e = len = xd.length; |
3829 | |
3830 | // Remove trailing zeros. |
3831 | for (; xd[--len] == 0;) xd.pop(); |
3832 | |
3833 | if (!xd[0]) { |
3834 | str = isExp ? '0p+0' : '0'; |
3835 | } else { |
3836 | if (i < 0) { |
3837 | e--; |
3838 | } else { |
3839 | x = new Ctor(x); |
3840 | x.d = xd; |
3841 | x.e = e; |
3842 | x = divide(x, y, sd, rm, 0, base); |
3843 | xd = x.d; |
3844 | e = x.e; |
3845 | roundUp = inexact; |
3846 | } |
3847 | |
3848 | // The rounding digit, i.e. the digit after the digit that may be rounded up. |
3849 | i = xd[sd]; |
3850 | k = base / 2; |
3851 | roundUp = roundUp || xd[sd + 1] !== void 0; |
3852 | |
3853 | roundUp = rm < 4 |
3854 | ? (i !== void 0 || roundUp) && (rm === 0 || rm === (x.s < 0 ? 3 : 2)) |
3855 | : i > k || i === k && (rm === 4 || roundUp || rm === 6 && xd[sd - 1] & 1 || |
3856 | rm === (x.s < 0 ? 8 : 7)); |
3857 | |
3858 | xd.length = sd; |
3859 | |
3860 | if (roundUp) { |
3861 | |
3862 | // Rounding up may mean the previous digit has to be rounded up and so on. |
3863 | for (; ++xd[--sd] > base - 1;) { |
3864 | xd[sd] = 0; |
3865 | if (!sd) { |
3866 | ++e; |
3867 | xd.unshift(1); |
3868 | } |
3869 | } |
3870 | } |
3871 | |
3872 | // Determine trailing zeros. |
3873 | for (len = xd.length; !xd[len - 1]; --len); |
3874 | |
3875 | // E.g. [4, 11, 15] becomes 4bf. |
3876 | for (i = 0, str = ''; i < len; i++) str += NUMERALS.charAt(xd[i]); |
3877 | |
3878 | // Add binary exponent suffix? |
3879 | if (isExp) { |
3880 | if (len > 1) { |
3881 | if (baseOut == 16 || baseOut == 8) { |
3882 | i = baseOut == 16 ? 4 : 3; |
3883 | for (--len; len % i; len++) str += '0'; |
3884 | xd = convertBase(str, base, baseOut); |
3885 | for (len = xd.length; !xd[len - 1]; --len); |
3886 | |
3887 | // xd[0] will always be be 1 |
3888 | for (i = 1, str = '1.'; i < len; i++) str += NUMERALS.charAt(xd[i]); |
3889 | } else { |
3890 | str = str.charAt(0) + '.' + str.slice(1); |
3891 | } |
3892 | } |
3893 | |
3894 | str = str + (e < 0 ? 'p' : 'p+') + e; |
3895 | } else if (e < 0) { |
3896 | for (; ++e;) str = '0' + str; |
3897 | str = '0.' + str; |
3898 | } else { |
3899 | if (++e > len) for (e -= len; e-- ;) str += '0'; |
3900 | else if (e < len) str = str.slice(0, e) + '.' + str.slice(e); |
3901 | } |
3902 | } |
3903 | |
3904 | str = (baseOut == 16 ? '0x' : baseOut == 2 ? '0b' : baseOut == 8 ? '0o' : '') + str; |
3905 | } |
3906 | |
3907 | return x.s < 0 ? '-' + str : str; |
3908 | } |
3909 | |
3910 | |
3911 | // Does not strip trailing zeros. |
3912 | function truncate(arr, len) { |
3913 | if (arr.length > len) { |
3914 | arr.length = len; |
3915 | return true; |
3916 | } |
3917 | } |
3918 | |
3919 | |
3920 | // Decimal methods |
3921 | |
3922 | |
3923 | /* |
3924 | * abs |
3925 | * acos |
3926 | * acosh |
3927 | * add |
3928 | * asin |
3929 | * asinh |
3930 | * atan |
3931 | * atanh |
3932 | * atan2 |
3933 | * cbrt |
3934 | * ceil |
3935 | * clone |
3936 | * config |
3937 | * cos |
3938 | * cosh |
3939 | * div |
3940 | * exp |
3941 | * floor |
3942 | * hypot |
3943 | * ln |
3944 | * log |
3945 | * log2 |
3946 | * log10 |
3947 | * max |
3948 | * min |
3949 | * mod |
3950 | * mul |
3951 | * pow |
3952 | * random |
3953 | * round |
3954 | * set |
3955 | * sign |
3956 | * sin |
3957 | * sinh |
3958 | * sqrt |
3959 | * sub |
3960 | * tan |
3961 | * tanh |
3962 | * trunc |
3963 | */ |
3964 | |
3965 | |
3966 | /* |
3967 | * Return a new Decimal whose value is the absolute value of `x`. |
3968 | * |
3969 | * x {number|string|Decimal} |
3970 | * |
3971 | */ |
3972 | function abs(x) { |
3973 | return new this(x).abs(); |
3974 | } |
3975 | |
3976 | |
3977 | /* |
3978 | * Return a new Decimal whose value is the arccosine in radians of `x`. |
3979 | * |
3980 | * x {number|string|Decimal} |
3981 | * |
3982 | */ |
3983 | function acos(x) { |
3984 | return new this(x).acos(); |
3985 | } |
3986 | |
3987 | |
3988 | /* |
3989 | * Return a new Decimal whose value is the inverse of the hyperbolic cosine of `x`, rounded to |
3990 | * `precision` significant digits using rounding mode `rounding`. |
3991 | * |
3992 | * x {number|string|Decimal} A value in radians. |
3993 | * |
3994 | */ |
3995 | function acosh(x) { |
3996 | return new this(x).acosh(); |
3997 | } |
3998 | |
3999 | |
4000 | /* |
4001 | * Return a new Decimal whose value is the sum of `x` and `y`, rounded to `precision` significant |
4002 | * digits using rounding mode `rounding`. |
4003 | * |
4004 | * x {number|string|Decimal} |
4005 | * y {number|string|Decimal} |
4006 | * |
4007 | */ |
4008 | function add(x, y) { |
4009 | return new this(x).plus(y); |
4010 | } |
4011 | |
4012 | |
4013 | /* |
4014 | * Return a new Decimal whose value is the arcsine in radians of `x`, rounded to `precision` |
4015 | * significant digits using rounding mode `rounding`. |
4016 | * |
4017 | * x {number|string|Decimal} |
4018 | * |
4019 | */ |
4020 | function asin(x) { |
4021 | return new this(x).asin(); |
4022 | } |
4023 | |
4024 | |
4025 | /* |
4026 | * Return a new Decimal whose value is the inverse of the hyperbolic sine of `x`, rounded to |
4027 | * `precision` significant digits using rounding mode `rounding`. |
4028 | * |
4029 | * x {number|string|Decimal} A value in radians. |
4030 | * |
4031 | */ |
4032 | function asinh(x) { |
4033 | return new this(x).asinh(); |
4034 | } |
4035 | |
4036 | |
4037 | /* |
4038 | * Return a new Decimal whose value is the arctangent in radians of `x`, rounded to `precision` |
4039 | * significant digits using rounding mode `rounding`. |
4040 | * |
4041 | * x {number|string|Decimal} |
4042 | * |
4043 | */ |
4044 | function atan(x) { |
4045 | return new this(x).atan(); |
4046 | } |
4047 | |
4048 | |
4049 | /* |
4050 | * Return a new Decimal whose value is the inverse of the hyperbolic tangent of `x`, rounded to |
4051 | * `precision` significant digits using rounding mode `rounding`. |
4052 | * |
4053 | * x {number|string|Decimal} A value in radians. |
4054 | * |
4055 | */ |
4056 | function atanh(x) { |
4057 | return new this(x).atanh(); |
4058 | } |
4059 | |
4060 | |
4061 | /* |
4062 | * Return a new Decimal whose value is the arctangent in radians of `y/x` in the range -pi to pi |
4063 | * (inclusive), rounded to `precision` significant digits using rounding mode `rounding`. |
4064 | * |
4065 | * Domain: [-Infinity, Infinity] |
4066 | * Range: [-pi, pi] |
4067 | * |
4068 | * y {number|string|Decimal} The y-coordinate. |
4069 | * x {number|string|Decimal} The x-coordinate. |
4070 | * |
4071 | * atan2(±0, -0) = ±pi |
4072 | * atan2(±0, +0) = ±0 |
4073 | * atan2(±0, -x) = ±pi for x > 0 |
4074 | * atan2(±0, x) = ±0 for x > 0 |
4075 | * atan2(-y, ±0) = -pi/2 for y > 0 |
4076 | * atan2(y, ±0) = pi/2 for y > 0 |
4077 | * atan2(±y, -Infinity) = ±pi for finite y > 0 |
4078 | * atan2(±y, +Infinity) = ±0 for finite y > 0 |
4079 | * atan2(±Infinity, x) = ±pi/2 for finite x |
4080 | * atan2(±Infinity, -Infinity) = ±3*pi/4 |
4081 | * atan2(±Infinity, +Infinity) = ±pi/4 |
4082 | * atan2(NaN, x) = NaN |
4083 | * atan2(y, NaN) = NaN |
4084 | * |
4085 | */ |
4086 | function atan2(y, x) { |
4087 | y = new this(y); |
4088 | x = new this(x); |
4089 | var r, |
4090 | pr = this.precision, |
4091 | rm = this.rounding, |
4092 | wpr = pr + 4; |
4093 | |
4094 | // Either NaN |
4095 | if (!y.s || !x.s) { |
4096 | r = new this(NaN); |
4097 | |
4098 | // Both ±Infinity |
4099 | } else if (!y.d && !x.d) { |
4100 | r = getPi(this, wpr, 1).times(x.s > 0 ? 0.25 : 0.75); |
4101 | r.s = y.s; |
4102 | |
4103 | // x is ±Infinity or y is ±0 |
4104 | } else if (!x.d || y.isZero()) { |
4105 | r = x.s < 0 ? getPi(this, pr, rm) : new this(0); |
4106 | r.s = y.s; |
4107 | |
4108 | // y is ±Infinity or x is ±0 |
4109 | } else if (!y.d || x.isZero()) { |
4110 | r = getPi(this, wpr, 1).times(0.5); |
4111 | r.s = y.s; |
4112 | |
4113 | // Both non-zero and finite |
4114 | } else if (x.s < 0) { |
4115 | this.precision = wpr; |
4116 | this.rounding = 1; |
4117 | r = this.atan(divide(y, x, wpr, 1)); |
4118 | x = getPi(this, wpr, 1); |
4119 | this.precision = pr; |
4120 | this.rounding = rm; |
4121 | r = y.s < 0 ? r.minus(x) : r.plus(x); |
4122 | } else { |
4123 | r = this.atan(divide(y, x, wpr, 1)); |
4124 | } |
4125 | |
4126 | return r; |
4127 | } |
4128 | |
4129 | |
4130 | /* |
4131 | * Return a new Decimal whose value is the cube root of `x`, rounded to `precision` significant |
4132 | * digits using rounding mode `rounding`. |
4133 | * |
4134 | * x {number|string|Decimal} |
4135 | * |
4136 | */ |
4137 | function cbrt(x) { |
4138 | return new this(x).cbrt(); |
4139 | } |
4140 | |
4141 | |
4142 | /* |
4143 | * Return a new Decimal whose value is `x` rounded to an integer using `ROUND_CEIL`. |
4144 | * |
4145 | * x {number|string|Decimal} |
4146 | * |
4147 | */ |
4148 | function ceil(x) { |
4149 | return finalise(x = new this(x), x.e + 1, 2); |
4150 | } |
4151 | |
4152 | |
4153 | /* |
4154 | * Configure global settings for a Decimal constructor. |
4155 | * |
4156 | * `obj` is an object with one or more of the following properties, |
4157 | * |
4158 | * precision {number} |
4159 | * rounding {number} |
4160 | * toExpNeg {number} |
4161 | * toExpPos {number} |
4162 | * maxE {number} |
4163 | * minE {number} |
4164 | * modulo {number} |
4165 | * crypto {boolean|number} |
4166 | * defaults {true} |
4167 | * |
4168 | * E.g. Decimal.config({ precision: 20, rounding: 4 }) |
4169 | * |
4170 | */ |
4171 | function config(obj) { |
4172 | if (!obj || typeof obj !== 'object') throw Error(decimalError + 'Object expected'); |
4173 | var i, p, v, |
4174 | useDefaults = obj.defaults === true, |
4175 | ps = [ |
4176 | 'precision', 1, MAX_DIGITS, |
4177 | 'rounding', 0, 8, |
4178 | 'toExpNeg', -EXP_LIMIT, 0, |
4179 | 'toExpPos', 0, EXP_LIMIT, |
4180 | 'maxE', 0, EXP_LIMIT, |
4181 | 'minE', -EXP_LIMIT, 0, |
4182 | 'modulo', 0, 9 |
4183 | ]; |
4184 | |
4185 | for (i = 0; i < ps.length; i += 3) { |
4186 | if (p = ps[i], useDefaults) this[p] = DEFAULTS[p]; |
4187 | if ((v = obj[p]) !== void 0) { |
4188 | if (mathfloor(v) === v && v >= ps[i + 1] && v <= ps[i + 2]) this[p] = v; |
4189 | else throw Error(invalidArgument + p + ': ' + v); |
4190 | } |
4191 | } |
4192 | |
4193 | if (p = 'crypto', useDefaults) this[p] = DEFAULTS[p]; |
4194 | if ((v = obj[p]) !== void 0) { |
4195 | if (v === true || v === false || v === 0 || v === 1) { |
4196 | if (v) { |
4197 | if (typeof crypto != 'undefined' && crypto && |
4198 | (crypto.getRandomValues || crypto.randomBytes)) { |
4199 | this[p] = true; |
4200 | } else { |
4201 | throw Error(cryptoUnavailable); |
4202 | } |
4203 | } else { |
4204 | this[p] = false; |
4205 | } |
4206 | } else { |
4207 | throw Error(invalidArgument + p + ': ' + v); |
4208 | } |
4209 | } |
4210 | |
4211 | return this; |
4212 | } |
4213 | |
4214 | |
4215 | /* |
4216 | * Return a new Decimal whose value is the cosine of `x`, rounded to `precision` significant |
4217 | * digits using rounding mode `rounding`. |
4218 | * |
4219 | * x {number|string|Decimal} A value in radians. |
4220 | * |
4221 | */ |
4222 | function cos(x) { |
4223 | return new this(x).cos(); |
4224 | } |
4225 | |
4226 | |
4227 | /* |
4228 | * Return a new Decimal whose value is the hyperbolic cosine of `x`, rounded to precision |
4229 | * significant digits using rounding mode `rounding`. |
4230 | * |
4231 | * x {number|string|Decimal} A value in radians. |
4232 | * |
4233 | */ |
4234 | function cosh(x) { |
4235 | return new this(x).cosh(); |
4236 | } |
4237 | |
4238 | |
4239 | /* |
4240 | * Create and return a Decimal constructor with the same configuration properties as this Decimal |
4241 | * constructor. |
4242 | * |
4243 | */ |
4244 | function clone(obj) { |
4245 | var i, p, ps; |
4246 | |
4247 | /* |
4248 | * The Decimal constructor and exported function. |
4249 | * Return a new Decimal instance. |
4250 | * |
4251 | * v {number|string|Decimal} A numeric value. |
4252 | * |
4253 | */ |
4254 | function Decimal(v) { |
4255 | var e, i, t, |
4256 | x = this; |
4257 | |
4258 | // Decimal called without new. |
4259 | if (!(x instanceof Decimal)) return new Decimal(v); |
4260 | |
4261 | // Retain a reference to this Decimal constructor, and shadow Decimal.prototype.constructor |
4262 | // which points to Object. |
4263 | x.constructor = Decimal; |
4264 | |
4265 | // Duplicate. |
4266 | if (v instanceof Decimal) { |
4267 | x.s = v.s; |
4268 | x.e = v.e; |
4269 | x.d = (v = v.d) ? v.slice() : v; |
4270 | return; |
4271 | } |
4272 | |
4273 | t = typeof v; |
4274 | |
4275 | if (t === 'number') { |
4276 | if (v === 0) { |
4277 | x.s = 1 / v < 0 ? -1 : 1; |
4278 | x.e = 0; |
4279 | x.d = [0]; |
4280 | return; |
4281 | } |
4282 | |
4283 | if (v < 0) { |
4284 | v = -v; |
4285 | x.s = -1; |
4286 | } else { |
4287 | x.s = 1; |
4288 | } |
4289 | |
4290 | // Fast path for small integers. |
4291 | if (v === ~~v && v < 1e7) { |
4292 | for (e = 0, i = v; i >= 10; i /= 10) e++; |
4293 | x.e = e; |
4294 | x.d = [v]; |
4295 | return; |
4296 | |
4297 | // Infinity, NaN. |
4298 | } else if (v * 0 !== 0) { |
4299 | if (!v) x.s = NaN; |
4300 | x.e = NaN; |
4301 | x.d = null; |
4302 | return; |
4303 | } |
4304 | |
4305 | return parseDecimal(x, v.toString()); |
4306 | |
4307 | } else if (t !== 'string') { |
4308 | throw Error(invalidArgument + v); |
4309 | } |
4310 | |
4311 | // Minus sign? |
4312 | if (v.charCodeAt(0) === 45) { |
4313 | v = v.slice(1); |
4314 | x.s = -1; |
4315 | } else { |
4316 | x.s = 1; |
4317 | } |
4318 | |
4319 | return isDecimal.test(v) ? parseDecimal(x, v) : parseOther(x, v); |
4320 | } |
4321 | |
4322 | Decimal.prototype = P; |
4323 | |
4324 | Decimal.ROUND_UP = 0; |
4325 | Decimal.ROUND_DOWN = 1; |
4326 | Decimal.ROUND_CEIL = 2; |
4327 | Decimal.ROUND_FLOOR = 3; |
4328 | Decimal.ROUND_HALF_UP = 4; |
4329 | Decimal.ROUND_HALF_DOWN = 5; |
4330 | Decimal.ROUND_HALF_EVEN = 6; |
4331 | Decimal.ROUND_HALF_CEIL = 7; |
4332 | Decimal.ROUND_HALF_FLOOR = 8; |
4333 | Decimal.EUCLID = 9; |
4334 | |
4335 | Decimal.config = Decimal.set = config; |
4336 | Decimal.clone = clone; |
4337 | Decimal.isDecimal = isDecimalInstance; |
4338 | |
4339 | Decimal.abs = abs; |
4340 | Decimal.acos = acos; |
4341 | Decimal.acosh = acosh; // ES6 |
4342 | Decimal.add = add; |
4343 | Decimal.asin = asin; |
4344 | Decimal.asinh = asinh; // ES6 |
4345 | Decimal.atan = atan; |
4346 | Decimal.atanh = atanh; // ES6 |
4347 | Decimal.atan2 = atan2; |
4348 | Decimal.cbrt = cbrt; // ES6 |
4349 | Decimal.ceil = ceil; |
4350 | Decimal.cos = cos; |
4351 | Decimal.cosh = cosh; // ES6 |
4352 | Decimal.div = div; |
4353 | Decimal.exp = exp; |
4354 | Decimal.floor = floor; |
4355 | Decimal.hypot = hypot; // ES6 |
4356 | Decimal.ln = ln; |
4357 | Decimal.log = log; |
4358 | Decimal.log10 = log10; // ES6 |
4359 | Decimal.log2 = log2; // ES6 |
4360 | Decimal.max = max; |
4361 | Decimal.min = min; |
4362 | Decimal.mod = mod; |
4363 | Decimal.mul = mul; |
4364 | Decimal.pow = pow; |
4365 | Decimal.random = random; |
4366 | Decimal.round = round; |
4367 | Decimal.sign = sign; // ES6 |
4368 | Decimal.sin = sin; |
4369 | Decimal.sinh = sinh; // ES6 |
4370 | Decimal.sqrt = sqrt; |
4371 | Decimal.sub = sub; |
4372 | Decimal.tan = tan; |
4373 | Decimal.tanh = tanh; // ES6 |
4374 | Decimal.trunc = trunc; // ES6 |
4375 | |
4376 | if (obj === void 0) obj = {}; |
4377 | if (obj) { |
4378 | if (obj.defaults !== true) { |
4379 | ps = ['precision', 'rounding', 'toExpNeg', 'toExpPos', 'maxE', 'minE', 'modulo', 'crypto']; |
4380 | for (i = 0; i < ps.length;) if (!obj.hasOwnProperty(p = ps[i++])) obj[p] = this[p]; |
4381 | } |
4382 | } |
4383 | |
4384 | Decimal.config(obj); |
4385 | |
4386 | return Decimal; |
4387 | } |
4388 | |
4389 | |
4390 | /* |
4391 | * Return a new Decimal whose value is `x` divided by `y`, rounded to `precision` significant |
4392 | * digits using rounding mode `rounding`. |
4393 | * |
4394 | * x {number|string|Decimal} |
4395 | * y {number|string|Decimal} |
4396 | * |
4397 | */ |
4398 | function div(x, y) { |
4399 | return new this(x).div(y); |
4400 | } |
4401 | |
4402 | |
4403 | /* |
4404 | * Return a new Decimal whose value is the natural exponential of `x`, rounded to `precision` |
4405 | * significant digits using rounding mode `rounding`. |
4406 | * |
4407 | * x {number|string|Decimal} The power to which to raise the base of the natural log. |
4408 | * |
4409 | */ |
4410 | function exp(x) { |
4411 | return new this(x).exp(); |
4412 | } |
4413 | |
4414 | |
4415 | /* |
4416 | * Return a new Decimal whose value is `x` round to an integer using `ROUND_FLOOR`. |
4417 | * |
4418 | * x {number|string|Decimal} |
4419 | * |
4420 | */ |
4421 | function floor(x) { |
4422 | return finalise(x = new this(x), x.e + 1, 3); |
4423 | } |
4424 | |
4425 | |
4426 | /* |
4427 | * Return a new Decimal whose value is the square root of the sum of the squares of the arguments, |
4428 | * rounded to `precision` significant digits using rounding mode `rounding`. |
4429 | * |
4430 | * hypot(a, b, ...) = sqrt(a^2 + b^2 + ...) |
4431 | * |
4432 | */ |
4433 | function hypot() { |
4434 | var i, n, |
4435 | t = new this(0); |
4436 | |
4437 | external = false; |
4438 | |
4439 | for (i = 0; i < arguments.length;) { |
4440 | n = new this(arguments[i++]); |
4441 | if (!n.d) { |
4442 | if (n.s) { |
4443 | external = true; |
4444 | return new this(1 / 0); |
4445 | } |
4446 | t = n; |
4447 | } else if (t.d) { |
4448 | t = t.plus(n.times(n)); |
4449 | } |
4450 | } |
4451 | |
4452 | external = true; |
4453 | |
4454 | return t.sqrt(); |
4455 | } |
4456 | |
4457 | |
4458 | /* |
4459 | * Return true if object is a Decimal instance (where Decimal is any Decimal constructor), |
4460 | * otherwise return false. |
4461 | * |
4462 | */ |
4463 | function isDecimalInstance(obj) { |
4464 | return obj instanceof Decimal || obj && obj.name === '[object Decimal]' || false; |
4465 | } |
4466 | |
4467 | |
4468 | /* |
4469 | * Return a new Decimal whose value is the natural logarithm of `x`, rounded to `precision` |
4470 | * significant digits using rounding mode `rounding`. |
4471 | * |
4472 | * x {number|string|Decimal} |
4473 | * |
4474 | */ |
4475 | function ln(x) { |
4476 | return new this(x).ln(); |
4477 | } |
4478 | |
4479 | |
4480 | /* |
4481 | * Return a new Decimal whose value is the log of `x` to the base `y`, or to base 10 if no base |
4482 | * is specified, rounded to `precision` significant digits using rounding mode `rounding`. |
4483 | * |
4484 | * log[y](x) |
4485 | * |
4486 | * x {number|string|Decimal} The argument of the logarithm. |
4487 | * y {number|string|Decimal} The base of the logarithm. |
4488 | * |
4489 | */ |
4490 | function log(x, y) { |
4491 | return new this(x).log(y); |
4492 | } |
4493 | |
4494 | |
4495 | /* |
4496 | * Return a new Decimal whose value is the base 2 logarithm of `x`, rounded to `precision` |
4497 | * significant digits using rounding mode `rounding`. |
4498 | * |
4499 | * x {number|string|Decimal} |
4500 | * |
4501 | */ |
4502 | function log2(x) { |
4503 | return new this(x).log(2); |
4504 | } |
4505 | |
4506 | |
4507 | /* |
4508 | * Return a new Decimal whose value is the base 10 logarithm of `x`, rounded to `precision` |
4509 | * significant digits using rounding mode `rounding`. |
4510 | * |
4511 | * x {number|string|Decimal} |
4512 | * |
4513 | */ |
4514 | function log10(x) { |
4515 | return new this(x).log(10); |
4516 | } |
4517 | |
4518 | |
4519 | /* |
4520 | * Return a new Decimal whose value is the maximum of the arguments. |
4521 | * |
4522 | * arguments {number|string|Decimal} |
4523 | * |
4524 | */ |
4525 | function max() { |
4526 | return maxOrMin(this, arguments, 'lt'); |
4527 | } |
4528 | |
4529 | |
4530 | /* |
4531 | * Return a new Decimal whose value is the minimum of the arguments. |
4532 | * |
4533 | * arguments {number|string|Decimal} |
4534 | * |
4535 | */ |
4536 | function min() { |
4537 | return maxOrMin(this, arguments, 'gt'); |
4538 | } |
4539 | |
4540 | |
4541 | /* |
4542 | * Return a new Decimal whose value is `x` modulo `y`, rounded to `precision` significant digits |
4543 | * using rounding mode `rounding`. |
4544 | * |
4545 | * x {number|string|Decimal} |
4546 | * y {number|string|Decimal} |
4547 | * |
4548 | */ |
4549 | function mod(x, y) { |
4550 | return new this(x).mod(y); |
4551 | } |
4552 | |
4553 | |
4554 | /* |
4555 | * Return a new Decimal whose value is `x` multiplied by `y`, rounded to `precision` significant |
4556 | * digits using rounding mode `rounding`. |
4557 | * |
4558 | * x {number|string|Decimal} |
4559 | * y {number|string|Decimal} |
4560 | * |
4561 | */ |
4562 | function mul(x, y) { |
4563 | return new this(x).mul(y); |
4564 | } |
4565 | |
4566 | |
4567 | /* |
4568 | * Return a new Decimal whose value is `x` raised to the power `y`, rounded to precision |
4569 | * significant digits using rounding mode `rounding`. |
4570 | * |
4571 | * x {number|string|Decimal} The base. |
4572 | * y {number|string|Decimal} The exponent. |
4573 | * |
4574 | */ |
4575 | function pow(x, y) { |
4576 | return new this(x).pow(y); |
4577 | } |
4578 | |
4579 | |
4580 | /* |
4581 | * Returns a new Decimal with a random value equal to or greater than 0 and less than 1, and with |
4582 | * `sd`, or `Decimal.precision` if `sd` is omitted, significant digits (or less if trailing zeros |
4583 | * are produced). |
4584 | * |
4585 | * [sd] {number} Significant digits. Integer, 0 to MAX_DIGITS inclusive. |
4586 | * |
4587 | */ |
4588 | function random(sd) { |
4589 | var d, e, k, n, |
4590 | i = 0, |
4591 | r = new this(1), |
4592 | rd = []; |
4593 | |
4594 | if (sd === void 0) sd = this.precision; |
4595 | else checkInt32(sd, 1, MAX_DIGITS); |
4596 | |
4597 | k = Math.ceil(sd / LOG_BASE); |
4598 | |
4599 | if (!this.crypto) { |
4600 | for (; i < k;) rd[i++] = Math.random() * 1e7 | 0; |
4601 | |
4602 | // Browsers supporting crypto.getRandomValues. |
4603 | } else if (crypto.getRandomValues) { |
4604 | d = crypto.getRandomValues(new Uint32Array(k)); |
4605 | |
4606 | for (; i < k;) { |
4607 | n = d[i]; |
4608 | |
4609 | // 0 <= n < 4294967296 |
4610 | // Probability n >= 4.29e9, is 4967296 / 4294967296 = 0.00116 (1 in 865). |
4611 | if (n >= 4.29e9) { |
4612 | d[i] = crypto.getRandomValues(new Uint32Array(1))[0]; |
4613 | } else { |
4614 | |
4615 | // 0 <= n <= 4289999999 |
4616 | // 0 <= (n % 1e7) <= 9999999 |
4617 | rd[i++] = n % 1e7; |
4618 | } |
4619 | } |
4620 | |
4621 | // Node.js supporting crypto.randomBytes. |
4622 | } else if (crypto.randomBytes) { |
4623 | |
4624 | // buffer |
4625 | d = crypto.randomBytes(k *= 4); |
4626 | |
4627 | for (; i < k;) { |
4628 | |
4629 | // 0 <= n < 2147483648 |
4630 | n = d[i] + (d[i + 1] << 8) + (d[i + 2] << 16) + ((d[i + 3] & 0x7f) << 24); |
4631 | |
4632 | // Probability n >= 2.14e9, is 7483648 / 2147483648 = 0.0035 (1 in 286). |
4633 | if (n >= 2.14e9) { |
4634 | crypto.randomBytes(4).copy(d, i); |
4635 | } else { |
4636 | |
4637 | // 0 <= n <= 2139999999 |
4638 | // 0 <= (n % 1e7) <= 9999999 |
4639 | rd.push(n % 1e7); |
4640 | i += 4; |
4641 | } |
4642 | } |
4643 | |
4644 | i = k / 4; |
4645 | } else { |
4646 | throw Error(cryptoUnavailable); |
4647 | } |
4648 | |
4649 | k = rd[--i]; |
4650 | sd %= LOG_BASE; |
4651 | |
4652 | // Convert trailing digits to zeros according to sd. |
4653 | if (k && sd) { |
4654 | n = mathpow(10, LOG_BASE - sd); |
4655 | rd[i] = (k / n | 0) * n; |
4656 | } |
4657 | |
4658 | // Remove trailing words which are zero. |
4659 | for (; rd[i] === 0; i--) rd.pop(); |
4660 | |
4661 | // Zero? |
4662 | if (i < 0) { |
4663 | e = 0; |
4664 | rd = [0]; |
4665 | } else { |
4666 | e = -1; |
4667 | |
4668 | // Remove leading words which are zero and adjust exponent accordingly. |
4669 | for (; rd[0] === 0; e -= LOG_BASE) rd.shift(); |
4670 | |
4671 | // Count the digits of the first word of rd to determine leading zeros. |
4672 | for (k = 1, n = rd[0]; n >= 10; n /= 10) k++; |
4673 | |
4674 | // Adjust the exponent for leading zeros of the first word of rd. |
4675 | if (k < LOG_BASE) e -= LOG_BASE - k; |
4676 | } |
4677 | |
4678 | r.e = e; |
4679 | r.d = rd; |
4680 | |
4681 | return r; |
4682 | } |
4683 | |
4684 | |
4685 | /* |
4686 | * Return a new Decimal whose value is `x` rounded to an integer using rounding mode `rounding`. |
4687 | * |
4688 | * To emulate `Math.round`, set rounding to 7 (ROUND_HALF_CEIL). |
4689 | * |
4690 | * x {number|string|Decimal} |
4691 | * |
4692 | */ |
4693 | function round(x) { |
4694 | return finalise(x = new this(x), x.e + 1, this.rounding); |
4695 | } |
4696 | |
4697 | |
4698 | /* |
4699 | * Return |
4700 | * 1 if x > 0, |
4701 | * -1 if x < 0, |
4702 | * 0 if x is 0, |
4703 | * -0 if x is -0, |
4704 | * NaN otherwise |
4705 | * |
4706 | */ |
4707 | function sign(x) { |
4708 | x = new this(x); |
4709 | return x.d ? (x.d[0] ? x.s : 0 * x.s) : x.s || NaN; |
4710 | } |
4711 | |
4712 | |
4713 | /* |
4714 | * Return a new Decimal whose value is the sine of `x`, rounded to `precision` significant digits |
4715 | * using rounding mode `rounding`. |
4716 | * |
4717 | * x {number|string|Decimal} A value in radians. |
4718 | * |
4719 | */ |
4720 | function sin(x) { |
4721 | return new this(x).sin(); |
4722 | } |
4723 | |
4724 | |
4725 | /* |
4726 | * Return a new Decimal whose value is the hyperbolic sine of `x`, rounded to `precision` |
4727 | * significant digits using rounding mode `rounding`. |
4728 | * |
4729 | * x {number|string|Decimal} A value in radians. |
4730 | * |
4731 | */ |
4732 | function sinh(x) { |
4733 | return new this(x).sinh(); |
4734 | } |
4735 | |
4736 | |
4737 | /* |
4738 | * Return a new Decimal whose value is the square root of `x`, rounded to `precision` significant |
4739 | * digits using rounding mode `rounding`. |
4740 | * |
4741 | * x {number|string|Decimal} |
4742 | * |
4743 | */ |
4744 | function sqrt(x) { |
4745 | return new this(x).sqrt(); |
4746 | } |
4747 | |
4748 | |
4749 | /* |
4750 | * Return a new Decimal whose value is `x` minus `y`, rounded to `precision` significant digits |
4751 | * using rounding mode `rounding`. |
4752 | * |
4753 | * x {number|string|Decimal} |
4754 | * y {number|string|Decimal} |
4755 | * |
4756 | */ |
4757 | function sub(x, y) { |
4758 | return new this(x).sub(y); |
4759 | } |
4760 | |
4761 | |
4762 | /* |
4763 | * Return a new Decimal whose value is the tangent of `x`, rounded to `precision` significant |
4764 | * digits using rounding mode `rounding`. |
4765 | * |
4766 | * x {number|string|Decimal} A value in radians. |
4767 | * |
4768 | */ |
4769 | function tan(x) { |
4770 | return new this(x).tan(); |
4771 | } |
4772 | |
4773 | |
4774 | /* |
4775 | * Return a new Decimal whose value is the hyperbolic tangent of `x`, rounded to `precision` |
4776 | * significant digits using rounding mode `rounding`. |
4777 | * |
4778 | * x {number|string|Decimal} A value in radians. |
4779 | * |
4780 | */ |
4781 | function tanh(x) { |
4782 | return new this(x).tanh(); |
4783 | } |
4784 | |
4785 | |
4786 | /* |
4787 | * Return a new Decimal whose value is `x` truncated to an integer. |
4788 | * |
4789 | * x {number|string|Decimal} |
4790 | * |
4791 | */ |
4792 | function trunc(x) { |
4793 | return finalise(x = new this(x), x.e + 1, 1); |
4794 | } |
4795 | |
4796 | |
4797 | // Create and configure initial Decimal constructor. |
4798 | Decimal = clone(DEFAULTS); |
4799 | |
4800 | Decimal['default'] = Decimal.Decimal = Decimal; |
4801 | |
4802 | // Create the internal constants from their string values. |
4803 | LN10 = new Decimal(LN10); |
4804 | PI = new Decimal(PI); |
4805 | |
4806 | |
4807 | // Export. |
4808 | |
4809 | |
4810 | // AMD. |
4811 | if (typeof define == 'function' && define.amd) { |
4812 | define(function () { |
4813 | return Decimal; |
4814 | }); |
4815 | |
4816 | // Node and other environments that support module.exports. |
4817 | } else if (typeof module != 'undefined' && module.exports) { |
4818 | module.exports = Decimal; |
4819 | |
4820 | // Browser. |
4821 | } else { |
4822 | if (!globalScope) { |
4823 | globalScope = typeof self != 'undefined' && self && self.self == self |
4824 | ? self : Function('return this')(); |
4825 | } |
4826 | |
4827 | noConflict = globalScope.Decimal; |
4828 | Decimal.noConflict = function () { |
4829 | globalScope.Decimal = noConflict; |
4830 | return Decimal; |
4831 | }; |
4832 | |
4833 | globalScope.Decimal = Decimal; |
4834 | } |
4835 | })(this); |
Travelled to 12 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1013878 |
Snippet name: | decimal.js (uncompressed) |
Eternal ID of this version: | #1013878/1 |
Text MD5: | 16058004b7d8e2174bc352a8657c0d75 |
Author: | stefan |
Category: | javax / web |
Type: | Document |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2018-03-09 14:45:34 |
Source code size: | 133522 bytes / 4835 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 362 / 105 |
Referenced in: | [show references] |