From c12e115620a2d686e5095de5b2870a6f9dee5c2f Mon Sep 17 00:00:00 2001 From: Gaurav Arora Date: Thu, 21 Aug 2014 16:07:40 +0530 Subject: [PATCH] fix(numberFilter): format large numbers correctly format large number to correct form instead of NAN.00 currently. in previous code when first time we add the exponent with fractionSize (number.toString()+'e'+fractionsize) and then convert it to an integer using , +(number.toString()+'e'+fractionsize) when the number is very large and number will be represented by using exponent. for example 12345868059685210000 will be represented by 1.234586805968521e+21. as getting string in exponent is not handles, we get the number as NAN. Handle when the number is being represented in exponent form, by adjusting exponent of number with fraction size: Closes #8674 --- src/ng/filter/filters.js | 15 ++++++++++++++- test/ng/filter/filtersSpec.js | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/ng/filter/filters.js b/src/ng/filter/filters.js index 91cb588aff75..30d3e737c735 100644 --- a/src/ng/filter/filters.js +++ b/src/ng/filter/filters.js @@ -118,6 +118,16 @@ function numberFilter($locale) { }; } +function shiftDecimalPlace(number,fractionSize) { + var numberArray = number.toString().split('e'); + var fractionUsed = +fractionSize; + //If number was already an exponent, adjust the exponent value rather than adding new exponent. + if(numberArray[1]) { + fractionUsed = +numberArray[1] + fractionUsed; + } + return +(numberArray[0] + 'e' + fractionUsed); +} + var DECIMAL_SEP = '.'; function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { if (number == null || !isFinite(number) || isObject(number)) return ''; @@ -151,7 +161,10 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { // 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); + number = shiftDecimalPlace(Math.round(shiftDecimalPlace(number,fractionSize)),-fractionSize); + if(isNaN(number)) { + number = shiftDecimalPlace(shiftDecimalPlace(number,-fractionSize),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 af0cdba6d96d..6117e42be75f 100644 --- a/test/ng/filter/filtersSpec.js +++ b/test/ng/filter/filtersSpec.js @@ -59,6 +59,26 @@ describe('filters', function() { expect(num).toBe('1.1112'); }); + it('should format large number',function() { + pattern.gsize = 2; + var num = formatNumber(12345868059685210000, pattern, ',', '.', 2); + expect(num).toBe('12,345,868,059,685,210,000.00'); + num = formatNumber(79832749837498327498274983793234322432, pattern, ',', '.', 2); + expect(num).toBe('7.983274983749832e+37'); + num = formatNumber(8798327498374983274928, pattern, ',', '.', 2); + expect(num).toBe('8.798327498374983e+21'); + num = formatNumber(879832749374983274928, pattern, ',', '.', 2); + var msie = +((/msie (\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1]); + var msie11 = +((/rv:(\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1]); + if(msie || msie11) { + expect(num).toBe('879,832,749,374,983,100,000.00'); + } else { + expect(num).toBe('879,832,749,374,983,200,000.00'); + } + num = formatNumber(879832749374983274928, pattern, ',', '.', 32); + expect(num).toBe('879,832,749,374,983,200,000.00000000000000000000000000000000'); + }); + it('should format according different separators', function() { var num = formatNumber(1234567.1, pattern, '.', ',', 2); expect(num).toBe('1.234.567,10');