diff --git a/src/ng/filter/filters.js b/src/ng/filter/filters.js index d03fcac7616a..81873431831d 100644 --- a/src/ng/filter/filters.js +++ b/src/ng/filter/filters.js @@ -221,18 +221,37 @@ function roundNumber(parsedNumber, fractionSize, minFrac, maxFrac) { var digit = digits[roundAt]; if (roundAt > 0) { - digits.splice(roundAt); + // Drop fractional digits beyond `roundAt` + digits.splice(Math.max(parsedNumber.i, roundAt)); + + // Set non-fractional digits beyond `roundAt` to 0 + for (var j = roundAt; j < digits.length; j++) { + digits[j] = 0; + } } else { // We rounded to zero so reset the parsedNumber + fractionLen = Math.max(0, fractionLen); parsedNumber.i = 1; - digits.length = roundAt = fractionSize + 1; - for (var i=0; i < roundAt; i++) digits[i] = 0; + digits.length = Math.max(1, roundAt = fractionSize + 1); + digits[0] = 0; + for (var i = 1; i < roundAt; i++) digits[i] = 0; } - if (digit >= 5) digits[roundAt - 1]++; + if (digit >= 5) { + if (roundAt - 1 < 0) { + for (var k = 0; k > roundAt; k--) { + digits.unshift(0); + parsedNumber.i++; + } + digits.unshift(1); + parsedNumber.i++; + } else { + digits[roundAt - 1]++; + } + } // Pad out with zeros to get the required fraction length - for (; fractionLen < fractionSize; fractionLen++) digits.push(0); + for (; fractionLen < Math.max(0, fractionSize); fractionLen++) digits.push(0); // Do any carrying, e.g. a digit was rounded up to 10 diff --git a/test/ng/filter/filtersSpec.js b/test/ng/filter/filtersSpec.js index 50b7612cedcf..4a9567c9ae56 100644 --- a/test/ng/filter/filtersSpec.js +++ b/test/ng/filter/filtersSpec.js @@ -86,6 +86,26 @@ describe('filters', function() { expect(num).toBe('123.100'); }); + it('should work with negative fractionSize', function() { + expect(formatNumber(49, pattern, ',', '.', -2)).toBe('0'); + expect(formatNumber(50, pattern, ',', '.', -2)).toBe('100'); + expect(formatNumber(51, pattern, ',', '.', -2)).toBe('100'); + expect(formatNumber(1234, pattern, ',', '.', -1)).toBe('1,230'); + expect(formatNumber(1234.567, pattern, ',', '.', -1)).toBe('1,230'); + expect(formatNumber(1235, pattern, ',', '.', -1)).toBe('1,240'); + expect(formatNumber(1235, pattern, ',', '.', -2)).toBe('1,200'); + expect(formatNumber(1235, pattern, ',', '.', -3)).toBe('1,000'); + expect(formatNumber(1235, pattern, ',', '.', -4)).toBe('0'); + expect(formatNumber(1250, pattern, ',', '.', -2)).toBe('1,300'); + expect(formatNumber(1000, pattern, ',', '.', -3)).toBe('1,000'); + expect(formatNumber(1000, pattern, ',', '.', -4)).toBe('0'); + expect(formatNumber(1000, pattern, ',', '.', -5)).toBe('0'); + expect(formatNumber(1, pattern, ',', '.', -1)).toBe('0'); + expect(formatNumber(1, pattern, ',', '.', -2)).toBe('0'); + expect(formatNumber(9, pattern, ',', '.', -1)).toBe('10'); + expect(formatNumber(501, pattern, ',', '.', -3)).toBe('1,000'); + }); + it('should format numbers that round to zero as nonnegative', function() { expect(formatNumber(-0.01, pattern, ',', '.', 1)).toBe('0.0'); expect(formatNumber(-1e-10, pattern, ',', '.', 1)).toBe('0.0');