简体   繁体   中英

Round a number to 2 or more decimal places

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 (eg 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.

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)

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)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM