I'm working in TypeScript. Is there an accepted way of rounding a number to n decimal places, or more, if the precision exists in the number?
The number must be represented as a string to avoid precision errors (e.g. 2.3 - 2 = 0.2999999999999998
)
For example:
precision = [2, 6];
tx(0.000000, precision) => 0.00
tx(0.123123, precision) => 0.123123
tx(2.00, precision) => 2.00
tx(2, precision) => 2.00
tx(2.01, precision) => 2.01
tx(2.001, precision) => 2.001
tx(2.000000001, precision) => 2.00
tx(2.000001, precision) => 2.000001
I can use this to deal with funky epsilon errors while still allowing users to enter more precise numbers than a fixed DP.
CodePudding user response:
You can try it like this, which is intentionally verbose:
type PrecisionRange = [min: number, max: number]
function tx(num: number, [min, max]: PrecisionRange): number {
const withoutTrailingZeroes = `${num}`.replace(/0 $/, '') || '0.0'
const digitsAfterDecimalSeparator = withoutTrailingZeroes.includes('.')
? withoutTrailingZeroes.split('.')[1].length
: 0
const toFixedDigits = Math.min(max, Math.max(min, digitsAfterDecimalSeparator))
return Number(num.toFixed(toFixedDigits))
}
const precision: PrecisionRange = [2, 6]
console.log(tx(0.000000, precision)) // 0
console.log(tx(0.123123, precision)) // 0.123123
console.log(tx(2.00, precision)) // 2
console.log(tx(2, precision)) // 2
console.log(tx(2.01, precision)) // 2.01
console.log(tx(2.001, precision)) // 2.001
console.log(tx(2.000000001, precision)) // 2
console.log(tx(2.000001, precision)) // 2.000001
However, 0.00
as a number will always be displayed as 0
, as trailing zeroes after the decimal separator are not displayed. If you need them for display purposes, simply adapt the method shown above to this:
function tx(num: number, [min, max]: PrecisionRange): string {
const withoutTrailingZeroes = `${num}`.replace(/0 $/, '') || '0.0'
const digitsAfterDecimalSeparator = withoutTrailingZeroes.includes('.')
? withoutTrailingZeroes.split('.')[1].length
: 0
const toFixedDigits = Math.min(max, Math.max(min, digitsAfterDecimalSeparator))
return num.toFixed(toFixedDigits)
}
CodePudding user response:
Use toLocaleString
with minimumFractionDigits
and maximumFractionDigits
parameters
function tx(value, [minimumFractionDigits, maximumFractionDigits]) {
const result = value.toLocaleString('en-US', {
minimumFractionDigits,
maximumFractionDigits
});
console.log( {value, result} );
return result;
}
const precision = [2, 6];
tx(0.000000, precision)
tx(0.123123, precision)
tx(2.00, precision)
tx(2, precision)
tx(2.01, precision)
tx(2.001, precision)
tx(2.000000001, precision)
tx(2.000001, precision)