From c073be5feb53eaa5ce12edcbc811f8b41a23995b Mon Sep 17 00:00:00 2001 From: Cameron Martin Date: Tue, 29 Mar 2016 10:57:31 +0100 Subject: [PATCH] Changed from throwing strings to throwing custom subtypes of Error --- fraction.js | 30 +++++++++++++++++----- fraction.min.js | 28 ++++++++++----------- tests/fraction.test.js | 57 ++++++++++++++++++++---------------------- 3 files changed, 65 insertions(+), 50 deletions(-) diff --git a/fraction.js b/fraction.js index acb652e..a5cd01b 100644 --- a/fraction.js +++ b/fraction.js @@ -41,7 +41,7 @@ "use strict"; - // Maximum search depth for cyclic rational numbers. 2000 should be more than enough. + // Maximum search depth for cyclic rational numbers. 2000 should be more than enough. // Example: 1/7 = 0.(142857) has 6 repeating decimal places. // If MAX_CYCLE_LEN gets reduced, long cycles will not be detected and toString() only gets the first 10 digits var MAX_CYCLE_LEN = 2000; @@ -53,6 +53,24 @@ "d": 1 }; + function createError(name) { + var errorConstructor = function() { + var temp = Error.apply(this, arguments); + temp.name = this.name = name; + this.stack = temp.stack; + this.message = temp.message; + } + + var IntermediateInheritor = function() {}; + IntermediateInheritor.prototype = Error.prototype; + errorConstructor.prototype = new IntermediateInheritor(); + + return errorConstructor; + } + + var DivisionByZero = Fraction['DivisionByZero'] = createError('DivisionByZero'); + var InvalidParameter = Fraction['InvalidParameter'] = createError('InvalidParameter'); + function assign(n, s) { if (isNaN(n = parseInt(n, 10))) { @@ -62,7 +80,7 @@ } function throwInvalidParam() { - throw "Invalid Param"; + throw new InvalidParameter(); } var parse = function(p1, p2) { @@ -221,7 +239,7 @@ } if (d === 0) { - throw "DIV/0"; + throw new DivisionByZero(); } P["s"] = s < 0 ? -1 : 1; @@ -253,7 +271,7 @@ // If we would like to compute really large numbers quicker, we could make use of Fermat's little theorem: // 10^(d-1) % d == 1 - // However, we don't need such large numbers and MAX_CYCLE_LEN should be the capstone, + // However, we don't need such large numbers and MAX_CYCLE_LEN should be the capstone, // as we want to translate the numbers to strings. var rem = 10 % d; @@ -437,7 +455,7 @@ parse(a, b); if (0 === P["n"] && 0 === this["d"]) { - Fraction(0, 0); // Throw div/0 + Fraction(0, 0); // Throw DivisionByZero } /* @@ -669,7 +687,7 @@ /** * Returns an array of continued fraction elements - * + * * Ex: new Fraction("7/8").toContinued() => [0,1,7] */ 'toContinued': function() { diff --git a/fraction.min.js b/fraction.min.js index 56e4af7..f362f95 100644 --- a/fraction.min.js +++ b/fraction.min.js @@ -1,17 +1,17 @@ /* -Fraction.js v3.3.0 09/09/2015 -http://www.xarg.org/2014/03/precise-calculations-in-javascript/ + Fraction.js v3.3.0 09/09/2015 + http://www.xarg.org/2014/03/precise-calculations-in-javascript/ -Copyright (c) 2015, Robert Eisele (robert@xarg.org) -Dual licensed under the MIT or GPL Version 2 licenses. + Copyright (c) 2015, Robert Eisele (robert@xarg.org) + Dual licensed under the MIT or GPL Version 2 licenses. */ -(function(w){"use strict";function u(a,c){if(!a)return c;if(!c)return a;for(;;){a%=c;if(!a)return c;c%=a;if(!c)return a}}function x(a){for(;0===a%2;a/=2);for(;0===a%5;a/=5);if(1===a)return 0;for(var c=10%a,b=1;1!==c;b++)if(c=10*c%a,2E3 -a&&(e=a,a=-a);if(0===a%1)b=a;else if(0=g&&1E7>=r;)if(b=(f+t)/(g+r),a===b){1E7>=g+r?(b=f+t,l=g+r):r>g?(b=t,l=r):(b=f,l=g);break}else a>b?(f+=t,g+=r):(t+=f,r+=g),1E7e?-1:1;d.n=Math.abs(b);d.d=Math.abs(l)}function p(a,c){isNaN(a=parseInt(a,10))&&v(); -return a*c}function v(){throw"Invalid Param";}function e(a,c){if(!(this instanceof e))return new e(a,c);k(a,c);e.REDUCE?a=u(d.d,d.n):a=1;this.s=d.s;this.n=d.n/a;this.d=d.d/a}var d={s:1,n:0,d:1};e.REDUCE=1;e.prototype={s:1,n:0,d:1,abs:function(){return new e(this.n,this.d)},neg:function(){return new e(-this.s*this.n,this.d)},add:function(a,c){k(a,c);return new e(this.s*this.n*d.d+d.s*this.d*d.n,this.d*d.d)},sub:function(a,c){k(a,c);return new e(this.s*this.n*d.d-d.s*this.d*d.n,this.d*d.d)},mul:function(a, -c){k(a,c);return new e(this.s*d.s*this.n*d.n,this.d*d.d)},div:function(a,c){k(a,c);return new e(this.s*d.s*this.n*d.d,this.d*d.n)},clone:function(){return new e(this)},mod:function(a,c){if(isNaN(this.n)||isNaN(this.d))return new e(NaN);if(void 0===a)return new e(this.s*this.n%this.d,1);k(a,c);0===d.n&&0===this.d&&e(0,0);return new e(this.s*d.d*this.n%(d.n*this.d),d.d*this.d)},gcd:function(a,c){k(a,c);return new e(u(d.n,this.n),d.d*this.d/u(d.d,this.d))},lcm:function(a,c){k(a,c);return 0===d.n&&0=== -this.n?new e:new e(d.n*this.n/u(d.n,this.n),u(d.d,this.d))},ceil:function(a){a=Math.pow(10,a||0);return isNaN(this.n)||isNaN(this.d)?new e(NaN):new e(Math.ceil(a*this.s*this.n/this.d),a)},floor:function(a){a=Math.pow(10,a||0);return isNaN(this.n)||isNaN(this.d)?new e(NaN):new e(Math.floor(a*this.s*this.n/this.d),a)},round:function(a){a=Math.pow(10,a||0);return isNaN(this.n)||isNaN(this.d)?new e(NaN):new e(Math.round(a*this.s*this.n/this.d),a)},inverse:function(){return new e(this.s*this.d,this.n)}, -pow:function(a){return 0>a?new e(Math.pow(this.s*this.d,-a),Math.pow(this.n,-a)):new e(Math.pow(this.s*this.n,a),Math.pow(this.d,a))},equals:function(a,c){k(a,c);return this.s*this.n*d.d===d.s*d.n*this.d},compare:function(a,c){k(a,c);var b=this.s*this.n*d.d-d.s*d.n*this.d;return(0b)},divisible:function(a,c){k(a,c);return!(!(d.n*this.d)||this.n*d.d%(d.n*this.d))},valueOf:function(){return this.s*this.n/this.d},toFraction:function(a){var c,b="",l=this.n,e=this.d;0>this.s&&(b+="-");1===e?b+=l: -(a&&0<(c=Math.floor(l/e))&&(b=b+c+" ",l%=e),b+=l,b+="/",b+=e);return b},toLatex:function(a){var c,b="",e=this.n,d=this.d;0>this.s&&(b+="-");1===d?b+=e:(a&&0<(c=Math.floor(e/d))&&(b+=c,e%=d),b=b+"\\frac{"+e,b+="}{",b+=d,b+="}");return b},toContinued:function(){var a,c=this.n,b=this.d,e=[];do e.push(Math.floor(c/b)),a=c%b,c=b,b=a;while(1!==c);return e},toString:function(){var a,c=this.n,b=this.d;if(isNaN(c)||isNaN(b))return"NaN";e.REDUCE||(a=u(c,b),c/=a,b/=a);a=String(c).split("");var c=0,d=[~this.s? -"":"-","",""],k="",p=x(b),n;a:{n=1;var m;m=p;for(var h=10,q=1;0>=1)m&1&&(q=q*h%b);m=q;for(h=0;300>h;h++){if(n===m){n=h;break a}n=10*n%b;m=10*m%b}n=0}m=-1;for(var h=1,q=10+p+n+a.length,f=0;f=b?(d[h]+=k+(c/b|0),k="",c%=b):1a&&(e=a,a=-a);if(0===a%1)b=a;else if(0=g&&1E7>=r;)if(b=(f+t)/(g+r),a===b){1E7>=g+r?(b=f+t,m=g+r):r>g?(b=t,m=r):(b=f,m=g);break}else a>b?(f+=t,g+=r):(t+=f,r+=g),1E7e?-1:1;d.n=Math.abs(b);d.d=Math.abs(m)}function w(a){function c(){} +function b(){var b=Error.apply(this,arguments);b.name=this.name=a;this.stack=b.stack;this.message=b.message}c.prototype=Error.prototype;b.prototype=new c;return b}function p(a,c){if(isNaN(a=parseInt(a,10)))throw new v;return a*c}function e(a,c){if(!(this instanceof e))return new e(a,c);k(a,c);a=e.REDUCE?u(d.d,d.n):1;this.s=d.s;this.n=d.n/a;this.d=d.d/a}var d={s:1,n:0,d:1},z=e.DivisionByZero=w("DivisionByZero"),v=e.InvalidParameter=w("InvalidParameter");e.REDUCE=1;e.prototype={s:1,n:0,d:1,abs:function(){return new e(this.n, +this.d)},neg:function(){return new e(-this.s*this.n,this.d)},add:function(a,c){k(a,c);return new e(this.s*this.n*d.d+d.s*this.d*d.n,this.d*d.d)},sub:function(a,c){k(a,c);return new e(this.s*this.n*d.d-d.s*this.d*d.n,this.d*d.d)},mul:function(a,c){k(a,c);return new e(this.s*d.s*this.n*d.n,this.d*d.d)},div:function(a,c){k(a,c);return new e(this.s*d.s*this.n*d.d,this.d*d.n)},clone:function(){return new e(this)},mod:function(a,c){if(isNaN(this.n)||isNaN(this.d))return new e(NaN);if(void 0===a)return new e(this.s* +this.n%this.d,1);k(a,c);0===d.n&&0===this.d&&e(0,0);return new e(this.s*d.d*this.n%(d.n*this.d),d.d*this.d)},gcd:function(a,c){k(a,c);return new e(u(d.n,this.n),d.d*this.d/u(d.d,this.d))},lcm:function(a,c){k(a,c);return 0===d.n&&0===this.n?new e:new e(d.n*this.n/u(d.n,this.n),u(d.d,this.d))},ceil:function(a){a=Math.pow(10,a||0);return isNaN(this.n)||isNaN(this.d)?new e(NaN):new e(Math.ceil(a*this.s*this.n/this.d),a)},floor:function(a){a=Math.pow(10,a||0);return isNaN(this.n)||isNaN(this.d)?new e(NaN): +new e(Math.floor(a*this.s*this.n/this.d),a)},round:function(a){a=Math.pow(10,a||0);return isNaN(this.n)||isNaN(this.d)?new e(NaN):new e(Math.round(a*this.s*this.n/this.d),a)},inverse:function(){return new e(this.s*this.d,this.n)},pow:function(a){return 0>a?new e(Math.pow(this.s*this.d,-a),Math.pow(this.n,-a)):new e(Math.pow(this.s*this.n,a),Math.pow(this.d,a))},equals:function(a,c){k(a,c);return this.s*this.n*d.d===d.s*d.n*this.d},compare:function(a,c){k(a,c);var b=this.s*this.n*d.d-d.s*d.n*this.d; +return(0b)},divisible:function(a,c){k(a,c);return!(!(d.n*this.d)||this.n*d.d%(d.n*this.d))},valueOf:function(){return this.s*this.n/this.d},toFraction:function(a){var c,b="",e=this.n,d=this.d;0>this.s&&(b+="-");1===d?b+=e:(a&&0<(c=Math.floor(e/d))&&(b=b+c+" ",e%=d),b+=e,b+="/",b+=d);return b},toLatex:function(a){var c,b="",e=this.n,d=this.d;0>this.s&&(b+="-");1===d?b+=e:(a&&0<(c=Math.floor(e/d))&&(b+=c,e%=d),b=b+"\\frac{"+e,b+="}{",b+=d,b+="}");return b},toContinued:function(){var a,c=this.n, +b=this.d,e=[];do e.push(Math.floor(c/b)),a=c%b,c=b,b=a;while(1!==c);return e},toString:function(){var a,c=this.n,b=this.d;if(isNaN(c)||isNaN(b))return"NaN";e.REDUCE||(a=u(c,b),c/=a,b/=a);a=String(c).split("");var c=0,d=[~this.s?"":"-","",""],k="",p=y(b),n;a:{n=1;var l;l=p;for(var h=10,q=1;0>=1)l&1&&(q=q*h%b);l=q;for(h=0;300>h;h++){if(n===l){n=h;break a}n=10*n%b;l=10*l%b}n=0}l=-1;for(var h=1,q=10+p+n+a.length,f=0;f=b?(d[h]+=k+(c/b|0),k="",c%=b):1