mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-20 12:15:51 +00:00
Fix to_human precision rounding
This commit is contained in:
@@ -1145,33 +1145,29 @@ Amount.prototype.to_human = function(opts) {
|
|||||||
fraction_part = fraction_part.replace(/0*$/, '');
|
fraction_part = fraction_part.replace(/0*$/, '');
|
||||||
|
|
||||||
if (fraction_part.length || !opts.skip_empty_fraction) {
|
if (fraction_part.length || !opts.skip_empty_fraction) {
|
||||||
|
|
||||||
// Enforce the maximum number of decimal digits (precision)
|
// Enforce the maximum number of decimal digits (precision)
|
||||||
if (typeof opts.precision === 'number') {
|
if (typeof opts.precision === 'number') {
|
||||||
if (opts.precision <= 0) {
|
var precision = Math.max(0, opts.precision);
|
||||||
|
precision = Math.min(precision, fraction_part.length);
|
||||||
|
var rounded = Number('0.' + fraction_part).toFixed(precision);
|
||||||
|
|
||||||
// increment the int_part if the first decimal is 5 or higher
|
if (rounded < 1) {
|
||||||
if (fraction_part.charCodeAt(0) >= 53) {
|
fraction_part = rounded.substring(2);
|
||||||
int_part = (Number(int_part) + 1).toString();
|
|
||||||
}
|
|
||||||
fraction_part = '';
|
|
||||||
} else {
|
} else {
|
||||||
var precision = Math.min(opts.precision, fraction_part.length);
|
int_part = (Number(int_part) + 1).toString();
|
||||||
fraction_part = Math.round(fraction_part / Math.pow(10, fraction_part.length - precision)).toString();
|
fraction_part = '';
|
||||||
|
}
|
||||||
|
|
||||||
// because the division above will cut off the leading 0's we have to add them back again
|
|
||||||
// XXX look for a more elegant alternative
|
|
||||||
while (fraction_part.length < precision) {
|
while (fraction_part.length < precision) {
|
||||||
fraction_part = '0' + fraction_part;
|
fraction_part = '0' + fraction_part;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Limit the number of significant digits (max_sig_digits)
|
// Limit the number of significant digits (max_sig_digits)
|
||||||
if (typeof opts.max_sig_digits === 'number') {
|
if (typeof opts.max_sig_digits === 'number') {
|
||||||
// First, we count the significant digits we have.
|
// First, we count the significant digits we have.
|
||||||
// A zero in the integer part does not count.
|
// A zero in the integer part does not count.
|
||||||
var int_is_zero = +int_part === 0;
|
var int_is_zero = Number(int_part) === 0;
|
||||||
var digits = int_is_zero ? 0 : int_part.length;
|
var digits = int_is_zero ? 0 : int_part.length;
|
||||||
|
|
||||||
// Don't count leading zeros in the fractional part if the integer part is
|
// Don't count leading zeros in the fractional part if the integer part is
|
||||||
@@ -1197,6 +1193,7 @@ Amount.prototype.to_human = function(opts) {
|
|||||||
|
|
||||||
// Enforce the minimum number of decimal digits (min_precision)
|
// Enforce the minimum number of decimal digits (min_precision)
|
||||||
if (typeof opts.min_precision === 'number') {
|
if (typeof opts.min_precision === 'number') {
|
||||||
|
opts.min_precision = Math.max(0, opts.min_precision);
|
||||||
while (fraction_part.length < opts.min_precision) {
|
while (fraction_part.length < opts.min_precision) {
|
||||||
fraction_part += '0';
|
fraction_part += '0';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ describe('Amount', function() {
|
|||||||
assert.strictEqual(Amount.from_human("0.8 XAU").to_human({precision:0}), '1');
|
assert.strictEqual(Amount.from_human("0.8 XAU").to_human({precision:0}), '1');
|
||||||
});
|
});
|
||||||
it('to human, precision 0, precision 16', function() {
|
it('to human, precision 0, precision 16', function() {
|
||||||
assert.strictEqual(Amount.from_human("0.0 XAU").to_human({precision:16}), '0.0');
|
assert.strictEqual(Amount.from_human("0.0 XAU").to_human({precision:16}), '0');
|
||||||
});
|
});
|
||||||
it('to human, precision 0, precision 8, min_precision 16', function() {
|
it('to human, precision 0, precision 8, min_precision 16', function() {
|
||||||
assert.strictEqual(Amount.from_human("0.0 XAU").to_human({precision:8, min_precision:16}), '0.0000000000000000');
|
assert.strictEqual(Amount.from_human("0.0 XAU").to_human({precision:8, min_precision:16}), '0.0000000000000000');
|
||||||
@@ -101,6 +101,21 @@ describe('Amount', function() {
|
|||||||
it('to human, precision 16, min_precision 6, max_sig_digits 20', function() {
|
it('to human, precision 16, min_precision 6, max_sig_digits 20', function() {
|
||||||
assert.strictEqual(Amount.from_human("0.0 XAU").to_human({precision: 16, min_precision: 6, max_sig_digits: 20}), '0.000000');
|
assert.strictEqual(Amount.from_human("0.0 XAU").to_human({precision: 16, min_precision: 6, max_sig_digits: 20}), '0.000000');
|
||||||
});
|
});
|
||||||
|
it('to human rounding edge case, precision 2, 1', function() {
|
||||||
|
assert.strictEqual(Amount.from_human("0.99 XAU").to_human({precision:1}), '1.0');
|
||||||
|
});
|
||||||
|
it('to human rounding edge case, precision 2, 2', function() {
|
||||||
|
assert.strictEqual(Amount.from_human("0.99 XAU").to_human({precision:2}), '0.99');
|
||||||
|
});
|
||||||
|
it('to human rounding edge case, precision 2, 3', function() {
|
||||||
|
assert.strictEqual(Amount.from_human("0.99 XAU").to_human({precision:3}), '0.99');
|
||||||
|
});
|
||||||
|
it('to human rounding edge case, precision 2, 3 min precision 3', function() {
|
||||||
|
assert.strictEqual(Amount.from_human("0.99 XAU").to_human({precision:3, min_precision:3}), '0.990');
|
||||||
|
});
|
||||||
|
it('to human rounding edge case, precision 3, 2', function() {
|
||||||
|
assert.strictEqual(Amount.from_human("0.999 XAU").to_human({precision:2}), '1.00');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe('from_human', function() {
|
describe('from_human', function() {
|
||||||
it('1 XRP', function() {
|
it('1 XRP', function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user