diff --git a/BigRational.js b/BigRational.js index 0bbafb2..5f76793 100644 --- a/BigRational.js +++ b/BigRational.js @@ -171,7 +171,7 @@ decPart = decPart.slice(0, -1); } } - if(digits < 1) decPart = ""; + if(digits < 1) decPart = ""; if (this.isNegative()) { intPart = "-"+intPart; } @@ -186,9 +186,9 @@ }; BigRational.prototype.valueOf = function () { - if(!isFinite(+this.num) || !isFinite(+this.denom)) { - return +this.toDecimal(64); - } + if(!isFinite(+this.num) || !isFinite(+this.denom)) { + return +this.toDecimal(64); + } return this.num / this.denom; }; @@ -238,6 +238,18 @@ return new BigRational(bigInt(n), bigInt[1]); } function parse(a, b) { + if( + a!==null + && !(a instanceof BigRational) + && ! bigInt.isInstance(a) + + && a instanceof Object + && typeof a === 'object' + ) + { + b = a["denom"] || a["denominator"]; + a = a["num"] || a["numerator"]; + } if(!a) { return new BigRational(bigInt(0), bigInt[1]); } @@ -253,6 +265,15 @@ var denom; var text = String(a); + var percents = text.split("%"); + if(percents.length>2){ + throw new Error("Invalid input: too many '%' tokens"); + } + if(percents.length>1){ + text = percents[0]; + var percent = true; + } + var texts = text.split("/"); if(texts.length > 2) { throw new Error("Invalid input: too many '/' tokens"); @@ -271,11 +292,11 @@ num = num.subtract(parts[1]); } denom = bigInt(texts[1]); - return reduce(num, denom); + return (percent) ? reduce(num, denom).divide(bigRat('100')) : reduce(num, denom); } - return reduce(bigInt(texts[0]), bigInt(texts[1])); + return (percent) ? reduce(bigInt(texts[0]), bigInt(texts[1])).divide(bigRat('100')) : reduce(bigInt(texts[0]), bigInt(texts[1])); } - return parseDecimal(text); + return (percent) ? parseDecimal(text).divide(bigRat('100')) : parseDecimal(text); } parse.zero = parse(0); diff --git a/test/SpecRunner.html b/test/SpecRunner.html index ece89e0..22ce2bd 100644 --- a/test/SpecRunner.html +++ b/test/SpecRunner.html @@ -12,9 +12,9 @@ - + - + diff --git a/test/spec.js b/test/spec.js index 83853bb..168809d 100644 --- a/test/spec.js +++ b/test/spec.js @@ -140,6 +140,24 @@ describe("BigRational", function () { expect(bigRat(1, 4096).toDecimal(5) === "0.00024").toBe(true); expect(bigRat(-1).toDecimal() === "-1").toBe(true); expect(bigRat(6.543).toDecimal(0) === "6").toBe(true); // Issue #30 + + //test percents + expect(bigRat("0.35%").toDecimal() === "0.0035").toBe(true); // Issue #22 + expect(bigRat("354.25%").toDecimal(2) === "3.54").toBe(true); + expect(bigRat("2_1/3%").toDecimal(64) === "0.0233333333333333333333333333333333333333333333333333333333333333").toBe(true); + expect(bigRat("1/3%").toDecimal(0) === "0").toBe(true); + expect(bigRat("0.00003%").toDecimal() === "0.0000003").toBe(true); + + //test percents + expect(bigRat('0.35%').toString() === "7/2000").toBe(true); // Issue #22 + expect(bigRat("354.25%").toString() === "1417/400").toBe(true); + expect(bigRat("2_1/3%").toString() === "7/300").toBe(true); + expect(bigRat("1/3%").toString() === "1/300").toBe(true); + expect(bigRat("0.00003%").toString() === "3/10000000").toBe(true); + + //test bigrational from json stringify object //Issue #26 + expect(bigRat(JSON.parse(JSON.stringify(bigRat("2_1/3")))).toString() === "7/3").toBe(true); + }); }); describe("toString", function () { @@ -157,4 +175,4 @@ describe("BigRational", function () { expect(+bigRat("1e350").add("1").over("2e350") === 0.5).toBe(true); // Issue #31 }); }); -}); \ No newline at end of file +});