Home > other >  How to dynamically trim decimal places after decimal with toFixed method without rounding
How to dynamically trim decimal places after decimal with toFixed method without rounding

Time:10-15

I am trying to find a solution to this but it seems like there isn't a case on stack overflow where decimal precision needs to be dynamic. So I am creating a react crypto project and trying to get it where I can dynamically remove digits after decimal places. Here is what I mean.

I am currently rendering precisions dynamically like this:

 const precision = pairType === 'base' ? selectedBaseCurrencyObj.precision.amount : selectedBaseCurrencyObj.precision.cost;
 Number(assetObj.freeTotal).toFixed(precision)

the 'precision' is dynamic and will be returned from a later api that I create. Now I searched all over stackoverflow and trying to see how I can achieve this without having the figure be rounded. Wondering if there was an easy way to just cut out the rest of the figure with some other js method, which will also not prevent it from rounding

CodePudding user response:

If it is just about truncating the mantissa of a certain number at a certain length, then this can be done easily with the Math.trunc method:

const truncate = (n, precision) => {
    const f = Math.pow(10, Math.max(precision | 0, 0)) * 10;
    return Math.trunc(n * f) / f;
};

console.log(truncate(1234.56789, 0));
console.log(truncate(1234.56789, 3));
console.log(truncate(1234.56789, 6));

But, if it is about mimicking the toFixed method while avoiding the rounding, then it is just a bit harder:

const toFixed = (n, precision) => {
    const s = `${n}`, i = `${n}`.split('.'), p = Math.max(precision | 0, 0);
    return i[0]   (p ? `.${(i[1] ?? '').padEnd(p, '0')}`.slice(0, p   1) : '');
};

console.log(toFixed(1234.56789, 0), (1234.56789).toFixed(0));
console.log(toFixed(1234.56789, 3), (1234.56789).toFixed(3));
console.log(toFixed(1234.56789, 6), (1234.56789).toFixed(6));

CodePudding user response:

You can convert the input number to a string, split it by the "." and then return the first element of the array and a part of the second element of the array, and finally convert back to Number

Example:

let num = 23.987654321

const trimDecimalWithPrecision = (num, precision) => {
  var splittedNum = num.toString().split(".")
  if(precision === 0 || !num.toString().includes(".")) return Number(splittedNum[0])
  else {
    return Number(splittedNum[0]   "."   splittedNum[1].substring(0, precision))
  }
}

console.log(trimDecimalWithPrecision(num, 0)) // Output => 23
console.log(trimDecimalWithPrecision(num, 1)) // Output => 23.9
console.log(trimDecimalWithPrecision(num, 2)) // Output => 23.98
console.log(trimDecimalWithPrecision(num, 3)) // Output => 23.987
console.log(trimDecimalWithPrecision(num, 4)) // Output => 23.9876

So in your case you want to have :

 const trimDecimalWithPrecision = (num, precision) => {
  var splittedNum = num.toString().split(".")
  if(precision === 0 || !num.toString().includes(".")) return Number(splittedNum[0])
  else {
    return Number(splittedNum[0]   "."   splittedNum[1].substring(0, precision))
  }
}

const precision = pairType === 'base' ? selectedBaseCurrencyObj.precision.amount : selectedBaseCurrencyObj.precision.cost;
trimDecimalWithPrecision(assetObj.freeTotal, precision)

EDIT: Added console.log for snippet to run

  • Related