Skip to content

Commit

Permalink
fix(numberFilter): format large numbers correctly
Browse files Browse the repository at this point in the history
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 angular#8674
  • Loading branch information
gauravaror committed Sep 5, 2014
1 parent 8863b9d commit 7649bb1
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
15 changes: 14 additions & 1 deletion src/ng/filter/filters.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 '';
Expand Down Expand Up @@ -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];
Expand Down
20 changes: 20 additions & 0 deletions test/ng/filter/filtersSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = +((/Trident\/.*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');
Expand Down

0 comments on commit 7649bb1

Please sign in to comment.