-
Notifications
You must be signed in to change notification settings - Fork 741
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Format to at least N decimal places #260
Comments
Thanks for your input. Yes, I agree. One option is to change In the meantime, the following overwrites the BigNumber.prototype.toFormat = (function (u) {
const format = BigNumber.prototype.toFormat;
return function (dp, rm) {
if (typeof dp === 'object' && dp) {
let t = dp.minimumDecimalPlaces;
if (t !== u) return format.call(this, this.dp() < t ? t : u);
rm = dp.roundingMode;
t = dp.maximumDecimalPlaces;
if (t !== u) return format.call(this.dp(t, rm));
t = dp.decimalPlaces;
if (t !== u) return format.call(this, t, rm);
}
return format.call(this, dp, rm);
}
})(); Usage: const x = new BigNumber('1');
x.toFormat(2); // '1.00'
x.toFormat({ decimalPlaces: 2 }); // '1.00'
x.toFormat({ maximumDecimalPlaces: 2 }); // '1'
x.toFormat({ minimumDecimalPlaces: 2 }); // '1.00'
const y = new BigNumber('1.234');
y.toFormat(2); // '1.23'
y.toFormat({ decimalPlaces: 2 }); // '1.23'
y.toFormat({ decimalPlaces: 2, roundingMode: 0 }); // '1.24'
y.toFormat({ maximumDecimalPlaces: 2 }); // '1.23'
y.toFormat({ minimumDecimalPlaces: 2 }); // '1.234' By the way, using the const formatMinDP = function(n, dp) {
return n.dp() < dp ? n.toFormat() : n.toFormat(dp);
} |
Thanks! That's great! |
@MikeMcl Thanks. This is really helpful. Edit: @MikeMcl |
I had the same use case and added a .toFormat2 method: FORMAT = {
minDP: 0,
maxDP: DECIMAL_PLACES,
roundingMode: ROUNDING_MODE,
prefix: '',
groupSize: 3,
secondaryGroupSize: 0,
groupSeparator: ',',
decimalSeparator: '.',
fractionGroupSize: 0,
fractionGroupSeparator: '\xA0', // non-breaking space
suffix: ''
}
....
P.toFormat2 = function ( format ) {
var str,i,
x = this;
if (format == null ) {
format = FORMAT;
} else if (typeof format != 'object') {
throw Error
(bignumberError + 'Argument not an object: ' + format);
}
for ( i in FORMAT ) {
if ( typeof format[i] === 'undefined' ) {
format[i] = FORMAT[i];
}
}
str = x.toFixed( format.maxDP, format.roundingMode );
if (x.c) {
var arr = str.split('.'),
g1 = +format.groupSize,
g2 = +format.secondaryGroupSize,
groupSeparator = format.groupSeparator || '',
intPart = arr[0],
fractionPart = arr[1],
isNeg = x.s < 0,
intDigits = isNeg ? intPart.slice(1) : intPart,
len = intDigits.length;
if (g2) {
i = g1;
g1 = g2;
g2 = i;
len -= i;
}
// intPart
if (g1 > 0 && len > 0) {
i = len % g1 || g1;
intPart = intDigits.substr(0, i);
for (; i < len; i += g1) intPart += groupSeparator + intDigits.substr(i, g1);
if (g2 > 0) intPart += groupSeparator + intDigits.slice(i);
if (isNeg) intPart = '-' + intPart;
}
// fractionPart
if ( fractionPart && fractionPart.length > format.minDP ) {
// trim trailing zeros
while ( fractionPart.length > format.minDP && fractionPart.slice(-1) === '0' ) {
fractionPart = fractionPart.slice(0, -1);
}
}
str = fractionPart
? intPart + (format.decimalSeparator || '') + ((g2 = +format.fractionGroupSize)
? fractionPart.replace(new RegExp('\\d{' + g2 + '}\\B', 'g'),
'$&' + (format.fractionGroupSeparator || ''))
: fractionPart)
: intPart;
}
return (format.prefix || '') + str + (format.suffix || '');
}; I merged the dp und rm parameters into the format object, since these are as important as any other format property imho. |
It is sometimes convenient when working with money to always format to at least N decimal places, but not to round if there is more precision present. For example, US currency generally should be formatted to two decimal places, but if there are fractions of a cent they should be included not rounded:
I currently work around this as follows:
But it seems this would a common enough use that it might be useful to have built-in. Not sure what sort of interface would make sense. Maybe a no-op rounding mode or a new format key to skip rounding.
The text was updated successfully, but these errors were encountered: