From 7818dff1caf5d2aa9b6946df779716f80a306fdb Mon Sep 17 00:00:00 2001 From: Michael Mclaughlin Date: Tue, 26 Feb 2019 23:27:35 +0000 Subject: [PATCH] v10.1.0 #122 Add custom `util.inspect()` function. Add `Symbol.toStringTag`. #121 Constructor: add range check for arguments of type number and Decimal. Remove premable from uglifyjs build script. Move *decimal.min.js.map* to root directory. --- .travis.yml | 2 ++ CHANGELOG.md | 8 +++++++ LICENCE.md | 2 +- decimal.js | 57 ++++++++++++++++++++++++++++++++++++---------- decimal.min.js | 4 +++- decimal.min.js.map | 1 + decimal.mjs | 52 ++++++++++++++++++++++++++++++++++-------- package.json | 4 ++-- 8 files changed, 105 insertions(+), 25 deletions(-) create mode 100644 decimal.min.js.map diff --git a/.travis.yml b/.travis.yml index 890eac0..c3a5d72 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,8 @@ language: node_js node_js: - "node" + - "11" + - "10" - "9" - "8" - "7" diff --git a/CHANGELOG.md b/CHANGELOG.md index 309e202..e8fab12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +#### 10.1.0 +* 26/02/2019 +* #122 Add custom `util.inspect()` function. +* Add `Symbol.toStringTag`. +* #121 Constructor: add range check for arguments of type number and Decimal. +* Remove premable from uglifyjs build script. +* Move *decimal.min.js.map* to root directory. + #### 10.0.2 * 13/12/2018 * #114 Remove soureMappingURL from *decimal.min.js*. diff --git a/LICENCE.md b/LICENCE.md index 0228516..3c39f85 100644 --- a/LICENCE.md +++ b/LICENCE.md @@ -1,6 +1,6 @@ The MIT Licence. -Copyright (c) 2018 Michael Mclaughlin +Copyright (c) 2019 Michael Mclaughlin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/decimal.js b/decimal.js index f67f26a..e552888 100644 --- a/decimal.js +++ b/decimal.js @@ -1,13 +1,12 @@ -/*! decimal.js v10.0.2 https://github.com/MikeMcl/decimal.js/LICENCE */ ;(function (globalScope) { 'use strict'; /* - * decimal.js v10.0.2 + * decimal.js v10.1.0 * An arbitrary-precision Decimal type for JavaScript. * https://github.com/MikeMcl/decimal.js - * Copyright (c) 2018 Michael Mclaughlin + * Copyright (c) 2019 Michael Mclaughlin * MIT Licence */ @@ -2112,7 +2111,6 @@ }; - /* * Returns a new Decimal whose value is the nearest multiple of `y` in the direction of rounding * mode `rm`, or `Decimal.rounding` if `rm` is omitted, to the value of this Decimal. @@ -4259,8 +4257,27 @@ // Duplicate. if (v instanceof Decimal) { x.s = v.s; - x.e = v.e; - x.d = (v = v.d) ? v.slice() : v; + + if (external) { + if (!v.d || v.e > Decimal.maxE) { + + // Infinity. + x.e = NaN; + x.d = null; + } else if (v.e < Decimal.minE) { + + // Zero. + x.e = 0; + x.d = [0]; + } else { + x.e = v.e; + x.d = v.d.slice(); + } + } else { + x.e = v.e; + x.d = v.d ? v.d.slice() : v.d; + } + return; } @@ -4284,8 +4301,23 @@ // Fast path for small integers. if (v === ~~v && v < 1e7) { for (e = 0, i = v; i >= 10; i /= 10) e++; - x.e = e; - x.d = [v]; + + if (external) { + if (e > Decimal.maxE) { + x.e = NaN; + x.d = null; + } else if (e < Decimal.minE) { + x.e = 0; + x.d = [0]; + } else { + x.e = e; + x.d = [v]; + } + } else { + x.e = e; + x.d = [v]; + } + return; // Infinity, NaN. @@ -4367,7 +4399,6 @@ Decimal.tanh = tanh; // ES6 Decimal.trunc = trunc; // ES6 - if (obj === void 0) obj = {}; if (obj) { if (obj.defaults !== true) { @@ -4810,9 +4841,11 @@ // Node and other environments that support module.exports. } else if (typeof module != 'undefined' && module.exports) { - Decimal.prototype[Symbol.for('nodejs.util.inspect.custom')] = function() { - return this.toString(); - }; + if (Symbol && typeof Symbol.iterator == 'symbol') { + P[Symbol.for('nodejs.util.inspect.custom')] = P.toString; + P[Symbol.toStringTag] = 'Decimal'; + } + module.exports = Decimal; // Browser. diff --git a/decimal.min.js b/decimal.min.js index d1e5022..8bb343b 100644 --- a/decimal.min.js +++ b/decimal.min.js @@ -1 +1,3 @@ -!function(n){"use strict";var a,S,e,o,u=9e15,g=1e9,w="0123456789abcdef",t="2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840422862486334095254650828067566662873690987816894829072083255546808437998948262331985283935053089653777326288461633662222876982198867465436674744042432743651550489343149393914796194044002221051017141748003688084012647080685567743216228355220114804663715659121373450747856947683463616792101806445070648000277502684916746550586856935673420670581136429224554405758925724208241314695689016758940256776311356919292033376587141660230105703089634572075440370847469940168269282808481184289314848524948644871927809676271275775397027668605952496716674183485704422507197965004714951050492214776567636938662976979522110718264549734772662425709429322582798502585509785265383207606726317164309505995087807523710333101197857547331541421808427543863591778117054309827482385045648019095610299291824318237525357709750539565187697510374970888692180205189339507238539205144634197265287286965110862571492198849978748873771345686209167058",r="3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632789",c={precision:20,rounding:4,modulo:1,toExpNeg:-7,toExpPos:21,minE:-u,maxE:u,crypto:!1},N=!0,f="[DecimalError] ",m=f+"Invalid argument: ",s=f+"Precision limit exceeded",h=f+"crypto unavailable",L=Math.floor,v=Math.pow,d=/^0b([01]+(\.[01]*)?|\.[01]+)(p[+-]?\d+)?$/i,l=/^0x([0-9a-f]+(\.[0-9a-f]*)?|\.[0-9a-f]+)(p[+-]?\d+)?$/i,p=/^0o([0-7]+(\.[0-7]*)?|\.[0-7]+)(p[+-]?\d+)?$/i,b=/^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,U=1e7,_=7,x=t.length-1,E=r.length-1,y={name:"[object Decimal]"};function M(n){var e,i,t,r=n.length-1,s="",o=n[0];if(0i-1&&(void 0===s[t+1]&&(s[t+1]=0),s[t+1]+=s[t]/i|0,s[t]%=i)}return s.reverse()}y.absoluteValue=y.abs=function(){var n=new this.constructor(this);return n.s<0&&(n.s=1),k(n)},y.ceil=function(){return k(new this.constructor(this),this.e+1,2)},y.comparedTo=y.cmp=function(n){var e,i,t,r,s=this,o=s.d,u=(n=new s.constructor(n)).d,c=s.s,f=n.s;if(!o||!u)return c&&f?c!==f?c:o===u?0:!o^c<0?1:-1:NaN;if(!o[0]||!u[0])return o[0]?c:u[0]?-f:0;if(c!==f)return c;if(s.e!==n.e)return s.e>n.e^c<0?1:-1;for(e=0,i=(t=o.length)<(r=u.length)?t:r;eu[e]^c<0?1:-1;return t===r?0:rthis.d.length-2},y.isNaN=function(){return!this.s},y.isNegative=y.isNeg=function(){return this.s<0},y.isPositive=y.isPos=function(){return 0e&&(e=this.e+1)):e=NaN,e},y.round=function(){var n=this.constructor;return k(new n(this),this.e+1,n.rounding)},y.sine=y.sin=function(){var n,e,i=this,t=i.constructor;return i.isFinite()?i.isZero()?new t(i):(n=t.precision,e=t.rounding,t.precision=n+Math.max(i.e,i.sd())+_,t.rounding=1,i=function(n,e){var i,t=e.d.length;if(t<3)return W(n,2,e,e);i=16<(i=1.4*Math.sqrt(t))?16:0|i,e=e.times(Math.pow(5,-i)),e=W(n,2,e,e);for(var r,s=new n(5),o=new n(16),u=new n(20);i--;)r=e.times(e),e=e.times(s.plus(r.times(o.times(r).minus(u))));return e}(t,J(t,i)),t.precision=n,t.rounding=e,k(2=n.d.length-1&&(i=f<0?-f:f)<=9007199254740991)return r=I(c,u,i,t),n.s<0?new c(1).div(r):k(r,t,s);if((o=u.s)<0){if(ec.maxE+1||e=r.toExpPos):(q(n,1,g),void 0===e?e=r.rounding:q(e,0,8),A(t=k(new r(t),n,e),n<=t.e||t.e<=r.toExpNeg,n)),t.isNeg()&&!t.isZero()?"-"+i:i},y.toSignificantDigits=y.toSD=function(n,e){var i=this.constructor;return void 0===n?(n=i.precision,e=i.rounding):(q(n,1,g),void 0===e?e=i.rounding:q(e,0,8)),k(new i(this),n,e)},y.toString=function(){var n=this,e=n.constructor,i=A(n,n.e<=e.toExpNeg||n.e>=e.toExpPos);return n.isNeg()&&!n.isZero()?"-"+i:i},y.truncated=y.trunc=function(){return k(new this.constructor(this),this.e+1,1)},y.valueOf=y.toJSON=function(){var n=this,e=n.constructor,i=A(n,n.e<=e.toExpNeg||n.e>=e.toExpPos);return n.isNeg()?"-"+i:i};var F=function(){function Z(n,e,i){var t,r=0,s=n.length;for(n=n.slice();s--;)t=n[s]*e+r,n[s]=t%i|0,r=t/i|0;return r&&n.unshift(r),n}function P(n,e,i,t){var r,s;if(i!=t)s=te[r]?1:-1;break}return s}function R(n,e,i,t){for(var r=0;i--;)n[i]-=r,r=n[i](F[c]||0)&&u--,null==i?(N=i=O.precision,t=O.rounding):N=r?i+(n.e-e.e)+1:i,N<0)g.push(1),a=!0;else{if(N=N/h+2|0,c=0,1==M){for(A=A[f=0],N++;(c=s/2&&++y;f=0,(o=P(A,w,M,m))<0?(v=w[0],M!=m&&(v=v*s+(w[1]||0)),1<(f=v/y|0)?(s<=f&&(f=s-1),1==(o=P(d=Z(A,f,s),w,l=d.length,m=w.length))&&(f--,R(d,Ml.maxE?(n.d=null,n.e=NaN):n.en.constructor.maxE?(n.d=null,n.e=NaN):n.er-1;)a[i]=0,i||(++s,a.unshift(1));for(c=a.length;!a[c-1];--c);for(o=0,h="";oc)for(s-=c;s--;)h+="0";else se)return n.length=e,!0}function K(n){return new this(n).abs()}function Q(n){return new this(n).acos()}function X(n){return new this(n).acosh()}function Y(n,e){return new this(n).plus(e)}function nn(n){return new this(n).asin()}function en(n){return new this(n).asinh()}function tn(n){return new this(n).atan()}function rn(n){return new this(n).atanh()}function sn(n,e){n=new this(n),e=new this(e);var i,t=this.precision,r=this.rounding,s=t+4;return n.s&&e.s?n.d||e.d?!e.d||n.isZero()?(i=e.s<0?R(this,t,r):new this(0)).s=n.s:!n.d||e.isZero()?(i=R(this,s,1).times(.5)).s=n.s:i=e.s<0?(this.precision=s,this.rounding=1,i=this.atan(F(n,e,s,1)),e=R(this,s,1),this.precision=t,this.rounding=r,n.s<0?i.minus(e):i.plus(e)):this.atan(F(n,e,s,1)):(i=R(this,s,1).times(0i-1&&(void 0===s[t+1]&&(s[t+1]=0),s[t+1]+=s[t]/i|0,s[t]%=i)}return s.reverse()}y.absoluteValue=y.abs=function(){var n=new this.constructor(this);return n.s<0&&(n.s=1),_(n)},y.ceil=function(){return _(new this.constructor(this),this.e+1,2)},y.comparedTo=y.cmp=function(n){var e,i,t,r,s=this,o=s.d,u=(n=new s.constructor(n)).d,c=s.s,f=n.s;if(!o||!u)return c&&f?c!==f?c:o===u?0:!o^c<0?1:-1:NaN;if(!o[0]||!u[0])return o[0]?c:u[0]?-f:0;if(c!==f)return c;if(s.e!==n.e)return s.e>n.e^c<0?1:-1;for(e=0,i=(t=o.length)<(r=u.length)?t:r;eu[e]^c<0?1:-1;return t===r?0:rthis.d.length-2},y.isNaN=function(){return!this.s},y.isNegative=y.isNeg=function(){return this.s<0},y.isPositive=y.isPos=function(){return 0e&&(e=this.e+1)):e=NaN,e},y.round=function(){var n=this.constructor;return _(new n(this),this.e+1,n.rounding)},y.sine=y.sin=function(){var n,e,i=this,t=i.constructor;return i.isFinite()?i.isZero()?new t(i):(n=t.precision,e=t.rounding,t.precision=n+Math.max(i.e,i.sd())+U,t.rounding=1,i=function(n,e){var i,t=e.d.length;if(t<3)return W(n,2,e,e);i=16<(i=1.4*Math.sqrt(t))?16:0|i,e=e.times(Math.pow(5,-i)),e=W(n,2,e,e);for(var r,s=new n(5),o=new n(16),u=new n(20);i--;)r=e.times(e),e=e.times(s.plus(r.times(o.times(r).minus(u))));return e}(t,J(t,i)),t.precision=n,t.rounding=e,_(2=n.d.length-1&&(i=f<0?-f:f)<=9007199254740991)return r=I(c,u,i,t),n.s<0?new c(1).div(r):_(r,t,s);if((o=u.s)<0){if(ec.maxE+1||e=r.toExpPos):(q(n,1,g),void 0===e?e=r.rounding:q(e,0,8),A(t=_(new r(t),n,e),n<=t.e||t.e<=r.toExpNeg,n)),t.isNeg()&&!t.isZero()?"-"+i:i},y.toSignificantDigits=y.toSD=function(n,e){var i=this.constructor;return void 0===n?(n=i.precision,e=i.rounding):(q(n,1,g),void 0===e?e=i.rounding:q(e,0,8)),_(new i(this),n,e)},y.toString=function(){var n=this,e=n.constructor,i=A(n,n.e<=e.toExpNeg||n.e>=e.toExpPos);return n.isNeg()&&!n.isZero()?"-"+i:i},y.truncated=y.trunc=function(){return _(new this.constructor(this),this.e+1,1)},y.valueOf=y.toJSON=function(){var n=this,e=n.constructor,i=A(n,n.e<=e.toExpNeg||n.e>=e.toExpPos);return n.isNeg()?"-"+i:i};var F=function(){function S(n,e,i){var t,r=0,s=n.length;for(n=n.slice();s--;)t=n[s]*e+r,n[s]=t%i|0,r=t/i|0;return r&&n.unshift(r),n}function Z(n,e,i,t){var r,s;if(i!=t)s=te[r]?1:-1;break}return s}function P(n,e,i,t){for(var r=0;i--;)n[i]-=r,r=n[i](F[c]||0)&&u--,null==i?(N=i=O.precision,t=O.rounding):N=r?i+(n.e-e.e)+1:i,N<0)g.push(1),h=!0;else{if(N=N/a+2|0,c=0,1==M){for(A=A[f=0],N++;(c=s/2&&++y;f=0,(o=Z(A,m,M,w))<0?(v=m[0],M!=w&&(v=v*s+(m[1]||0)),1<(f=v/y|0)?(s<=f&&(f=s-1),1==(o=Z(l=S(A,f,s),m,d=l.length,w=m.length))&&(f--,P(l,Md.maxE?(n.d=null,n.e=NaN):n.en.constructor.maxE?(n.d=null,n.e=NaN):n.er-1;)h[i]=0,i||(++s,h.unshift(1));for(c=h.length;!h[c-1];--c);for(o=0,a="";oc)for(s-=c;s--;)a+="0";else se)return n.length=e,!0}function K(n){return new this(n).abs()}function Q(n){return new this(n).acos()}function X(n){return new this(n).acosh()}function Y(n,e){return new this(n).plus(e)}function nn(n){return new this(n).asin()}function en(n){return new this(n).asinh()}function tn(n){return new this(n).atan()}function rn(n){return new this(n).atanh()}function sn(n,e){n=new this(n),e=new this(e);var i,t=this.precision,r=this.rounding,s=t+4;return n.s&&e.s?n.d||e.d?!e.d||n.isZero()?(i=e.s<0?P(this,t,r):new this(0)).s=n.s:!n.d||e.isZero()?(i=P(this,s,1).times(.5)).s=n.s:i=e.s<0?(this.precision=s,this.rounding=1,i=this.atan(F(n,e,s,1)),e=P(this,s,1),this.precision=t,this.rounding=r,n.s<0?i.minus(e):i.plus(e)):this.atan(F(n,e,s,1)):(i=P(this,s,1).times(0s.maxE?(r.e=NaN,r.d=null):n.e + * Copyright (c) 2019 Michael Mclaughlin * MIT Licence - * https://github.com/MikeMcl/decimal.js/LICENCE - * */ @@ -4256,8 +4253,27 @@ function clone(obj) { // Duplicate. if (v instanceof Decimal) { x.s = v.s; - x.e = v.e; - x.d = (v = v.d) ? v.slice() : v; + + if (external) { + if (!v.d || v.e > Decimal.maxE) { + + // Infinity. + x.e = NaN; + x.d = null; + } else if (v.e < Decimal.minE) { + + // Zero. + x.e = 0; + x.d = [0]; + } else { + x.e = v.e; + x.d = v.d.slice(); + } + } else { + x.e = v.e; + x.d = v.d ? v.d.slice() : v.d; + } + return; } @@ -4281,8 +4297,23 @@ function clone(obj) { // Fast path for small integers. if (v === ~~v && v < 1e7) { for (e = 0, i = v; i >= 10; i /= 10) e++; - x.e = e; - x.d = [v]; + + if (external) { + if (e > Decimal.maxE) { + x.e = NaN; + x.d = null; + } else if (e < Decimal.minE) { + x.e = 0; + x.d = [0]; + } else { + x.e = e; + x.d = [v]; + } + } else { + x.e = e; + x.d = [v]; + } + return; // Infinity, NaN. @@ -4785,6 +4816,9 @@ function trunc(x) { } +P[Symbol.for('nodejs.util.inspect.custom')] = P.toString; +P[Symbol.toStringTag] = 'Decimal'; + // Create and configure initial Decimal constructor. export var Decimal = clone(DEFAULTS); diff --git a/package.json b/package.json index cbf94df..3d4b349 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "decimal.js", "description": "An arbitrary-precision Decimal type for JavaScript.", - "version": "10.0.2", + "version": "10.1.0", "keywords": [ "arbitrary", "precision", @@ -30,7 +30,7 @@ "license": "MIT", "scripts": { "test": "node ./test/test.js", - "build": "uglifyjs decimal.js --source-map doc/decimal.js.map -c -m -o decimal.min.js --preamble \"/* decimal.js v10.0.2 https://github.com/MikeMcl/decimal.js/LICENCE */\"" + "build": "uglifyjs decimal.js --source-map url=decimal.min.js.map -c -m -o decimal.min.js" }, "types": "decimal.d.ts" }