diff --git a/README.md b/README.md index cff57ac..21bab90 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,6 @@ An arbitrary-precision Decimal type for JavaScript. - Includes a `toFraction` and correctly-rounded `exp`, `ln`, `log` and `sqrt` functions - Supports non-integer powers - Works with numbers with or without fraction digits in bases from 2 to 64 inclusive - - Stores values in an accessible decimal floating-point format - No dependencies - Wide platform compatibility: uses JavaScript 1.5 (ECMAScript 3) features only - Comprehensive [documentation](http://mikemcl.github.io/decimal.js/) and test set @@ -27,8 +26,8 @@ those involving division. This library also adds `exp`, `ln` and `log` functions, among others, and supports non-integer powers. Another major difference is that this library enables multiple Decimal constructors to be created - each with their own configuration (e.g. precision and range). This is, however, a significantly - larger library than *bignumber.js* and the even smaller [big.js](https://github.com/MikeMcl/big.js/). + each with their own configuration. This is, however, a significantly larger library than + *bignumber.js* and the even smaller [big.js](https://github.com/MikeMcl/big.js/). ## Load @@ -96,12 +95,17 @@ Like JavaScript's Number type, there are `toExponential`, `toFixed` and `toPreci and a base can be specified for `toString`. - x.toString(16) // 'ff.8' + x.toString(16) // 'ff.8' -There is a `toFraction` method with an optional *maximum denominator* argument +There is a `toFormat` method, - y = new Decimal(355) - pi = y.dividedBy(113) // '3.1415929204' + y = new Decimal(1e6) + y.toFormat(2) // '1,000,000.00' + +a `toFraction` method with an optional *maximum denominator* argument + + z = new Decimal(355) + pi = z.dividedBy(113) // '3.1415929204' pi.toFraction() // [ '7853982301', '2500000000' ] pi.toFraction(1000) // [ '355', '113' ] @@ -111,15 +115,16 @@ and `isNaN` and `isFinite` methods, as `NaN` and `Infinity` are valid `Decimal` y = new Decimal(Infinity) // 'Infinity' x.isNaN() && !y.isNaN() && !x.isFinite() && !y.isFinite() // true -All calculations are rounded to the number of significant digits specified by the `precision` property -of the Decimal constructor and rounded using the rounding mode specified by the `rounding` property. +All calculations are rounded according to the number of significant digits and rounding mode + specified by the `precision` and `rounding` properties of the Decimal constructor. As mentioned above, multiple Decimal constructors can be created, each with their own independent configuration which applies to all Decimal numbers created from it. + // Set the precision and rounding of the default Decimal constructor Decimal.config({ precision: 5, rounding: 4 }) - // constructor is a factory method and it can also accept a configuration object + // Create another Decimal constructor, optionally passing in a configuration object Decimal10 = Decimal.constructor({ precision: 10, rounding: 1 }) x = new Decimal(5) @@ -178,7 +183,7 @@ then will create *decimal.min.js*. -The *decimal.min.js* already present was created with *Microsoft Ajax Minifier 5.8*. +The *decimal.min.js* already present was created with *Microsoft Ajax Minifier 5.11*. ## Feedback @@ -198,6 +203,9 @@ See LICENCE. ## Change Log +####4.0.0 +* 10/11/2014 `toFormat` amended to use `Decimal.format` object for more flexible configuration. + ####3.0.1 * 8/06/2014 Surround crypto require in try catch. See issue #5 diff --git a/decimal.js b/decimal.js index 492f363..3f3fc48 100644 --- a/decimal.js +++ b/decimal.js @@ -1,10 +1,10 @@ -/*! decimal.js v3.0.1 https://github.com/MikeMcl/decimal.js/LICENCE */ +/*! decimal.js v4.0.0 https://github.com/MikeMcl/decimal.js/LICENCE */ ;(function (global) { 'use strict'; /* - * decimal.js v3.0.1 + * decimal.js v4.0.0 * An arbitrary-precision Decimal type for JavaScript. * https://github.com/MikeMcl/decimal.js * Copyright (c) 2014 Michael Mclaughlin @@ -1260,25 +1260,74 @@ /* - * Return a string representing the value of this Decimal in normal notation rounded using - * rounding mode rounding to dp fixed decimal places, with the integer part of the number - * separated into thousands by string sep1 or ',' if sep1 is null or undefined, and the - * fraction part separated into groups of five digits by string sep2. + * Return a string representing the value of this Decimal in fixed-point notation to dp decimal + * places, rounded using rounding mode rm or Decimal.rounding if rm is omitted, and formatted + * according to the following properties of the Decimal.format object. + * + * Decimal.format = { + * decimalSeparator : '.', + * groupSeparator : ',', + * groupSize : 3, + * secondaryGroupSize : 0, + * fractionGroupSeparator : '\xA0', // non-breaking space + * fractionGroupSize : 0 + * }; + * + * If groupFractionDigits is truthy, fraction digits will be separated into 5-digit groupings + * using the space character as separator. * - * [sep1] {string} The grouping separator of the integer part of the number. - * [sep2] {string} The grouping separator of the fraction part of the number. * [dp] {number} Decimal places. Integer, -MAX_DIGITS to MAX_DIGITS inclusive. + * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive * - * Non-breaking thin-space: \u202f - * - * If dp is invalid the error message will incorrectly give the method as toFixed. + * (If dp or rm are invalid the error message will give the offending method call as toFixed.) * */ - P['toFormat'] = function ( sep1, dp, sep2 ) { - var arr = this.toFixed(dp).split('.'); + P['toFormat'] = function( dp, rm ) { + var x = this; + + if ( !x['c'] ) { + return x.toString(); + } + + var i, + isNeg = x['s'] < 0, + format = x['constructor']['format'], + groupSeparator = format['groupSeparator'], + g1 = +format['groupSize'], + g2 = +format['secondaryGroupSize'], + arr = x.toFixed( dp, rm ).split('.'), + intPart = arr[0], + fractionPart = arr[1], + intDigits = isNeg ? intPart.slice(1) : intPart, + len = intDigits.length; + + if (g2) { + len -= ( i = g1, g1 = g2, g2 = i ); + } + + if ( g1 > 0 && len > 0 ) { + i = len % g1 || g1; + intPart = intDigits.substr( 0, i ); + + for ( ; i < len; i += g1 ) { + intPart += groupSeparator + intDigits.substr( i, g1 ); + } + + if ( g2 > 0 ) { + intPart += groupSeparator + intDigits.slice(i); + } - return arr[0].replace( /\B(?=(\d{3})+$)/g, sep1 == null ? ',' : sep1 + '' ) + - ( arr[1] ? '.' + ( sep2 ? arr[1].replace( /\d{5}\B/g, '$&' + sep2 ) : arr[1] ) : '' ); + if (isNeg) { + intPart = '-' + intPart; + } + } + + return fractionPart + ? intPart + format['decimalSeparator'] + ( ( g2 = +format['fractionGroupSize'] ) + ? fractionPart.replace( new RegExp( '\\d{' + g2 + '}\\B', 'g' ), + '$&' + format['fractionGroupSeparator'] ) + : fractionPart ) + : intPart; }; @@ -1566,8 +1615,8 @@ log10(x_significand) = ln(x_significand) / ln(10) */ e = b == 0 || !isFinite(b) - ? mathfloor( yN * ( - Math.log( '0.' + coefficientToString( x['c'] ) ) / Math.LN10 + x['e'] + 1 ) ) + ? mathfloor( yN * ( Math.log( '0.' + coefficientToString( x['c'] ) ) / + Math.LN10 + x['e'] + 1 ) ) : new Decimal( b + '' )['e']; // Estimate may be incorrect e.g.: x: 0.999999999999999999, y: 2.29, e: 0, r.e:-1 @@ -1875,7 +1924,7 @@ n %= LOGBASE; } - k =mathpow( 10, LOGBASE - n ); + k = mathpow( 10, LOGBASE - n ); rd = c[ci] % k | 0; if ( repeating == null ) { @@ -2816,7 +2865,7 @@ been repeated previously) and the first 4 rounding digits 9999? If so, restart the summation with a higher precision, otherwise - E.g. with precision: 12, rounding: 1 + e.g. with precision: 12, rounding: 1 ln(135520028.6126091714265381533) = 18.7246299999 when it should be 18.72463. sd - guard is the index of first rounding digit. @@ -2853,7 +2902,7 @@ Decimal = x['constructor']; // Don't round if sd is null or undefined. - r: if ( sd != i ) { + r: if ( sd != null ) { // Infinity/NaN. if ( !( xc = x['c'] ) ) { @@ -2978,7 +3027,7 @@ for ( ; ; ) { - // Is the digit to be rounded up in the first element of xc. + // Is the digit to be rounded up in the first element of xc? if ( xci == 0 ) { // i will be the length of xc[0] before k is added. @@ -3132,6 +3181,16 @@ * crypto {boolean|number} * modulo {number} * + * format {object} See Decimal.prototype.toFormat + * decimalSeparator {string} + * groupSeparator {string} + * groupSize {number} + * secondaryGroupSize {number} + * groupFractionDigits {boolean|number} + * + * A format object will replace the existing Decimal.format object without any property + * checking. + * * E.g. * Decimal.config({ precision: 20, rounding: 4 }) * @@ -3143,12 +3202,13 @@ parse = Decimal['errors'] ? parseInt : parseFloat; if ( obj == u || typeof obj != 'object' && + // 'config() object expected: {obj}' !ifExceptionsThrow( Decimal, 'object expected', obj, c ) ) { return Decimal; } - // precision {number|number[]} Integer, 1 to MAX_DIGITS inclusive. + // precision {number} Integer, 1 to MAX_DIGITS inclusive. if ( ( v = obj[ p = 'precision' ] ) != u ) { if ( !( outOfRange = v < 1 || v > MAX_DIGITS ) && parse(v) == v ) { @@ -3264,6 +3324,18 @@ } } + // format {object} + if ( ( obj = obj[ p = 'format' ] ) != u ) { + + if ( typeof obj == 'object' ) { + Decimal[p] = obj; + } else { + + // 'config() format object expected: {obj}' + ifExceptionsThrow( Decimal, 'format object expected', obj, c ); + } + } + return Decimal; } @@ -3376,14 +3448,13 @@ if ( typeof n != 'string' ) { - // TODO: modify so regex test below is avoided if type is number. // If n is a number, check if minus zero. n = ( isNum = typeof n == 'number' || toString.call(n) == '[object Number]' ) && n === 0 && 1 / n < 0 ? '-0' : n + ''; } orig = n; - if ( b == e && isValid.test(n) ) { + if ( b == null && isValid.test(n) ) { // Determine sign. x['s'] = n.charAt(0) == '-' ? ( n = n.slice(1), -1 ) : 1; @@ -3404,7 +3475,7 @@ x['s'] = n.charAt(0) == '-' ? ( n = n.replace( /^-(?!-)/, '' ), -1 ) : 1; - if ( b != e ) { + if ( b != null ) { if ( ( b == (b | 0) || !Decimal['errors'] ) && !( outOfRange = !( b >= 2 && b < 65 ) ) ) { @@ -3415,8 +3486,7 @@ // Any number in exponential form will fail due to the e+/-. if ( valid = new RegExp( - '^' + d + '(?:\\.' + d + ')?$', b < 37 ? 'i' : '' ).test(n) - ) { + '^' + d + '(?:\\.' + d + ')?$', b < 37 ? 'i' : '' ).test(n) ) { if (isNum) { @@ -3478,7 +3548,7 @@ } // Exponential form? - if ( ( i = n.search( /e/i ) ) > 0 ) { + if ( ( i = n.search(/e/i) ) > 0 ) { // Determine exponent. if ( e < 0 ) { @@ -3863,19 +3933,19 @@ // The exponent value at and beneath which toString returns exponential notation. // Number type: -7 - Decimal['toExpNeg'] = -7; // 0 to -EXP_LIMIT + Decimal['toExpNeg'] = -7; // 0 to -EXP_LIMIT // The exponent value at and above which toString returns exponential notation. // Number type: 21 - Decimal['toExpPos'] = 21; // 0 to EXP_LIMIT + Decimal['toExpPos'] = 21; // 0 to EXP_LIMIT // The minimum exponent value, beneath which underflow to zero occurs. // Number type: -324 (5e-324) - Decimal['minE'] = -EXP_LIMIT; // -1 to -EXP_LIMIT + Decimal['minE'] = -EXP_LIMIT; // -1 to -EXP_LIMIT // The maximum exponent value, above which overflow to Infinity occurs. // Number type: 308 (1.7976931348623157e+308) - Decimal['maxE'] = EXP_LIMIT; // 1 to EXP_LIMIT + Decimal['maxE'] = EXP_LIMIT; // 1 to EXP_LIMIT // Whether Decimal Errors are ever thrown. Decimal['errors'] = true; // true/false @@ -3883,6 +3953,16 @@ // Whether to use cryptographically-secure random number generation, if available. Decimal['crypto'] = false; // true/false + // Format specification for the Decimal.prototype.toFormat method + Decimal.format = { + decimalSeparator : '.', + groupSeparator : ',', + groupSize : 3, + secondaryGroupSize : 0, + fractionGroupSeparator : '\xA0', // non-breaking space + fractionGroupSize : 0 + }; + /* ********************** END OF CONSTRUCTOR DEFAULT PROPERTIES ********************* */ diff --git a/decimal.min.js b/decimal.min.js index 05872e2..f85a4d6 100644 --- a/decimal.min.js +++ b/decimal.min.js @@ -1,2 +1,2 @@ -/*! decimal.js v3.0.1 https://github.com/MikeMcl/decimal.js/LICENCE */ -(function(n){"use strict";function l(n){for(var t,e,f=1,r=n.length,u=n[0]+"";f=10;e/=10,o++);return e=t-o,e<0?(e+=i,s=0):(s=Math.ceil((e+1)/i),e%=i),o=h(10,i-e),f=n[s]%o|0,u==null?e<3?(e==0?f=f/100|0:e==1&&(f=f/10|0),c=r<4&&f==99999||r>3&&f==49999||f==5e4||f==0):c=(r<4&&f+1==o||r>3&&f+1==o/2)&&(n[s+1]/o/100|0)==h(10,e-2)-1||(f==o/2||f==0)&&(n[s+1]/o/100|0)==0:e<4?(e==0?f=f/1e3|0:e==1?f=f/100|0:e==2&&(f=f/10|0),c=(u||r<4)&&f==9999||!u&&r>3&&f==4999):c=((u||r<4)&&f+1==o||!u&&r>3&&f+1==o/2)&&(n[s+1]/o/1e3|0)==h(10,e-3)-1,c}function k(n,t,i){var r=n.constructor;return t==null||((c=t<0||t>8)||t!==0&&(r.errors?parseInt:parseFloat)(t)!=t)&&!e(r,"rounding mode",t,i,0)?r.rounding:t|0}function d(n,t,i,r){var u=n.constructor;return!(c=t<(r||0)||t>=et+1)&&(t===0||(u.errors?parseInt:parseFloat)(t)==t)||e(u,"argument",t,i,0)}function rt(n,t){var c,v,k,a,i,e,o,y=0,d=0,p=0,u=n.constructor,w=u.ONE,nt=u.rounding,b=u.precision;if(!n.c||!n.c[0]||n.e>17)return new u(n.c?n.c[0]?n.s<0?0:1/0:w:n.s?n.s<0?0:n:NaN);for(t==null?(f=!1,i=b):i=t,o=new u(.03125);n.e>-2;)n=n.times(o),p+=5;for(v=Math.log(h(2,p))/Math.LN10*2+5|0,i+=v,c=a=e=new u(w),u.precision=i;;){if(a=r(a.times(n),i,1),c=c.times(++d),o=e.plus(s(a,c,i,1)),l(o.c).slice(0,i)===l(e.c).slice(0,i)){for(k=p;k--;)e=r(e.times(e),i,1);if(t==null)if(y<3&&g(e.c,i-v,nt,y))u.precision=i+=10,c=a=o=new u(w),d=0,y++;else return r(e,u.precision=b,nt,f=!0);else return u.precision=b,e}e=o}}function nt(n,t,i,u){var f,o,s=n.constructor,e=(n=new s(n)).e;if(t==null?i=0:(r(n,++t,i),i=u?t:t+n.e-e),e=n.e,f=l(n.c),u==1||u==2&&(t<=e||e<=s.toExpNeg)){for(;f.length1&&(f=f.charAt(0)+"."+f.slice(1));f+=(e<0?"e":"e+")+e}else{if(u=f.length,e<0){for(o=i-u;++e;f="0"+f);f="0."+f}else if(++e>u){for(o=i-e,e-=u;e--;f+="0");o>0&&(f+=".")}else o=i-u,e0&&(f+=".");if(o>0)for(;o--;f+="0");}return n.s<0&&n.c[0]?"-"+f:f}function ot(n){var t=n.length-1,r=t*i+1;if(t=n[t]){for(;t%10==0;t/=10,r--);for(t=n[0];t>=10;t/=10,r++);}return r}function e(n,t,i,r,f){if(n.errors){var e=new Error((r||["new Decimal","cmp","div","eq","gt","gte","lt","lte","minus","mod","plus","times","toFraction","pow","random","log","sqrt","toNearest","divToInt"][u?u<0?-u:u:1/u<0?1:0])+"() "+(["number type has more than 15 significant digits","LN10 out of digits"][t]||t+([c?" out of range":" not an integer"," not a boolean or binary digit"][f]||""))+": "+i);e.name="Decimal Error";c=u=0;throw e;}}function st(n,t,i){var r=new n(n.ONE);for(f=!1;;){if(i&1&&(r=r.times(t)),i>>=1,!i)break;t=t.times(t)}return f=!0,r}function p(n,t){var c,a,d,w,b,et,u,h,nt,rt,ut,ot=1,tt=10,i=n,v=i.c,o=i.constructor,it=o.ONE,ft=o.rounding,k=o.precision;if(i.s<0||!v||!v[0]||!i.e&&v[0]==1&&v.length==1)return new o(v&&!v[0]?-1/0:i.s!=1?NaN:v?0:i);if(t==null?(f=!1,u=k):u=t,o.precision=u+=tt,c=l(v),a=c.charAt(0),Math.abs(w=i.e)<15e14){while(a<7&&a!=1||a==1&&c.charAt(1)>3)i=i.times(n),c=l(i.c),a=c.charAt(0),ot++;w=i.e;a>1?(i=new o("0."+c),w++):i=new o(a+"."+c.slice(1))}else return i=new o(a+"."+c.slice(1)),u+2>y.length&&e(o,1,u+2,"ln"),i=p(i,u-tt).plus(new o(y.slice(0,u+2)).times(w+"")),o.precision=k,t==null?r(i,k,ft,f=!0):i;for(rt=i,h=b=i=s(i.minus(it),i.plus(it),u,1),ut=r(i.times(i),u,1),d=3;;){if(b=r(b.times(ut),u,1),nt=h.plus(s(b,new o(d),u,1)),l(nt.c).slice(0,u)===l(h.c).slice(0,u))if(h=h.times(2),w!==0&&(u+2>y.length&&e(o,1,u+2,"ln"),h=h.plus(new o(y.slice(0,u+2)).times(w+""))),h=s(h,new o(ot),u,1),t==null)if(g(h.c,u-tt,ft,et))o.precision=u+=tt,nt=b=i=s(rt.minus(it),rt.plus(it),u,1),ut=r(i.times(i),u,1),d=et=1;else return r(h,o.precision=k,ft,f=!0);else return o.precision=k,h;h=nt;d+=2}}function r(n,t,r,u){var y,c,s,l,p,w,e,a,b=n.constructor;n:if(t!=c){if(!(e=n.c))return n;for(y=1,l=e[0];l>=10;l/=10,y++);if(c=t-y,c<0)c+=i,s=t,p=e[a=0],w=p/h(10,y-s-1)%10|0;else if(a=Math.ceil((c+1)/i),a>=e.length)if(u){for(;e.length<=a;e.push(0));p=w=0;y=1;c%=i;s=c-i+1}else break n;else{for(p=l=e[a],y=1;l>=10;l/=10,y++);c%=i;s=c-i+y;w=s<0?0:o(p/h(10,y-s-1)%10)}if(u=u||t<0||e[a+1]!=null||(s<0?p:p%h(10,y-s-1)),u=r<4?(w||u)&&(r==0||r==(n.s<0?3:2)):w>5||w==5&&(r==4||u||r==6&&(c>0?s>0?p/h(10,y-s):0:e[a-1])%10&1||r==(n.s<0?8:7)),t<1||!e[0])return e.length=0,u?(t-=n.e+1,e[0]=h(10,t%i),n.e=-t||0):e[0]=n.e=0,n;if(c==0?(e.length=a,l=1,a--):(e.length=a+1,l=h(10,i-c),e[a]=s>0?(p/h(10,y-s)%h(10,s)|0)*l:0),u)for(;;)if(a==0){for(c=1,s=e[0];s>=10;s/=10,c++);for(s=e[0]+=l,l=1;s>=10;s/=10,l++);c!=l&&(n.e++,e[0]==v&&(e[0]=1));break}else{if(e[a]+=l,e[a]!=v)break;e[a--]=0;l=1}for(c=e.length;e[--c]===0;e.pop());}return f&&(n.e>b.maxE?n.c=n.e=null:n.eo^r?1:-1;for(i=-1,h=(e=f.length)<(o=s.length)?e:o;++is[i]^r?1:-1;return e==o?0:e>o^r?1:-1},t.decimalPlaces=t.dp=function(){var r,n,t=null;if(r=this.c){if(t=((n=r.length-1)-o(this.e/i))*i,n=r[n])for(;n%10==0;n/=10,t--);t<0&&(t=0)}return t},t.dividedBy=t.div=function(n,t){return u=2,s(this,new this.constructor(n,t))},t.dividedToIntegerBy=t.divToInt=function(n,t){var f=this,i=f.constructor;return u=18,r(s(f,new i(n,t),0,1,1),i.precision,i.rounding)},t.equals=t.eq=function(n,t){return u=3,this.cmp(n,t)===0},t.exponential=t.exp=function(){return rt(this)},t.floor=function(){return r(new this.constructor(this),this.e+1,3)},t.greaterThan=t.gt=function(n,t){return u=4,this.cmp(n,t)>0},t.greaterThanOrEqualTo=t.gte=function(n,t){return u=5,t=this.cmp(n,t),t==1||t===0},t.isFinite=function(){return!!this.c},t.isInteger=t.isInt=function(){return!!this.c&&o(this.e/i)>this.c.length-2},t.isNaN=function(){return!this.s},t.isNegative=t.isNeg=function(){return this.s<0},t.isZero=function(){return!!this.c&&this.c[0]==0},t.lessThan=t.lt=function(n,t){return u=6,this.cmp(n,t)<0},t.lessThanOrEqualTo=t.lte=function(n,t){return u=7,t=this.cmp(n,t),t==-1||t===0},t.logarithm=t.log=function(n,t){var k,i,b,o,it,d,h,a,v,w=this,c=w.constructor,nt=c.precision,tt=c.rounding;if(n==null)n=new c(10),k=!0;else{if(u=15,n=new c(n,t),i=n.c,n.s<0||!i||!i[0]||!n.e&&i[0]==1&&i.length==1)return new c(NaN);k=n.eq(10)}if(i=w.c,w.s<0||!i||!i[0]||!w.e&&i[0]==1&&i.length==1)return new c(i&&!i[0]?-1/0:w.s!=1?NaN:i?0:1/0);if(it=k&&(o=i[0],i.length>1||o!=1&&o!=10&&o!=100&&o!=1e3&&o!=1e4&&o!=1e5&&o!=1e6),f=!1,h=nt+5,a=h+10,d=p(w,h),k?(a>y.length&&e(c,1,a,"log"),b=new c(y.slice(0,a))):b=p(n,h),v=s(d,b,h,1),g(v.c,o=nt,tt))do if(h+=10,d=p(w,h),k?(a=h+10,a>y.length&&e(c,1,a,"log"),b=new c(y.slice(0,a))):b=p(n,h),v=s(d,b,h,1),!it){+l(v.c).slice(o+1,o+15)+1==1e14&&(v=r(v,nt+1,0));break}while(g(v.c,o+=10,tt));return f=!0,r(v,nt,tt)},t.minus=function(n,t){var a,c,p,k,l=this,w=l.constructor,h=l.s;if(u=8,n=new w(n,t),t=n.s,!h||!t)return new w(NaN);if(h!=t)return n.s=-t,l.plus(n);var e=l.c,s=n.c,b=o(n.e/i),y=o(l.e/i),g=w.precision,d=w.rounding;if(!y||!b){if(!e||!s)return e?(n.s=-t,n):new w(s?l:NaN);if(!e[0]||!s[0])return l=s[0]?(n.s=-t,n):new w(e[0]?l:d==3?-0:0),f?r(l,g,d):l}if(e=e.slice(),c=e.length,h=y-b){for((k=h<0)?(h=-h,a=e,c=s.length):(b=y,a=s),(y=Math.ceil(g/i))>c&&(c=y),h>(c+=2)&&(h=c,a.length=1),a.reverse(),t=h;t--;a.push(0));a.reverse()}else for((k=c<(p=s.length))&&(p=c),h=t=0;t0)for(;t--;e[p++]=0);for(y=v-1,t=s.length;t>h;){if(e[--t]=10;t/=10,h++);return n.e=h+b*i-1,f?r(n,g,d):n},t.modulo=t.mod=function(n,t){var h,e,i=this,o=i.constructor,c=o.modulo;return(u=9,n=new o(n,t),t=n.s,h=!i.c||!t||n.c&&!n.c[0],h||!n.c||i.c&&!i.c[0])?h?new o(NaN):r(new o(i),o.precision,o.rounding):(f=!1,c==9?(n.s=1,e=s(i,n,0,3,1),n.s=t,e.s*=t):e=s(i,n,0,c,1),e=e.times(n),f=!0,i.minus(e))},t.naturalLogarithm=t.ln=function(){return p(this)},t.negated=t.neg=function(){var n=new this.constructor(this);return n.s=-n.s||null,r(n)},t.plus=function(n,t){var l,c=this,y=c.constructor,e=c.s;if(u=10,n=new y(n,t),t=n.s,!e||!t)return new y(NaN);if(e!=t)return n.s=-t,c.minus(n);var s=c.c,h=n.c,p=o(n.e/i),a=o(c.e/i),w=y.precision,b=y.rounding;if(!a||!p){if(!s||!h)return new y(e/0);if(!s[0]||!h[0])return c=h[0]?n:new y(s[0]?c:e*0),f?r(c,w,b):c}if(s=s.slice(),e=a-p){for(e<0?(e=-e,l=s,t=h.length):(p=a,l=h,t=s.length),(a=Math.ceil(w/i))>t&&(t=a),e>++t&&(e=t,l.length=1),l.reverse();e--;l.push(0));l.reverse()}for(s.length-h.length<0&&(l=h,h=s,s=l),e=h.length,t=0,a=v;e;s[e]%=a)t=(s[--e]=s[e]+h[e]+t)/a|0;for(t&&(s.unshift(t),++p),e=s.length;s[--e]==0;s.pop());for(n.c=s,e=1,t=s[0];t>=10;t/=10,e++);return n.e=e+p*i-1,f?r(n,w,b):n},t.precision=t.sd=function(n){var t=null,i=this;return n!=t&&n!==!!n&&n!==1&&n!==0&&e(i.constructor,"argument",n,"precision",1),i.c&&(t=ot(i.c),n&&i.e+1>t&&(t=i.e+1)),t},t.round=function(){var n=this,t=n.constructor;return r(new t(n),n.e+1,t.rounding)},t.squareRoot=t.sqrt=function(){var p,n,c,i,y,h,e=this,a=e.c,u=e.s,t=e.e,v=e.constructor,w=new v(.5);if(u!==1||!a||!a[0])return new v(!u||u<0&&(!a||a[0])?NaN:a?e:1/0);for(f=!1,u=Math.sqrt(+e),u==0||u==1/0?(n=l(a),(n.length+t)%2==0&&(n+="0"),u=Math.sqrt(n),t=o((t+1)/2)-(t<0||t%2),u==1/0?n="1e"+t:(n=u.toExponential(),n=n.slice(0,n.indexOf("e")+1)+t),i=new v(n)):i=new v(u.toString()),c=(t=v.precision)+3;;)if(h=i,i=w.times(h.plus(s(e,h,c+2,1))),l(h.c).slice(0,c)===(n=l(i.c)).slice(0,c))if(n=n.slice(c-3,c+1),n!="9999"&&(y||n!="4999")){+n&&(+n.slice(1)||n.charAt(0)!="5")||(r(i,t+1,1),p=!i.times(i).eq(e));break}else{if(!y&&(r(h,t+1,0),h.times(h).eq(e))){i=h;break}c+=4;y=1}return f=!0,r(i,t,v.rounding,p)},t.times=function(n,t){var e,w,y=this,p=y.constructor,c=y.c,l=(u=11,n=new p(n,t),n.c),a=o(y.e/i),s=o(n.e/i),h=y.s;if(t=n.s,n.s=h==t?1:-1,!a&&(!c||!c[0])||!s&&(!l||!l[0]))return new p(!h||!t||c&&!c[0]&&!l||l&&!l[0]&&!c?NaN:!c||!l?n.s/0:n.s*0);for(w=a+s,h=c.length,t=l.length,h-1;a--){for(t=0,s=h+a;s>a;t=t/v|0)t=e[s]+l[a]*c[s-a-1]+t,e[s--]=t%v|0;t&&(e[s]=(e[s]+t)%v)}for(t&&++w,e[0]||e.shift(),s=e.length;!e[--s];e.pop());for(n.c=e,h=1,t=e[0];t>=10;t/=10,h++);return n.e=h+w*i-1,f?r(n,p.precision,p.rounding):n},t.toDecimalPlaces=t.toDP=function(n,t){var i=this;return i=new i.constructor(i),n==null||!d(i,n,"toDP")?i:r(i,(n|0)+i.e+1,k(i,t,"toDP"))},t.toExponential=function(n,t){var i=this;return i.c?nt(i,n!=null&&d(i,n,"toExponential")?n|0:null,n!=null&&k(i,t,"toExponential"),1):i.toString()},t.toFixed=function(n,t){var i,r=this,u=r.constructor,f=u.toExpNeg,e=u.toExpPos;return n!=null&&(n=d(r,n,i="toFixed")?r.e+(n|0):null,t=k(r,t,i)),u.toExpNeg=-(u.toExpPos=1/0),n!=null&&r.c?(i=nt(r,n,t),r.s<0&&r.c&&(r.c[0]?i.indexOf("-")<0&&(i="-"+i):i=i.replace("-",""))):i=r.toString(),u.toExpNeg=f,u.toExpPos=e,i},t.toFormat=function(n,t,i){var r=this.toFixed(t).split(".");return r[0].replace(/\B(?=(\d{3})+$)/g,n==null?",":n+"")+(r[1]?"."+(i?r[1].replace(/\d{5}\B/g,"$&"+i):r[1]):"")},t.toFraction=function(n){var v,r,d,it,a,y,g,nt,b=this,t=b.constructor,p=v=new t(t.ONE),w=y=new t(0),tt=b.c,k=new t(w);if(!tt)return b.toString();for(d=k.e=ot(tt)-b.e-1,k.c[0]=h(10,(g=d%i)<0?i+g:g),(n==null||(!(u=12,a=new t(n)).s||(c=a.cmp(p)<0||!a.c)||t.errors&&o(a.e/i)0)&&(n=d>0?k:p),f=!1,a=new t(l(tt)),g=t.precision,t.precision=d=tt.length*i*2;;){if(nt=s(a,k,0,1,1),r=v.plus(nt.times(w)),r.cmp(n)==1)break;v=w;w=r;p=y.plus(nt.times(r=p));y=r;k=a.minus(nt.times(r=k));a=r}return r=s(n.minus(v),w,0,1,1),y=y.plus(r.times(p)),v=v.plus(r.times(w)),y.s=p.s=b.s,it=s(p,w,d,1).minus(b).abs().cmp(s(y,v,d,1).minus(b).abs())<1?[p+"",w+""]:[y+"",v+""],f=!0,t.precision=g,it},t.toNearest=function(n,t){var i=this,e=i.constructor;return i=new e(i),n==null?(n=new e(e.ONE),t=e.rounding):(u=17,n=new e(n),t=k(i,t,"toNearest")),n.c?i.c&&(n.c[0]?(f=!1,i=s(i,n,0,t<4?[4,5,7,8][t]:t,1).times(n),f=!0,r(i)):i.c=[i.e=0]):i.s&&(n.s&&(n.s=i.s),i=n),i},t.toNumber=function(){var n=this;return+n||(n.s?0*n.s:NaN)},t.toPower=t.pow=function(n,t){var nt,a,b,s,e=this,c=e.constructor,y=e.s,w=+(u=13,n=new c(n,t)),k=w<0?-w:w,v=c.precision,d=c.rounding;if(!e.c||!n.c||(b=!e.c[0])||!n.c[0])return new c(h(b?y*0:+e,w));if(e=new c(e),nt=e.c.length,!e.e&&e.c[0]==e.s&&nt==1)return e;if(t=n.c.length-1,n.e||n.c[0]!=n.s||t)if(a=o(n.e/i),b=a>=t,!b&&y<0)s=new c(NaN);else{if(b&&nt*i*kc.maxE+1||a0?y/0:0);f=!1;c.rounding=e.s=1;k=Math.min(12,(a+"").length);s=rt(n.times(p(e,v+k)),v);s=r(s,v+5,1);g(s.c,v,d)&&(a=v+10,s=r(rt(n.times(p(e,a+k)),a),a+5,1),+l(s.c).slice(v+1,v+15)+1==1e14&&(s=r(s,v+1,0)));s.s=y;f=!0;c.rounding=d}s=r(s,v,d)}else s=r(e,v,d);return s},t.toPrecision=function(n,t){var i=this;return n!=null&&d(i,n,"toPrecision",1)&&i.c?nt(i,--n|0,k(i,t,"toPrecision"),2):i.toString()},t.toSignificantDigits=t.toSD=function(n,t){var i=this,u=i.constructor;return i=new u(i),n==null||!d(i,n,"toSD",1)?r(i,u.precision,u.rounding):r(i,n|0,k(i,t,"toSD"))},t.toString=function(n){var f,t,o,r=this,u=r.constructor,i=r.e;if(i===null)t=r.s?"Infinity":"NaN";else{if(n===f&&(i<=u.toExpNeg||i>=u.toExpPos))return nt(r,null,u.rounding,1);if(t=l(r.c),i<0){for(;++i;t="0"+t);t="0."+t}else if(o=t.length,i>0)if(++i>o)for(i-=o;i--;t+="0");else i1)t=f+"."+t.slice(1);else if(f=="0")return f;if(n!=null)if((c=!(n>=2&&n<65))||n!=(n|0)&&u.errors)e(u,"base",n,"toString",0);else if(t=tt(u,t,n|0,10,r.s),t=="0")return t}return r.s<0?"-"+t:t},t.truncated=t.trunc=function(){return r(new this.constructor(this),this.e+1,1)},t.valueOf=t.toJSON=function(){return this.toString()},tt=function(){function n(n,t,i){for(var u,r=[0],f,e=0,o=n.length;ei-1&&(r[u+1]==null&&(r[u+1]=0),r[u+1]+=r[u]/i|0,r[u]%=i)}return r.reverse()}return function(t,i,r,u,f){var h,a,p,c,e,y,o=i.indexOf("."),l=t.precision,v=t.rounding;for(u<37&&(i=i.toLowerCase()),o>=0&&(i=i.replace(".",""),y=new t(u),c=st(t,y,i.length-o),y.c=n(c.toFixed(),10,r),y.e=y.c.length),e=n(i,u,r),h=a=e.length;e[--a]==0;e.pop());if(!e[0])return"0";if(o<0?h--:(c.c=e,c.e=h,c.s=f,c=s(c,y,l,v,0,r),e=c.c,p=c.r,h=c.e),o=e[l],a=r/2,p=p||e[l+1]!=null,v<4?(o!=null||p)&&(v==0||v==(c.s<0?3:2)):o>a||o==a&&(v==4||p||v==6&&e[l-1]&1||v==(c.s<0?8:7)))for(e.length=l,--r;++e[--l]>r;)e[l]=0,l||(++h,e.unshift(1));else e.length=l;for(a=e.length;!e[--a];);for(o=0,i="";o<=a;i+=it.charAt(e[o++]));if(h<0){for(;++h;i="0"+i);i="0."+i}else if(o=i.length,++h>o)for(h-=o;h--;i+="0");else hr?1:-1;else for(u=f=0;ut[u]?1:-1;break}return f}function u(n,t,i,r){for(var u=0;i--;)n[i]-=u,u=n[i]1;n.shift());}return function(f,e,s,h,c,l){var nt,et,w,rt,ot,y,tt,ft,it,ut,p,b,ht,vt,ct,st,yt,g,lt,at=f.constructor,d=f.s==e.s?1:-1,k=f.c,a=e.c;if(!k||!k[0]||!a||!a[0])return new at(!f.s||!e.s||(k?a&&k[0]==a[0]:!a)?NaN:k&&k[0]==0||!a?d*0:d/0);for(l?(rt=1,et=f.e-e.e):(l=v,rt=i,et=o(f.e/rt)-o(e.e/rt)),g=a.length,st=k.length,it=new at(d),ut=it.c=[],w=0;a[w]==(k[w]||0);w++);if(a[w]>(k[w]||0)&&et--,s==null?(d=s=at.precision,h=at.rounding):d=c?s+(f.e-e.e)+1:s,d<0)ut.push(1),ot=!0;else{if(d=d/rt+2|0,w=0,g==1){for(y=0,a=a[0],d++;(w1&&(a=n(a,y,l),k=n(k,y,l),g=a.length,st=k.length),ct=g,p=k.slice(0,g),b=p.length;b=l/2&&yt++;do y=0,nt=t(a,p,g,b),nt<0?(ht=p[0],g!=b&&(ht=ht*l+(p[1]||0)),y=ht/yt|0,y>1?(y>=l&&(y=l-1),tt=n(a,y,l),ft=tt.length,b=p.length,nt=t(tt,p,ft,b),nt==1&&(y--,u(tt,g=10;d/=10,w++);it.e=w+et*rt-1;r(it,c?s+it.e+1:s,h,ot)}return it}}(),w=function(){function l(n){var i,f,t,r=this,s="config",h=r.errors?parseInt:parseFloat;return n==f||typeof n!="object"&&!e(r,"object expected",n,s)?r:((t=n[i="precision"])!=f&&((c=t<1||t>et)||h(t)!=t?e(r,i,t,s,0):r[i]=t|0),(t=n[i="rounding"])!=f&&((c=t<0||t>8)||h(t)!=t?e(r,i,t,s,0):r[i]=t|0),(t=n[i="toExpNeg"])!=f&&((c=t<-b||t>0)||h(t)!=t?e(r,i,t,s,0):r[i]=o(t)),(t=n[i="toExpPos"])!=f&&((c=t<0||t>b)||h(t)!=t?e(r,i,t,s,0):r[i]=o(t)),(t=n[i="minE"])!=f&&((c=t<-b||t>0)||h(t)!=t?e(r,i,t,s,0):r[i]=o(t)),(t=n[i="maxE"])!=f&&((c=t<0||t>b)||h(t)!=t?e(r,i,t,s,0):r[i]=o(t)),(t=n[i="errors"])!=f&&(t===!!t||t===1||t===0?(c=u=0,r[i]=!!t):e(r,i,t,s,1)),(t=n[i="crypto"])!=f&&(t===!!t||t===1||t===0?r[i]=!!(t&&a&&typeof a=="object"):e(r,i,t,s,1)),(t=n[i="modulo"])!=f&&((c=t<0||t>9)||h(t)!=t?e(r,i,t,s,0):r[i]=t|0),r)}function v(n){return new this(n).exp()}function y(n){return new this(n).ln()}function p(n,t){return new this(n).log(t)}function n(n,t,i){var r,u,f=0;for(ft.call(t[0])=="[object Array]"&&(t=t[0]),r=new n(t[0]);++f=429e7?o[t]=a.getRandomValues(new Uint32Array(1))[0]:f[t++]=u%1e7;else if(a&&a.randomBytes){for(o=a.randomBytes(r*=4);t=214e7?a.randomBytes(4).copy(o,t):(f.push(u%1e7),t+=4);t=r/4}else e(s,"crypto unavailable",a,"random");if(!t)for(;t=10;)u/=10,t++;t=2&&l<65))?(e(o,"base",l,0,0),w=n.test(h)):(b="["+it.slice(0,l=l|0)+"]+",h=h.replace(/\.$/,"").replace(/^\./,"0."),(w=new RegExp("^"+b+"(?:\\."+b+")?$",l<37?"i":"").test(h))?(y&&(h.replace(/^0\.0*|\./,"").length>15&&e(o,0,p),y=!y),h=tt(o,h,10,l,s.s)):h!="Infinity"&&h!="NaN"&&(e(o,"not a base "+l+" number",p),h="NaN")):w=n.test(h),!w)return s.c=s.e=null,h!="Infinity"&&(h!="NaN"&&e(o,"not a number",p),s.s=null),u=0,s}for((v=h.indexOf("."))>-1&&(h=h.replace(".","")),(a=h.search(/e/i))>0?(v<0&&(v=a),v+=+h.slice(a+1),h=h.substring(0,a)):v<0&&(v=h.length),a=0;h.charAt(a)=="0";a++);for(l=h.length;h.charAt(--l)=="0";);if(h=h.slice(a,l+1),h){if(l=h.length,y&&l>15&&e(o,0,p),s.e=v=v-a-1,s.c=[],a=(v+1)%i,v<0&&(a+=i),ao.maxE?s.c=s.e=null:s.e=10;e/=10,o++);return e=t-o,e<0?(e+=i,s=0):(s=Math.ceil((e+1)/i),e%=i),o=h(10,i-e),f=n[s]%o|0,u==null?e<3?(e==0?f=f/100|0:e==1&&(f=f/10|0),c=r<4&&f==99999||r>3&&f==49999||f==5e4||f==0):c=(r<4&&f+1==o||r>3&&f+1==o/2)&&(n[s+1]/o/100|0)==h(10,e-2)-1||(f==o/2||f==0)&&(n[s+1]/o/100|0)==0:e<4?(e==0?f=f/1e3|0:e==1?f=f/100|0:e==2&&(f=f/10|0),c=(u||r<4)&&f==9999||!u&&r>3&&f==4999):c=((u||r<4)&&f+1==o||!u&&r>3&&f+1==o/2)&&(n[s+1]/o/1e3|0)==h(10,e-3)-1,c}function k(n,t,i){var r=n.constructor;return t==null||((c=t<0||t>8)||t!==0&&(r.errors?parseInt:parseFloat)(t)!=t)&&!f(r,"rounding mode",t,i,0)?r.rounding:t|0}function d(n,t,i,r){var u=n.constructor;return!(c=t<(r||0)||t>=et+1)&&(t===0||(u.errors?parseInt:parseFloat)(t)==t)||f(u,"argument",t,i,0)}function rt(n,t){var c,v,k,a,i,f,o,y=0,d=0,p=0,u=n.constructor,w=u.ONE,nt=u.rounding,b=u.precision;if(!n.c||!n.c[0]||n.e>17)return new u(n.c?n.c[0]?n.s<0?0:1/0:w:n.s?n.s<0?0:n:NaN);for(t==null?(e=!1,i=b):i=t,o=new u(.03125);n.e>-2;)n=n.times(o),p+=5;for(v=Math.log(h(2,p))/Math.LN10*2+5|0,i+=v,c=a=f=new u(w),u.precision=i;;){if(a=r(a.times(n),i,1),c=c.times(++d),o=f.plus(s(a,c,i,1)),l(o.c).slice(0,i)===l(f.c).slice(0,i)){for(k=p;k--;)f=r(f.times(f),i,1);if(t==null)if(y<3&&g(f.c,i-v,nt,y))u.precision=i+=10,c=a=o=new u(w),d=0,y++;else return r(f,u.precision=b,nt,e=!0);else return u.precision=b,f}f=o}}function nt(n,t,i,u){var f,o,s=n.constructor,e=(n=new s(n)).e;if(t==null?i=0:(r(n,++t,i),i=u?t:t+n.e-e),e=n.e,f=l(n.c),u==1||u==2&&(t<=e||e<=s.toExpNeg)){for(;f.length1&&(f=f.charAt(0)+"."+f.slice(1));f+=(e<0?"e":"e+")+e}else{if(u=f.length,e<0){for(o=i-u;++e;f="0"+f);f="0."+f}else if(++e>u){for(o=i-e,e-=u;e--;f+="0");o>0&&(f+=".")}else o=i-u,e0&&(f+=".");if(o>0)for(;o--;f+="0");}return n.s<0&&n.c[0]?"-"+f:f}function ot(n){var t=n.length-1,r=t*i+1;if(t=n[t]){for(;t%10==0;t/=10,r--);for(t=n[0];t>=10;t/=10,r++);}return r}function f(n,t,i,r,f){if(n.errors){var e=new Error((r||["new Decimal","cmp","div","eq","gt","gte","lt","lte","minus","mod","plus","times","toFraction","pow","random","log","sqrt","toNearest","divToInt"][u?u<0?-u:u:1/u<0?1:0])+"() "+(["number type has more than 15 significant digits","LN10 out of digits"][t]||t+([c?" out of range":" not an integer"," not a boolean or binary digit"][f]||""))+": "+i);e.name="Decimal Error";c=u=0;throw e;}}function st(n,t,i){var r=new n(n.ONE);for(e=!1;;){if(i&1&&(r=r.times(t)),i>>=1,!i)break;t=t.times(t)}return e=!0,r}function p(n,t){var c,a,d,w,b,et,u,h,nt,rt,ut,ot=1,tt=10,i=n,v=i.c,o=i.constructor,it=o.ONE,ft=o.rounding,k=o.precision;if(i.s<0||!v||!v[0]||!i.e&&v[0]==1&&v.length==1)return new o(v&&!v[0]?-1/0:i.s!=1?NaN:v?0:i);if(t==null?(e=!1,u=k):u=t,o.precision=u+=tt,c=l(v),a=c.charAt(0),Math.abs(w=i.e)<15e14){while(a<7&&a!=1||a==1&&c.charAt(1)>3)i=i.times(n),c=l(i.c),a=c.charAt(0),ot++;w=i.e;a>1?(i=new o("0."+c),w++):i=new o(a+"."+c.slice(1))}else return i=new o(a+"."+c.slice(1)),u+2>y.length&&f(o,1,u+2,"ln"),i=p(i,u-tt).plus(new o(y.slice(0,u+2)).times(w+"")),o.precision=k,t==null?r(i,k,ft,e=!0):i;for(rt=i,h=b=i=s(i.minus(it),i.plus(it),u,1),ut=r(i.times(i),u,1),d=3;;){if(b=r(b.times(ut),u,1),nt=h.plus(s(b,new o(d),u,1)),l(nt.c).slice(0,u)===l(h.c).slice(0,u))if(h=h.times(2),w!==0&&(u+2>y.length&&f(o,1,u+2,"ln"),h=h.plus(new o(y.slice(0,u+2)).times(w+""))),h=s(h,new o(ot),u,1),t==null)if(g(h.c,u-tt,ft,et))o.precision=u+=tt,nt=b=i=s(rt.minus(it),rt.plus(it),u,1),ut=r(i.times(i),u,1),d=et=1;else return r(h,o.precision=k,ft,e=!0);else return o.precision=k,h;h=nt;d+=2}}function r(n,t,r,u){var y,c,s,l,p,w,f,a,b=n.constructor;n:if(t!=null){if(!(f=n.c))return n;for(y=1,l=f[0];l>=10;l/=10,y++);if(c=t-y,c<0)c+=i,s=t,p=f[a=0],w=p/h(10,y-s-1)%10|0;else if(a=Math.ceil((c+1)/i),a>=f.length)if(u){for(;f.length<=a;f.push(0));p=w=0;y=1;c%=i;s=c-i+1}else break n;else{for(p=l=f[a],y=1;l>=10;l/=10,y++);c%=i;s=c-i+y;w=s<0?0:o(p/h(10,y-s-1)%10)}if(u=u||t<0||f[a+1]!=null||(s<0?p:p%h(10,y-s-1)),u=r<4?(w||u)&&(r==0||r==(n.s<0?3:2)):w>5||w==5&&(r==4||u||r==6&&(c>0?s>0?p/h(10,y-s):0:f[a-1])%10&1||r==(n.s<0?8:7)),t<1||!f[0])return f.length=0,u?(t-=n.e+1,f[0]=h(10,t%i),n.e=-t||0):f[0]=n.e=0,n;if(c==0?(f.length=a,l=1,a--):(f.length=a+1,l=h(10,i-c),f[a]=s>0?(p/h(10,y-s)%h(10,s)|0)*l:0),u)for(;;)if(a==0){for(c=1,s=f[0];s>=10;s/=10,c++);for(s=f[0]+=l,l=1;s>=10;s/=10,l++);c!=l&&(n.e++,f[0]==v&&(f[0]=1));break}else{if(f[a]+=l,f[a]!=v)break;f[a--]=0;l=1}for(c=f.length;f[--c]===0;f.pop());}return e&&(n.e>b.maxE?n.c=n.e=null:n.eo^r?1:-1;for(i=-1,h=(e=f.length)<(o=s.length)?e:o;++is[i]^r?1:-1;return e==o?0:e>o^r?1:-1},t.decimalPlaces=t.dp=function(){var r,n,t=null;if(r=this.c){if(t=((n=r.length-1)-o(this.e/i))*i,n=r[n])for(;n%10==0;n/=10,t--);t<0&&(t=0)}return t},t.dividedBy=t.div=function(n,t){return u=2,s(this,new this.constructor(n,t))},t.dividedToIntegerBy=t.divToInt=function(n,t){var f=this,i=f.constructor;return u=18,r(s(f,new i(n,t),0,1,1),i.precision,i.rounding)},t.equals=t.eq=function(n,t){return u=3,this.cmp(n,t)===0},t.exponential=t.exp=function(){return rt(this)},t.floor=function(){return r(new this.constructor(this),this.e+1,3)},t.greaterThan=t.gt=function(n,t){return u=4,this.cmp(n,t)>0},t.greaterThanOrEqualTo=t.gte=function(n,t){return u=5,t=this.cmp(n,t),t==1||t===0},t.isFinite=function(){return!!this.c},t.isInteger=t.isInt=function(){return!!this.c&&o(this.e/i)>this.c.length-2},t.isNaN=function(){return!this.s},t.isNegative=t.isNeg=function(){return this.s<0},t.isZero=function(){return!!this.c&&this.c[0]==0},t.lessThan=t.lt=function(n,t){return u=6,this.cmp(n,t)<0},t.lessThanOrEqualTo=t.lte=function(n,t){return u=7,t=this.cmp(n,t),t==-1||t===0},t.logarithm=t.log=function(n,t){var k,i,b,o,it,d,h,a,v,w=this,c=w.constructor,nt=c.precision,tt=c.rounding;if(n==null)n=new c(10),k=!0;else{if(u=15,n=new c(n,t),i=n.c,n.s<0||!i||!i[0]||!n.e&&i[0]==1&&i.length==1)return new c(NaN);k=n.eq(10)}if(i=w.c,w.s<0||!i||!i[0]||!w.e&&i[0]==1&&i.length==1)return new c(i&&!i[0]?-1/0:w.s!=1?NaN:i?0:1/0);if(it=k&&(o=i[0],i.length>1||o!=1&&o!=10&&o!=100&&o!=1e3&&o!=1e4&&o!=1e5&&o!=1e6),e=!1,h=nt+5,a=h+10,d=p(w,h),k?(a>y.length&&f(c,1,a,"log"),b=new c(y.slice(0,a))):b=p(n,h),v=s(d,b,h,1),g(v.c,o=nt,tt))do if(h+=10,d=p(w,h),k?(a=h+10,a>y.length&&f(c,1,a,"log"),b=new c(y.slice(0,a))):b=p(n,h),v=s(d,b,h,1),!it){+l(v.c).slice(o+1,o+15)+1==1e14&&(v=r(v,nt+1,0));break}while(g(v.c,o+=10,tt));return e=!0,r(v,nt,tt)},t.minus=function(n,t){var a,c,p,k,l=this,w=l.constructor,h=l.s;if(u=8,n=new w(n,t),t=n.s,!h||!t)return new w(NaN);if(h!=t)return n.s=-t,l.plus(n);var f=l.c,s=n.c,b=o(n.e/i),y=o(l.e/i),g=w.precision,d=w.rounding;if(!y||!b){if(!f||!s)return f?(n.s=-t,n):new w(s?l:NaN);if(!f[0]||!s[0])return l=s[0]?(n.s=-t,n):new w(f[0]?l:d==3?-0:0),e?r(l,g,d):l}if(f=f.slice(),c=f.length,h=y-b){for((k=h<0)?(h=-h,a=f,c=s.length):(b=y,a=s),(y=Math.ceil(g/i))>c&&(c=y),h>(c+=2)&&(h=c,a.length=1),a.reverse(),t=h;t--;a.push(0));a.reverse()}else for((k=c<(p=s.length))&&(p=c),h=t=0;t0)for(;t--;f[p++]=0);for(y=v-1,t=s.length;t>h;){if(f[--t]=10;t/=10,h++);return n.e=h+b*i-1,e?r(n,g,d):n},t.modulo=t.mod=function(n,t){var h,f,i=this,o=i.constructor,c=o.modulo;return(u=9,n=new o(n,t),t=n.s,h=!i.c||!t||n.c&&!n.c[0],h||!n.c||i.c&&!i.c[0])?h?new o(NaN):r(new o(i),o.precision,o.rounding):(e=!1,c==9?(n.s=1,f=s(i,n,0,3,1),n.s=t,f.s*=t):f=s(i,n,0,c,1),f=f.times(n),e=!0,i.minus(f))},t.naturalLogarithm=t.ln=function(){return p(this)},t.negated=t.neg=function(){var n=new this.constructor(this);return n.s=-n.s||null,r(n)},t.plus=function(n,t){var l,c=this,y=c.constructor,f=c.s;if(u=10,n=new y(n,t),t=n.s,!f||!t)return new y(NaN);if(f!=t)return n.s=-t,c.minus(n);var s=c.c,h=n.c,p=o(n.e/i),a=o(c.e/i),w=y.precision,b=y.rounding;if(!a||!p){if(!s||!h)return new y(f/0);if(!s[0]||!h[0])return c=h[0]?n:new y(s[0]?c:f*0),e?r(c,w,b):c}if(s=s.slice(),f=a-p){for(f<0?(f=-f,l=s,t=h.length):(p=a,l=h,t=s.length),(a=Math.ceil(w/i))>t&&(t=a),f>++t&&(f=t,l.length=1),l.reverse();f--;l.push(0));l.reverse()}for(s.length-h.length<0&&(l=h,h=s,s=l),f=h.length,t=0,a=v;f;s[f]%=a)t=(s[--f]=s[f]+h[f]+t)/a|0;for(t&&(s.unshift(t),++p),f=s.length;s[--f]==0;s.pop());for(n.c=s,f=1,t=s[0];t>=10;t/=10,f++);return n.e=f+p*i-1,e?r(n,w,b):n},t.precision=t.sd=function(n){var t=null,i=this;return n!=t&&n!==!!n&&n!==1&&n!==0&&f(i.constructor,"argument",n,"precision",1),i.c&&(t=ot(i.c),n&&i.e+1>t&&(t=i.e+1)),t},t.round=function(){var n=this,t=n.constructor;return r(new t(n),n.e+1,t.rounding)},t.squareRoot=t.sqrt=function(){var p,n,c,i,y,h,f=this,a=f.c,u=f.s,t=f.e,v=f.constructor,w=new v(.5);if(u!==1||!a||!a[0])return new v(!u||u<0&&(!a||a[0])?NaN:a?f:1/0);for(e=!1,u=Math.sqrt(+f),u==0||u==1/0?(n=l(a),(n.length+t)%2==0&&(n+="0"),u=Math.sqrt(n),t=o((t+1)/2)-(t<0||t%2),u==1/0?n="1e"+t:(n=u.toExponential(),n=n.slice(0,n.indexOf("e")+1)+t),i=new v(n)):i=new v(u.toString()),c=(t=v.precision)+3;;)if(h=i,i=w.times(h.plus(s(f,h,c+2,1))),l(h.c).slice(0,c)===(n=l(i.c)).slice(0,c))if(n=n.slice(c-3,c+1),n!="9999"&&(y||n!="4999")){+n&&(+n.slice(1)||n.charAt(0)!="5")||(r(i,t+1,1),p=!i.times(i).eq(f));break}else{if(!y&&(r(h,t+1,0),h.times(h).eq(f))){i=h;break}c+=4;y=1}return e=!0,r(i,t,v.rounding,p)},t.times=function(n,t){var f,w,y=this,p=y.constructor,c=y.c,l=(u=11,n=new p(n,t),n.c),a=o(y.e/i),s=o(n.e/i),h=y.s;if(t=n.s,n.s=h==t?1:-1,!a&&(!c||!c[0])||!s&&(!l||!l[0]))return new p(!h||!t||c&&!c[0]&&!l||l&&!l[0]&&!c?NaN:!c||!l?n.s/0:n.s*0);for(w=a+s,h=c.length,t=l.length,h-1;a--){for(t=0,s=h+a;s>a;t=t/v|0)t=f[s]+l[a]*c[s-a-1]+t,f[s--]=t%v|0;t&&(f[s]=(f[s]+t)%v)}for(t&&++w,f[0]||f.shift(),s=f.length;!f[--s];f.pop());for(n.c=f,h=1,t=f[0];t>=10;t/=10,h++);return n.e=h+w*i-1,e?r(n,p.precision,p.rounding):n},t.toDecimalPlaces=t.toDP=function(n,t){var i=this;return i=new i.constructor(i),n==null||!d(i,n,"toDP")?i:r(i,(n|0)+i.e+1,k(i,t,"toDP"))},t.toExponential=function(n,t){var i=this;return i.c?nt(i,n!=null&&d(i,n,"toExponential")?n|0:null,n!=null&&k(i,t,"toExponential"),1):i.toString()},t.toFixed=function(n,t){var i,r=this,u=r.constructor,f=u.toExpNeg,e=u.toExpPos;return n!=null&&(n=d(r,n,i="toFixed")?r.e+(n|0):null,t=k(r,t,i)),u.toExpNeg=-(u.toExpPos=1/0),n!=null&&r.c?(i=nt(r,n,t),r.s<0&&r.c&&(r.c[0]?i.indexOf("-")<0&&(i="-"+i):i=i.replace("-",""))):i=r.toString(),u.toExpNeg=f,u.toExpPos=e,i},t.toFormat=function(n,t){var o=this;if(!o.c)return o.toString();var r,l=o.s<0,f=o.constructor.format,a=f.groupSeparator,u=+f.groupSize,e=+f.secondaryGroupSize,v=o.toFixed(n,t).split("."),i=v[0],c=v[1],s=l?i.slice(1):i,h=s.length;if(e&&(h-=(r=u,u=e,e=r)),u>0&&h>0){for(r=h%u||u,i=s.substr(0,r);r0&&(i+=a+s.slice(r));l&&(i="-"+i)}return c?i+f.decimalSeparator+((e=+f.fractionGroupSize)?c.replace(new RegExp("\\d{"+e+"}\\B","g"),"$&"+f.fractionGroupSeparator):c):i},t.toFraction=function(n){var v,r,d,it,a,y,g,nt,b=this,t=b.constructor,p=v=new t(t.ONE),w=y=new t(0),tt=b.c,k=new t(w);if(!tt)return b.toString();for(d=k.e=ot(tt)-b.e-1,k.c[0]=h(10,(g=d%i)<0?i+g:g),(n==null||(!(u=12,a=new t(n)).s||(c=a.cmp(p)<0||!a.c)||t.errors&&o(a.e/i)0)&&(n=d>0?k:p),e=!1,a=new t(l(tt)),g=t.precision,t.precision=d=tt.length*i*2;;){if(nt=s(a,k,0,1,1),r=v.plus(nt.times(w)),r.cmp(n)==1)break;v=w;w=r;p=y.plus(nt.times(r=p));y=r;k=a.minus(nt.times(r=k));a=r}return r=s(n.minus(v),w,0,1,1),y=y.plus(r.times(p)),v=v.plus(r.times(w)),y.s=p.s=b.s,it=s(p,w,d,1).minus(b).abs().cmp(s(y,v,d,1).minus(b).abs())<1?[p+"",w+""]:[y+"",v+""],e=!0,t.precision=g,it},t.toNearest=function(n,t){var i=this,f=i.constructor;return i=new f(i),n==null?(n=new f(f.ONE),t=f.rounding):(u=17,n=new f(n),t=k(i,t,"toNearest")),n.c?i.c&&(n.c[0]?(e=!1,i=s(i,n,0,t<4?[4,5,7,8][t]:t,1).times(n),e=!0,r(i)):i.c=[i.e=0]):i.s&&(n.s&&(n.s=i.s),i=n),i},t.toNumber=function(){var n=this;return+n||(n.s?0*n.s:NaN)},t.toPower=t.pow=function(n,t){var nt,a,b,s,f=this,c=f.constructor,y=f.s,w=+(u=13,n=new c(n,t)),k=w<0?-w:w,v=c.precision,d=c.rounding;if(!f.c||!n.c||(b=!f.c[0])||!n.c[0])return new c(h(b?y*0:+f,w));if(f=new c(f),nt=f.c.length,!f.e&&f.c[0]==f.s&&nt==1)return f;if(t=n.c.length-1,n.e||n.c[0]!=n.s||t)if(a=o(n.e/i),b=a>=t,!b&&y<0)s=new c(NaN);else{if(b&&nt*i*kc.maxE+1||a0?y/0:0);e=!1;c.rounding=f.s=1;k=Math.min(12,(a+"").length);s=rt(n.times(p(f,v+k)),v);s=r(s,v+5,1);g(s.c,v,d)&&(a=v+10,s=r(rt(n.times(p(f,a+k)),a),a+5,1),+l(s.c).slice(v+1,v+15)+1==1e14&&(s=r(s,v+1,0)));s.s=y;e=!0;c.rounding=d}s=r(s,v,d)}else s=r(f,v,d);return s},t.toPrecision=function(n,t){var i=this;return n!=null&&d(i,n,"toPrecision",1)&&i.c?nt(i,--n|0,k(i,t,"toPrecision"),2):i.toString()},t.toSignificantDigits=t.toSD=function(n,t){var i=this,u=i.constructor;return i=new u(i),n==null||!d(i,n,"toSD",1)?r(i,u.precision,u.rounding):r(i,n|0,k(i,t,"toSD"))},t.toString=function(n){var e,t,o,r=this,u=r.constructor,i=r.e;if(i===null)t=r.s?"Infinity":"NaN";else{if(n===e&&(i<=u.toExpNeg||i>=u.toExpPos))return nt(r,null,u.rounding,1);if(t=l(r.c),i<0){for(;++i;t="0"+t);t="0."+t}else if(o=t.length,i>0)if(++i>o)for(i-=o;i--;t+="0");else i1)t=e+"."+t.slice(1);else if(e=="0")return e;if(n!=null)if((c=!(n>=2&&n<65))||n!=(n|0)&&u.errors)f(u,"base",n,"toString",0);else if(t=tt(u,t,n|0,10,r.s),t=="0")return t}return r.s<0?"-"+t:t},t.truncated=t.trunc=function(){return r(new this.constructor(this),this.e+1,1)},t.valueOf=t.toJSON=function(){return this.toString()},tt=function(){function n(n,t,i){for(var u,r=[0],f,e=0,o=n.length;ei-1&&(r[u+1]==null&&(r[u+1]=0),r[u+1]+=r[u]/i|0,r[u]%=i)}return r.reverse()}return function(t,i,r,u,f){var h,a,p,c,e,y,o=i.indexOf("."),l=t.precision,v=t.rounding;for(u<37&&(i=i.toLowerCase()),o>=0&&(i=i.replace(".",""),y=new t(u),c=st(t,y,i.length-o),y.c=n(c.toFixed(),10,r),y.e=y.c.length),e=n(i,u,r),h=a=e.length;e[--a]==0;e.pop());if(!e[0])return"0";if(o<0?h--:(c.c=e,c.e=h,c.s=f,c=s(c,y,l,v,0,r),e=c.c,p=c.r,h=c.e),o=e[l],a=r/2,p=p||e[l+1]!=null,v<4?(o!=null||p)&&(v==0||v==(c.s<0?3:2)):o>a||o==a&&(v==4||p||v==6&&e[l-1]&1||v==(c.s<0?8:7)))for(e.length=l,--r;++e[--l]>r;)e[l]=0,l||(++h,e.unshift(1));else e.length=l;for(a=e.length;!e[--a];);for(o=0,i="";o<=a;i+=it.charAt(e[o++]));if(h<0){for(;++h;i="0"+i);i="0."+i}else if(o=i.length,++h>o)for(h-=o;h--;i+="0");else hr?1:-1;else for(u=f=0;ut[u]?1:-1;break}return f}function u(n,t,i,r){for(var u=0;i--;)n[i]-=u,u=n[i]1;n.shift());}return function(f,e,s,h,c,l){var nt,et,w,rt,ot,y,tt,ft,it,ut,p,b,ht,vt,ct,st,yt,g,lt,at=f.constructor,d=f.s==e.s?1:-1,k=f.c,a=e.c;if(!k||!k[0]||!a||!a[0])return new at(!f.s||!e.s||(k?a&&k[0]==a[0]:!a)?NaN:k&&k[0]==0||!a?d*0:d/0);for(l?(rt=1,et=f.e-e.e):(l=v,rt=i,et=o(f.e/rt)-o(e.e/rt)),g=a.length,st=k.length,it=new at(d),ut=it.c=[],w=0;a[w]==(k[w]||0);w++);if(a[w]>(k[w]||0)&&et--,s==null?(d=s=at.precision,h=at.rounding):d=c?s+(f.e-e.e)+1:s,d<0)ut.push(1),ot=!0;else{if(d=d/rt+2|0,w=0,g==1){for(y=0,a=a[0],d++;(w1&&(a=n(a,y,l),k=n(k,y,l),g=a.length,st=k.length),ct=g,p=k.slice(0,g),b=p.length;b=l/2&&yt++;do y=0,nt=t(a,p,g,b),nt<0?(ht=p[0],g!=b&&(ht=ht*l+(p[1]||0)),y=ht/yt|0,y>1?(y>=l&&(y=l-1),tt=n(a,y,l),ft=tt.length,b=p.length,nt=t(tt,p,ft,b),nt==1&&(y--,u(tt,g=10;d/=10,w++);it.e=w+et*rt-1;r(it,c?s+it.e+1:s,h,ot)}return it}}(),w=function(){function l(n){var i,e,t,r=this,s="config",h=r.errors?parseInt:parseFloat;return n==e||typeof n!="object"&&!f(r,"object expected",n,s)?r:((t=n[i="precision"])!=e&&((c=t<1||t>et)||h(t)!=t?f(r,i,t,s,0):r[i]=t|0),(t=n[i="rounding"])!=e&&((c=t<0||t>8)||h(t)!=t?f(r,i,t,s,0):r[i]=t|0),(t=n[i="toExpNeg"])!=e&&((c=t<-b||t>0)||h(t)!=t?f(r,i,t,s,0):r[i]=o(t)),(t=n[i="toExpPos"])!=e&&((c=t<0||t>b)||h(t)!=t?f(r,i,t,s,0):r[i]=o(t)),(t=n[i="minE"])!=e&&((c=t<-b||t>0)||h(t)!=t?f(r,i,t,s,0):r[i]=o(t)),(t=n[i="maxE"])!=e&&((c=t<0||t>b)||h(t)!=t?f(r,i,t,s,0):r[i]=o(t)),(t=n[i="errors"])!=e&&(t===!!t||t===1||t===0?(c=u=0,r[i]=!!t):f(r,i,t,s,1)),(t=n[i="crypto"])!=e&&(t===!!t||t===1||t===0?r[i]=!!(t&&a&&typeof a=="object"):f(r,i,t,s,1)),(t=n[i="modulo"])!=e&&((c=t<0||t>9)||h(t)!=t?f(r,i,t,s,0):r[i]=t|0),(n=n[i="format"])!=e&&(typeof n=="object"?r[i]=n:f(r,"format object expected",n,s)),r)}function v(n){return new this(n).exp()}function y(n){return new this(n).ln()}function p(n,t){return new this(n).log(t)}function n(n,t,i){var r,u,f=0;for(ft.call(t[0])=="[object Array]"&&(t=t[0]),r=new n(t[0]);++f=429e7?o[t]=a.getRandomValues(new Uint32Array(1))[0]:e[t++]=u%1e7;else if(a&&a.randomBytes){for(o=a.randomBytes(r*=4);t=214e7?a.randomBytes(4).copy(o,t):(e.push(u%1e7),t+=4);t=r/4}else f(s,"crypto unavailable",a,"random");if(!t)for(;t=10;)u/=10,t++;t=2&&l<65))?(f(o,"base",l,0,0),w=n.test(h)):(b="["+it.slice(0,l=l|0)+"]+",h=h.replace(/\.$/,"").replace(/^\./,"0."),(w=new RegExp("^"+b+"(?:\\."+b+")?$",l<37?"i":"").test(h))?(y&&(h.replace(/^0\.0*|\./,"").length>15&&f(o,0,p),y=!y),h=tt(o,h,10,l,s.s)):h!="Infinity"&&h!="NaN"&&(f(o,"not a base "+l+" number",p),h="NaN")):w=n.test(h),!w)return s.c=s.e=null,h!="Infinity"&&(h!="NaN"&&f(o,"not a number",p),s.s=null),u=0,s}for((v=h.indexOf("."))>-1&&(h=h.replace(".","")),(a=h.search(/e/i))>0?(v<0&&(v=a),v+=+h.slice(a+1),h=h.substring(0,a)):v<0&&(v=h.length),a=0;h.charAt(a)=="0";a++);for(l=h.length;h.charAt(--l)=="0";);if(h=h.slice(a,l+1),h){if(l=h.length,y&&l>15&&f(o,0,p),s.e=v=v-a-1,s.c=[],a=(v+1)%i,v<0&&(a+=i),ao.maxE?s.c=s.e=null:s.eerrors
  • modulo
  • crypto
  • +
  • format
  •  
  • ROUND_UP
  • ROUND_DOWN
  • @@ -348,7 +349,15 @@ Decimal.config({ maxE: 9e15, errors: true, crypto: false, - modulo: 1 + modulo: 1, + format: { + decimalSeparator : '.', + groupSeparator : ',', + groupSize : 3, + secondaryGroupSize : 0, + fractionGroupSeparator : '\xA0', // non-breaking space + fractionGroupSize : 0 + } })

    The properties of a Decimal constructor can also be set by direct assignment, but that will @@ -553,13 +562,16 @@ x.equals(y) // true rounding, minE, maxE, toExpNeg, toExpPos, errors, - modulo and crypto are - set using the config method. + modulo, crypto and + format are set using the + config method.

    As simple object properties they can be set directly without using config, and it is fine to do so, but the values assigned - will not then be checked for validity. For example: + will not then be checked for validity (the properties of the + format object are not checked by + config). For example:

    Decimal.config({ precision: 0 })
     // 'Decimal Error: config() precision out of range: 0'
    @@ -851,6 +863,47 @@ Decimal.config({ crypto: true })
    +
    format
    +

    object +

    + The format object configures the format of the string returned by the + toFormat method. +

    +

    + The example below shows the properties of the format object + that are recognised, and their default values. +

    +

    + Unlike setting other properties using config, the values of the + properties of the format object will not be checked for validity. The existing + format object will simply be replaced by the object that is passed in. Only the + toFormat method ever references a Decimal constructor's + format object property. +

    +

    + See toFormat for examples of usage, and of setting + format properties individually and directly without using config. +

    +
    +Decimal.config({
    +    format : {
    +        // the decimal separator
    +        decimalSeparator : '.',
    +        // the grouping separator of the integer part of the number
    +        groupSeparator : ',',
    +        // the primary grouping size of the integer part of the number
    +        groupSize : 3,
    +        // the secondary grouping size of the integer part of the number
    +        secondaryGroupSize : 0,
    +        // the grouping separator of the fraction part of the number
    +        fractionGroupSeparator : ' ',
    +        // the grouping size of the fraction part of the number
    +        fractionGroupSize : 0
    +    }
    +});
    + + +
    Rounding modes

    The library's enumerated rounding modes are stored as properties of a Decimal constructor. @@ -1617,47 +1670,61 @@ y.toFixed(5) // '3.45600'

    - toFormat.toFormat([sep1 [, dp [, sep2]]]) ⇒ string + toFormat.toFormat([dp [, rm]]) ⇒ string

    - sep1: string: the grouping separator of the integer part of the number -
    - sep2: string: the grouping separator of the fraction part of the number -
    - dp: number: integer, 0 to 8 inclusive -

    -

    - - This method is a placeholder and is likely to be subject to change / further development. - -

    -

    - Returns a string representing the value of this Decimal to dp decimal places, - (see toFixed), but with the integer part of the number - separated by sep1 into groups of three digits, and the fraction part of the - number separated into groups of five digits by sep2. + dp: number: integer, 0 to 1e+9 inclusive
    + rm: number: integer, 0 to 8 inclusive

    - If sep1 is null or undefined, the integer part groupings will be - separated by a comma. + Returns a string representing the value of this Decimal in fixed-point notation rounded to + dp decimal places using rounding mode rm (as + toFixed), and formatted according to the properties of this + Decimal's constructor's format object property.

    - If sep2 is null or undefined, the fraction part groupings will not - be separated. + See the examples below for the properties of the format + object, their types and their usage.

    If dp is omitted or is null or undefined, then the return value is not rounded to a fixed number of decimal places.

    -

    A useful separator character is the non-breaking thin-space: \u202f.

    +

    + if rm is omitted or is null or undefined, rounding mode + rounding is used. +

    -x = new Decimal('1.23456000000000000000789e+9')
    -x.toFormat()                     // '1,234,560,000.00000000000789'
    -x.toFormat(' ')                  // '1 234 560 000.00000000000789'
    -x.toFormat(',', 2)               // '1,234,560,000.00'
    -x.toFormat(' ', 2)               // '1 234 560 000.00'
    -x.toFormat(',', 12, ' ')         // '1 ,234,560,000.00000 00000 08'
    -x.toFormat('-', 14, '-')         // '1-234-560-000.00000-00000-0789'
    +// Using config to assign values to the format object +Decimal.config({ + format : { + decimalSeparator : '.', + groupSeparator : ',', + groupSize : 3, + secondaryGroupSize : 0, + fractionGroupSeparator : ' ', + fractionGroupSize : 0 + } +}); + +x = new Decimal('123456789.123456789') +x.toFormat() // '123,456,789.123456789' +x.toFormat(1) // '123,456,789.1' + +// Assigning the format properties directly +Decimal.format.groupSeparator = ' '; +Decimal.format.fractionGroupSize = 5; +x.toFormat() // '123 456 789.12345 6789' + +// Assigning the format object directly +Decimal.format = { + decimalSeparator = ',', + groupSeparator = '.', + groupSize = 3, + secondaryGroupSize = 2 +} + +x.toFormat() // '12.34.56.789,123456789' diff --git a/package.json b/package.json index 7aea6d6..8b7cf4f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "decimal.js", "description": "An arbitrary-precision Decimal type for JavaScript.", - "version": "3.0.1", + "version": "4.0.0", "keywords": [ "arbitrary", "precision", @@ -31,6 +31,6 @@ "license": "MIT", "scripts": { "test": "node ./test/every-test.js", - "build": "uglifyjs decimal.js -c -m -o decimal.min.js --preamble '/* decimal.js v3.0.1 https://github.com/MikeMcl/decimal.js/LICENCE */'" + "build": "uglifyjs decimal.js -c -m -o decimal.min.js --preamble '/* decimal.js v4.0.0 https://github.com/MikeMcl/decimal.js/LICENCE */'" } } \ No newline at end of file diff --git a/test/toFormat.js b/test/toFormat.js index 7fddc3c..ca1a375 100644 --- a/test/toFormat.js +++ b/test/toFormat.js @@ -49,8 +49,8 @@ var count = (function toFormat(Decimal) { } } - function T(expected, value, sep1, dp, sep2){ - assert(String(expected), new Decimal(value).toFormat(sep1, dp, sep2)); + function T(expected, value, dp){ + assert(expected, new Decimal(value).toFormat(dp)); } log('\n Testing toFormat...'); @@ -62,32 +62,40 @@ var count = (function toFormat(Decimal) { toExpPos: 9e15, minE: -9e15, maxE: 9e15, - errors: true + errors: true, + format: { + decimalSeparator : '.', + groupSeparator : ',', + groupSize : 3, + secondaryGroupSize : 0, + fractionGroupSeparator : ' ', + fractionGroupSize : 0 + } }); - T(0, 0); - T(1, 1); - T(-1, -1); - T(123.456, 123.456); - T(NaN, NaN); - T(Infinity, 1/0); - T(-Infinity, -1/0); - - T(0, 0, ' '); - T(1, 1, ' '); - T(-1, -1, ' '); - T(123.456, 123.456, ' '); - T(NaN, NaN, ' '); - T(Infinity, 1/0, ' '); - T(-Infinity, -1/0, ' '); - - T('0.0', 0, ' ', 1); - T('1.00', 1, ' ', 2); - T('-1.000', -1, ' ', 3); - T('123.4560', 123.456, ' ', 4); - T(NaN, NaN, ' ', 5); - T(Infinity, 1/0, ' ', 6); - T(-Infinity, -1/0, ' ', 7); + T('0', 0); + T('1', 1); + T('-1', -1); + T('123.456', 123.456); + T('NaN', NaN); + T('Infinity', 1/0); + T('-Infinity', -1/0); + + T('0', 0, null); + T('1', 1, undefined); + T('-1', -1, 0); + T('123.456', 123.456, 3); + T('NaN', NaN, 0); + T('Infinity', 1/0, 3); + T('-Infinity', -1/0, 0); + + T('0.0', 0, 1); + T('1.00', 1, 2); + T('-1.000', -1, 3); + T('123.4560', 123.456, 4); + T('NaN', NaN, 5); + T('Infinity', 1/0, 6); + T('-Infinity', -1/0, 7); T('9,876.54321', 9876.54321); T('4,018,736,400,000,000,000,000', '4.0187364e+21'); @@ -108,42 +116,125 @@ var count = (function toFormat(Decimal) { T('99', 99); T('9', 9); - T('999 999 999 999 999', 999999999999999, ' ', 0, ' '); - T('99 999 999 999 999.0', 99999999999999, ' ', 1, ' '); - T('9 999 999 999 999.00', 9999999999999, ' ', 2, ' '); - T('999 999 999 999.000', 999999999999, ' ', 3, ' '); - T('99 999 999 999.0000', 99999999999, ' ', 4, ' '); - T('9 999 999 999.00000', 9999999999, ' ', 5, ' '); - T('999 999 999.00000 0', 999999999, ' ', 6, ' '); - T('99 999 999.00000 00', 99999999, ' ', 7, ' '); - T('9 999 999.00000 000', 9999999, ' ', 8, ' '); - T('999 999.00000 0000', 999999, ' ', 9, ' '); - T('99 999.00000 00000', 99999, ' ', 10, ' '); - T('9 999.00000 00000 0', 9999, ' ', 11, ' '); - T('999.00000 00000 00', 999, ' ', 12, ' '); - T('99.00000 00000 000', 99, ' ', 13, ' '); - T('9.00000 00000 0000', 9, ' ', 14, ' '); - - T('1.00000 00000 00000', 1, ' ', 15, ' '); - T('1.00000 00000 0000', 1, ' ', 14, ' '); - T('1.00000 00000 000', 1, ' ', 13, ' '); - T('1.00000 00000 00', 1, ' ', 12, ' '); - T('1.00000 00000 0', 1, ' ', 11, ' '); - T('1.00000 00000', 1, ' ', 10, ' '); - T('1.00000 0000', 1, ' ', 9, ' '); - T('76,852.342091', '7.6852342091e+4'); - T('4 018 736 400 000 000 000 000', '4.0187364e+21', ' '); - T('76 852.342091', '7.6852342091e+4', ' '); - T('76 852.34', '7.6852342091e+4', ' ', 2); - T('76 852.34209 10871 45832 64089', '7.685234209108714583264089e+4', ' ', 20, ' '); - T('76 852.34209 10871 45832 64089 7', '7.6852342091087145832640897e+4', ' ', 21, ' '); - T('76 852.34209 10871 45832 64089 70000', '7.6852342091087145832640897e+4', ' ', 25, ' '); - T('76 852.34', '7.6852342091087145832640897e+4', ' ', 2, ' '); + Decimal.format.groupSeparator = ' '; + + T('76 852.34', '7.6852342091e+4', 2); + T('76 852.342091', '7.6852342091e+4'); + T('76 852.3420910871', '7.6852342091087145832640897e+4', 10); + + Decimal.format.fractionGroupSize = 5; + + T('4 018 736 400 000 000 000 000', '4.0187364e+21'); + T('76 852.34209 10871 45832 64089', '7.685234209108714583264089e+4', 20); + T('76 852.34209 10871 45832 64089 7', '7.6852342091087145832640897e+4', 21); + T('76 852.34209 10871 45832 64089 70000', '7.6852342091087145832640897e+4', 25); + + T('999 999 999 999 999', 999999999999999, 0); + T('99 999 999 999 999.0', 99999999999999, 1); + T('9 999 999 999 999.00', 9999999999999, 2); + T('999 999 999 999.000', 999999999999, 3); + T('99 999 999 999.0000', 99999999999, 4); + T('9 999 999 999.00000', 9999999999, 5); + T('999 999 999.00000 0', 999999999, 6); + T('99 999 999.00000 00', 99999999, 7); + T('9 999 999.00000 000', 9999999, 8); + T('999 999.00000 0000', 999999, 9); + T('99 999.00000 00000', 99999, 10); + T('9 999.00000 00000 0', 9999, 11); + T('999.00000 00000 00', 999, 12); + T('99.00000 00000 000', 99, 13); + T('9.00000 00000 0000', 9, 14); + + T('1.00000 00000 00000', 1, 15); + T('1.00000 00000 0000', 1, 14); + T('1.00000 00000 000', 1, 13); + T('1.00000 00000 00', 1, 12); + T('1.00000 00000 0', 1, 11); + T('1.00000 00000', 1, 10); + T('1.00000 0000', 1, 9); + + Decimal.format.fractionGroupSize = 0; + + T('4 018 736 400 000 000 000 000', '4.0187364e+21'); + T('76 852.34209108714583264089', '7.685234209108714583264089e+4', 20); + T('76 852.342091087145832640897', '7.6852342091087145832640897e+4', 21); + T('76 852.3420910871458326408970000', '7.6852342091087145832640897e+4', 25); + + T('999 999 999 999 999', 999999999999999, 0); + T('99 999 999 999 999.0', 99999999999999, 1); + T('9 999 999 999 999.00', 9999999999999, 2); + T('999 999 999 999.000', 999999999999, 3); + T('99 999 999 999.0000', 99999999999, 4); + T('9 999 999 999.00000', 9999999999, 5); + T('999 999 999.000000', 999999999, 6); + T('99 999 999.0000000', 99999999, 7); + T('9 999 999.00000000', 9999999, 8); + T('999 999.000000000', 999999, 9); + T('99 999.0000000000', 99999, 10); + T('9 999.00000000000', 9999, 11); + T('999.000000000000', 999, 12); + T('99.0000000000000', 99, 13); + T('9.00000000000000', 9, 14); + + T('1.000000000000000', 1, 15); + T('1.00000000000000', 1, 14); + T('1.0000000000000', 1, 13); + T('1.000000000000', 1, 12); + T('1.00000000000', 1, 11); + T('1.0000000000', 1, 10); + T('1.000000000', 1, 9); + + Decimal.config({ + format: { + decimalSeparator : '.', + groupSeparator : ',', + groupSize : 3, + secondaryGroupSize : 2 + } + }); + + T('9,876.54321', 9876.54321); + T('10,00,037.123', '1000037.123456789', 3); + T('4,01,87,36,40,00,00,00,00,00,000', '4.0187364e+21'); + + T('99,99,99,99,99,99,999', 999999999999999); + T('9,99,99,99,99,99,999', 99999999999999); + T('99,99,99,99,99,999', 9999999999999); + T('9,99,99,99,99,999', 999999999999); + T('99,99,99,99,999', 99999999999); + T('9,99,99,99,999', 9999999999); + T('99,99,99,999', 999999999); + T('9,99,99,999', 99999999); + T('99,99,999', 9999999); + T('9,99,999', 999999); + T('99,999', 99999); + T('9,999', 9999); + T('999', 999); + T('99', 99); + T('9', 9); + + Decimal.format.decimalSeparator = ','; + Decimal.format.groupSeparator = '.'; + + T('1.23.45.60.000,000000000008', '1.23456000000000000000789e+9', 12); + + Decimal.format.groupSeparator = ''; + + T('10000000000123456789000000,0000000001', '10000000000123456789000000.000000000100000001', 10); + + Decimal.format.groupSeparator = ' '; + Decimal.format.groupSize = 1; + Decimal.format.secondaryGroupSize = 4; + + T('4658 0734 6509 8347 6580 3645 0,6', '4658073465098347658036450.59764985763489569875659876459', 1); + + Decimal.format.fractionGroupSize = 2; + Decimal.format.fractionGroupSeparator = ':'; + Decimal.format.secondaryGroupSize = null; - T('1,234,560,000.00000 00000 08', '1.23456000000000000000789e+9', ',', 12, ' '); - T('1-234-560-000.00000-00000-0789', '1.23456000000000000000789e+9', '-', 14, '-'); + T('4 6 5 8 0 7 3 4 6 5 0 9 8 3 4 7 6 5 8 0 3 6 4 5 0,59:76:49:85:76:34:89:56:98:75:65:98:76:45:9', '4658073465098347658036450.59764985763489569875659876459' ); log('\n ' + passed + ' of ' + total + ' tests passed in ' + (+new Date() - start) + ' ms \n'); return [passed, total];