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 e371cc2

Browse files
committedNov 26, 2014
Fix to_human precision rounding
1 parent 0d7fc0a commit e371cc2

File tree

2 files changed

+28
-16
lines changed

2 files changed

+28
-16
lines changed
 

‎src/js/ripple/amount.js

+12-15
Original file line numberDiff line numberDiff line change
@@ -1145,33 +1145,29 @@ Amount.prototype.to_human = function(opts) {
11451145
fraction_part = fraction_part.replace(/0*$/, '');
11461146

11471147
if (fraction_part.length || !opts.skip_empty_fraction) {
1148-
11491148
// Enforce the maximum number of decimal digits (precision)
11501149
if (typeof opts.precision === 'number') {
1151-
if (opts.precision <= 0) {
1150+
var precision = Math.max(0, opts.precision);
1151+
precision = Math.min(precision, fraction_part.length);
1152+
var rounded = Number('0.' + fraction_part).toFixed(precision);
11521153

1153-
// increment the int_part if the first decimal is 5 or higher
1154-
if (fraction_part.charCodeAt(0) >= 53) {
1155-
int_part = (Number(int_part) + 1).toString();
1156-
}
1157-
fraction_part = '';
1154+
if (rounded < 1) {
1155+
fraction_part = rounded.substring(2);
11581156
} else {
1159-
var precision = Math.min(opts.precision, fraction_part.length);
1160-
fraction_part = Math.round(fraction_part / Math.pow(10, fraction_part.length - precision)).toString();
1157+
int_part = (Number(int_part) + 1).toString();
1158+
fraction_part = '';
1159+
}
11611160

1162-
// because the division above will cut off the leading 0's we have to add them back again
1163-
// XXX look for a more elegant alternative
1164-
while (fraction_part.length < precision) {
1165-
fraction_part = '0' + fraction_part;
1166-
}
1161+
while (fraction_part.length < precision) {
1162+
fraction_part = '0' + fraction_part;
11671163
}
11681164
}
11691165

11701166
// Limit the number of significant digits (max_sig_digits)
11711167
if (typeof opts.max_sig_digits === 'number') {
11721168
// First, we count the significant digits we have.
11731169
// A zero in the integer part does not count.
1174-
var int_is_zero = +int_part === 0;
1170+
var int_is_zero = Number(int_part) === 0;
11751171
var digits = int_is_zero ? 0 : int_part.length;
11761172

11771173
// Don't count leading zeros in the fractional part if the integer part is
@@ -1197,6 +1193,7 @@ Amount.prototype.to_human = function(opts) {
11971193

11981194
// Enforce the minimum number of decimal digits (min_precision)
11991195
if (typeof opts.min_precision === 'number') {
1196+
opts.min_precision = Math.max(0, opts.min_precision);
12001197
while (fraction_part.length < opts.min_precision) {
12011198
fraction_part += '0';
12021199
}

‎test/amount-test.js

+16-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ describe('Amount', function() {
8787
assert.strictEqual(Amount.from_human("0.8 XAU").to_human({precision:0}), '1');
8888
});
8989
it('to human, precision 0, precision 16', function() {
90-
assert.strictEqual(Amount.from_human("0.0 XAU").to_human({precision:16}), '0.0');
90+
assert.strictEqual(Amount.from_human("0.0 XAU").to_human({precision:16}), '0');
9191
});
9292
it('to human, precision 0, precision 8, min_precision 16', function() {
9393
assert.strictEqual(Amount.from_human("0.0 XAU").to_human({precision:8, min_precision:16}), '0.0000000000000000');
@@ -101,6 +101,21 @@ describe('Amount', function() {
101101
it('to human, precision 16, min_precision 6, max_sig_digits 20', function() {
102102
assert.strictEqual(Amount.from_human("0.0 XAU").to_human({precision: 16, min_precision: 6, max_sig_digits: 20}), '0.000000');
103103
});
104+
it('to human rounding edge case, precision 2, 1', function() {
105+
assert.strictEqual(Amount.from_human("0.99 XAU").to_human({precision:1}), '1.0');
106+
});
107+
it('to human rounding edge case, precision 2, 2', function() {
108+
assert.strictEqual(Amount.from_human("0.99 XAU").to_human({precision:2}), '0.99');
109+
});
110+
it('to human rounding edge case, precision 2, 3', function() {
111+
assert.strictEqual(Amount.from_human("0.99 XAU").to_human({precision:3}), '0.99');
112+
});
113+
it('to human rounding edge case, precision 2, 3 min precision 3', function() {
114+
assert.strictEqual(Amount.from_human("0.99 XAU").to_human({precision:3, min_precision:3}), '0.990');
115+
});
116+
it('to human rounding edge case, precision 3, 2', function() {
117+
assert.strictEqual(Amount.from_human("0.999 XAU").to_human({precision:2}), '1.00');
118+
});
104119
});
105120
describe('from_human', function() {
106121
it('1 XRP', function() {

0 commit comments

Comments
 (0)
Please sign in to comment.