diff --git a/src/ng/filter/filters.js b/src/ng/filter/filters.js index 14e71b53e266..7130094d6408 100644 --- a/src/ng/filter/filters.js +++ b/src/ng/filter/filters.js @@ -131,6 +131,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { var match = numStr.match(/([\d\.]+)e(-?)(\d+)/); if (match && match[2] == '-' && match[3] > fractionSize + 1) { numStr = '0'; + number = 0; } else { formatedText = numStr; hasExponent = true; @@ -145,8 +146,11 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { fractionSize = Math.min(Math.max(pattern.minFrac, fractionLen), pattern.maxFrac); } - var pow = Math.pow(10, fractionSize + 1); - number = Math.floor(number * pow + 5) / pow; + // 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]; fraction = fraction[1] || ''; diff --git a/test/ng/filter/filtersSpec.js b/test/ng/filter/filtersSpec.js index 271691efcefa..5ed1b8a1667b 100644 --- a/test/ng/filter/filtersSpec.js +++ b/test/ng/filter/filtersSpec.js @@ -147,6 +147,10 @@ describe('filters', function() { expect(number(.99, 2)).toEqual("0.99"); expect(number(.999, 3)).toEqual("0.999"); expect(number(.9999, 3)).toEqual("1.000"); + expect(number(1.9, 2)).toEqual("1.90"); + expect(number(1.99, 2)).toEqual("1.99"); + expect(number(1.999, 3)).toEqual("1.999"); + expect(number(1.9999, 3)).toEqual("2.000"); expect(number(1234.567, 0)).toEqual("1,235"); expect(number(1234.567, 1)).toEqual("1,234.6"); expect(number(1234.567, 2)).toEqual("1,234.57"); @@ -154,6 +158,7 @@ describe('filters', function() { expect(number(1.255, 1)).toEqual("1.3"); expect(number(1.255, 2)).toEqual("1.26"); expect(number(1.255, 3)).toEqual("1.255"); + expect(number(0, 8)).toEqual("0.00000000"); }); it('should filter exponentially large numbers', function() {