From 090d188fbf4aebdf46cc8a279547ed8cdf328862 Mon Sep 17 00:00:00 2001 From: danprince <danielprince@hotmail.co.uk> Date: Sun, 30 Aug 2015 17:40:16 +0100 Subject: [PATCH 1/3] fix(filters): Fixes rounding bug with numbers close to limit for scientific notation Adds an if statement to the formatNumber function to prevent the safe decimal rounding from happening to numbers that will be converted into scientific notation. --- src/ng/filter/filters.js | 11 +++++++---- test/ng/filter/filtersSpec.js | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/ng/filter/filters.js b/src/ng/filter/filters.js index 7805085fd7d6..89d3638010d1 100644 --- a/src/ng/filter/filters.js +++ b/src/ng/filter/filters.js @@ -174,10 +174,13 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { fractionSize = Math.min(Math.max(pattern.minFrac, fractionLen), pattern.maxFrac); } - // safely round numbers in JS without hitting imprecisions of floating-point arithmetics - // inspired by: - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round - number = +(Math.round(+(number.toString() + 'e' + fractionSize)).toString() + 'e' + -fractionSize); + // round the number only if it's decimal + if(number.toString().indexOf('.') >= 0) { + // safely round numbers in JS without hitting imprecisions of floating-point arithmetics + // inspired by: + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round + number = +(Math.round(+(number.toString() + 'e' + fractionSize)).toString() + 'e' + -fractionSize); + } var fraction = ('' + number).split(DECIMAL_SEP); var whole = fraction[0]; diff --git a/test/ng/filter/filtersSpec.js b/test/ng/filter/filtersSpec.js index 52ad6fbd6a4d..a71054eca424 100644 --- a/test/ng/filter/filtersSpec.js +++ b/test/ng/filter/filtersSpec.js @@ -90,6 +90,24 @@ describe('filters', function() { expect(formatNumber(-0.0001, pattern, ',', '.', 3)).toBe('0.000'); expect(formatNumber(-0.0000001, pattern, ',', '.', 6)).toBe('0.000000'); }); + + it('should work with numbers that are close to the limit for exponent notation', function() { + // previously, numbers that n * (10 ^ fractionSize) > localLimitMax + // were ending up with a second exponent in them, then coercing to + // NaN when formatNumber rounded them with the safe rounding + // function. + var localLimitMax = 999999999999999934463, + localLimitMin = 10000000000000000000, + exampleNumber = 444444444400000000000; + + expect(formatNumber(localLimitMax, pattern, ',', '.', 2)) + .toBe('999,999,999,999,999,900,000.00'); + expect(formatNumber(localLimitMin, pattern, ',', '.', 2)) + .toBe('10,000,000,000,000,000,000.00'); + expect(formatNumber(exampleNumber, pattern, ',', '.', 2)) + .toBe('444,444,444,400,000,000,000.00'); + + }); }); describe('currency', function() { From c4654ddd6043e66934ca702389909b791cd615a1 Mon Sep 17 00:00:00 2001 From: danprince <danielprince@hotmail.co.uk> Date: Sun, 30 Aug 2015 18:14:22 +0100 Subject: [PATCH 2/3] test(filters): adds better examples for testing formatNumber --- test/ng/filter/filtersSpec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/ng/filter/filtersSpec.js b/test/ng/filter/filtersSpec.js index a71054eca424..90f792d3f6ca 100644 --- a/test/ng/filter/filtersSpec.js +++ b/test/ng/filter/filtersSpec.js @@ -96,7 +96,8 @@ describe('filters', function() { // were ending up with a second exponent in them, then coercing to // NaN when formatNumber rounded them with the safe rounding // function. - var localLimitMax = 999999999999999934463, + + var localLimitMax = 999999999999999900000, localLimitMin = 10000000000000000000, exampleNumber = 444444444400000000000; From 7691f0a993fb197a074fbc34c6183fbc215a716b Mon Sep 17 00:00:00 2001 From: danprince <danielprince@hotmail.co.uk> Date: Sun, 30 Aug 2015 18:16:01 +0100 Subject: [PATCH 3/3] style(filters) fix coding style on if statement --- src/ng/filter/filters.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ng/filter/filters.js b/src/ng/filter/filters.js index 89d3638010d1..e05c7ebf2a35 100644 --- a/src/ng/filter/filters.js +++ b/src/ng/filter/filters.js @@ -175,7 +175,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { } // round the number only if it's decimal - if(number.toString().indexOf('.') >= 0) { + if (number.toString().indexOf('.') >= 0) { // safely round numbers in JS without hitting imprecisions of floating-point arithmetics // inspired by: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round