Skip to content

Commit c74bdde

Browse files
committed
fix(numberFilter): correctly round fractions despite floating-point arithmetics issues in JS
Closes angular#7870 Closes angular#7878
1 parent ceaea86 commit c74bdde

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

src/ng/filter/filters.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,11 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
145145
fractionSize = Math.min(Math.max(pattern.minFrac, fractionLen), pattern.maxFrac);
146146
}
147147

148-
var pow = Math.pow(10, fractionSize + 1);
149-
number = Math.floor(number * pow + 5) / pow;
148+
// safely round numbers in JS without hitting imprecisions of floating-point arithmetics
149+
// inspired by:
150+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
151+
number = +(Math.round(+(number.toString() + 'e' + fractionSize)).toString() + 'e' + -fractionSize);
152+
150153
var fraction = ('' + number).split(DECIMAL_SEP);
151154
var whole = fraction[0];
152155
fraction = fraction[1] || '';

test/ng/filter/filtersSpec.js

+5
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,18 @@ describe('filters', function() {
147147
expect(number(.99, 2)).toEqual("0.99");
148148
expect(number(.999, 3)).toEqual("0.999");
149149
expect(number(.9999, 3)).toEqual("1.000");
150+
expect(number(1.9, 2)).toEqual("1.90");
151+
expect(number(1.99, 2)).toEqual("1.99");
152+
expect(number(1.999, 3)).toEqual("1.999");
153+
expect(number(1.9999, 3)).toEqual("2.000");
150154
expect(number(1234.567, 0)).toEqual("1,235");
151155
expect(number(1234.567, 1)).toEqual("1,234.6");
152156
expect(number(1234.567, 2)).toEqual("1,234.57");
153157
expect(number(1.255, 0)).toEqual("1");
154158
expect(number(1.255, 1)).toEqual("1.3");
155159
expect(number(1.255, 2)).toEqual("1.26");
156160
expect(number(1.255, 3)).toEqual("1.255");
161+
expect(number(0, 8)).toEqual("0.00000000");
157162
});
158163

159164
it('should filter exponentially large numbers', function() {

0 commit comments

Comments
 (0)