Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit bca1604

Browse files
bshepherdsonmhevery
authored andcommitted
fix(currency): Handle not-quite-zero values
IEEE 754 floating point sometimes results in values that are very small, rather than zero. One example is 1.0 + 1.07 - 2.07, which returns 4.440892098500626e-16 instead of 0. This change tweaks the number formatting logic so that an exponential value with a negative exponent that is larger than the precision+1 returns 0 instead. For example: with precision 2, anything with an exponent of -4, -5 or more would become 0. 9e-3 = 0.009 = 0.01, but 9e-4 = 0.0009 = 0.001 = 0.00. This detail is unlikely to matter since this quirk is usually only triggered with values very close to zero. Closes #1469
1 parent f4517b5 commit bca1604

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

src/ng/filter/filters.js

+11-2
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,18 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
117117
formatedText = '',
118118
parts = [];
119119

120+
var hasExponent = false;
120121
if (numStr.indexOf('e') !== -1) {
121-
formatedText = numStr;
122-
} else {
122+
var match = numStr.match(/([\d\.]+)e(-?)(\d+)/);
123+
if (match && match[2] == '-' && match[3] > fractionSize + 1) {
124+
numStr = '0';
125+
} else {
126+
formatedText = numStr;
127+
hasExponent = true;
128+
}
129+
}
130+
131+
if (!hasExponent) {
123132
var fractionLen = (numStr.split(DECIMAL_SEP)[1] || '').length;
124133

125134
// determine fractionSize if it is not specified

test/ng/filter/filtersSpec.js

+7
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ describe('filters', function() {
9191
expect(currency()).toBe('');
9292
expect(currency('abc')).toBe('');
9393
});
94+
95+
it('should handle zero and nearly-zero values properly', function() {
96+
// This expression is known to yield 4.440892098500626e-16 instead of 0.0.
97+
expect(currency(1.07 + 1 - 2.07)).toBe('$0.00');
98+
expect(currency(0.008)).toBe('$0.01');
99+
expect(currency(0.003)).toBe('$0.00');
100+
});
94101
});
95102

96103

0 commit comments

Comments
 (0)