Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 7649bb1

Browse files
committedSep 5, 2014
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 angular#8674
1 parent 8863b9d commit 7649bb1

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed
 

‎src/ng/filter/filters.js

+14-1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,16 @@ function numberFilter($locale) {
118118
};
119119
}
120120

121+
function shiftDecimalPlace(number,fractionSize) {
122+
var numberArray = number.toString().split('e');
123+
var fractionUsed = +fractionSize;
124+
//If number was already an exponent, adjust the exponent value rather than adding new exponent.
125+
if(numberArray[1]) {
126+
fractionUsed = +numberArray[1] + fractionUsed;
127+
}
128+
return +(numberArray[0] + 'e' + fractionUsed);
129+
}
130+
121131
var DECIMAL_SEP = '.';
122132
function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
123133
if (number == null || !isFinite(number) || isObject(number)) return '';
@@ -151,7 +161,10 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
151161
// safely round numbers in JS without hitting imprecisions of floating-point arithmetics
152162
// inspired by:
153163
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
154-
number = +(Math.round(+(number.toString() + 'e' + fractionSize)).toString() + 'e' + -fractionSize);
164+
number = shiftDecimalPlace(Math.round(shiftDecimalPlace(number,fractionSize)),-fractionSize);
165+
if(isNaN(number)) {
166+
number = shiftDecimalPlace(shiftDecimalPlace(number,-fractionSize),fractionSize);
167+
}
155168

156169
var fraction = ('' + number).split(DECIMAL_SEP);
157170
var whole = fraction[0];

‎test/ng/filter/filtersSpec.js

+20
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,26 @@ describe('filters', function() {
5959
expect(num).toBe('1.1112');
6060
});
6161

62+
it('should format large number',function() {
63+
pattern.gsize = 2;
64+
var num = formatNumber(12345868059685210000, pattern, ',', '.', 2);
65+
expect(num).toBe('12,345,868,059,685,210,000.00');
66+
num = formatNumber(79832749837498327498274983793234322432, pattern, ',', '.', 2);
67+
expect(num).toBe('7.983274983749832e+37');
68+
num = formatNumber(8798327498374983274928, pattern, ',', '.', 2);
69+
expect(num).toBe('8.798327498374983e+21');
70+
num = formatNumber(879832749374983274928, pattern, ',', '.', 2);
71+
var msie = +((/msie (\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1]);
72+
var msie11 = +((/Trident\/.*rv:(\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1]);
73+
if(msie || msie11) {
74+
expect(num).toBe('879,832,749,374,983,100,000.00');
75+
} else {
76+
expect(num).toBe('879,832,749,374,983,200,000.00');
77+
}
78+
num = formatNumber(879832749374983274928, pattern, ',', '.', 32);
79+
expect(num).toBe('879,832,749,374,983,200,000.00000000000000000000000000000000');
80+
});
81+
6282
it('should format according different separators', function() {
6383
var num = formatNumber(1234567.1, pattern, '.', ',', 2);
6484
expect(num).toBe('1.234.567,10');

0 commit comments

Comments
 (0)
Please sign in to comment.