11

How would I calculate the number of decimal places (not digits) of a real number with Javascript?

function countDecimals(number) {

}

For example, given 245.395, it should return 3.

Andrei Volgin
  • 40,755
  • 6
  • 49
  • 58
Octocat
  • 571
  • 2
  • 6
  • 20

8 Answers8

12

Like this:

var val = 37.435345;
var countDecimals = function(value) {
  let text = value.toString()
  // verify if number 0.000005 is represented as "5e-6"
  if (text.indexOf('e-') > -1) {
    let [base, trail] = text.split('e-');
    let deg = parseInt(trail, 10);
    return deg;
  }
  // count decimals for number in representation like "0.123456"
  if (Math.floor(value) !== value) {
    return value.toString().split(".")[1].length || 0;
  }
  return 0;
}
countDecimals(val);
Alex Filatov
  • 2,232
  • 3
  • 32
  • 39
5

The main idea is to convert a number to string and get the index of "."

var x = 13.251256;
var text = x.toString();
var index = text.indexOf(".");
alert(text.length - index - 1);
Gosha_Fighten
  • 3,838
  • 1
  • 20
  • 31
  • 1
    Ok but works only for number with decimals. If given number is an integer, this fails because indexOf should return -1 and as a result, you get the count of number instead zero. – BADAOUI Mohamed Dec 12 '20 at 14:47
1

Here is a method that does not rely on converting anything to string:

function getDecimalPlaces(x,watchdog)
{
    x = Math.abs(x);
    watchdog = watchdog || 20;
    var i = 0;
    while (x % 1 > 0 && i < watchdog)
    {
        i++;
        x = x*10;
    }
    return i;
}

Note that the count will not go beyond watchdog value (defaults to 20).

jahu
  • 5,427
  • 3
  • 37
  • 64
  • This seem to fail for the following value `37.43534579815` as it returns 15 instead of 11. What do you think? – codejockie Sep 23 '21 at 12:15
  • @codejockie You're right. The quirk of all floats strikes again. I guess any operation I'll perform on a float runs the risk of returning a result slightly off the mark. Multiplication by 10 and modulo 1 are no exception. This solution probably returns valid results only for some numbers and the more decimals in the number, the error is more likely. – jahu Sep 23 '21 at 17:14
  • Exactly, and well said – codejockie Sep 23 '21 at 17:32
1

I tried some of the solutions in this thread but I have decided to build on them as I encountered some limitations. The version below can handle: string, double and whole integer input, it also ignores any insignificant zeros as was required for my application. Therefore 0.010000 would be counted as 2 decimal places. This is limited to 15 decimal places.

  function countDecimals(decimal)
    {
    var num = parseFloat(decimal); // First convert to number to check if whole

    if(Number.isInteger(num) === true)
      {
      return 0;
      }

    var text = num.toString(); // Convert back to string and check for "1e-8" numbers
    
    if(text.indexOf('e-') > -1)
      {
      var [base, trail] = text.split('e-');
      var deg = parseInt(trail, 10);
      return deg;
      }
    else
      {
      var index = text.indexOf(".");
      return text.length - index - 1; // Otherwise use simple string function to count
      }
    }
0

You can use a simple function that splits on the decimal place (if there is one) and counts the digits after that. Since the decimal place can be represented by '.' or ',' (or maybe some other character), you can test for that and use the appropriate one:

function countPlaces(num) {
    var sep = String(23.32).match(/\D/)[0];
    var b = String(num).split(sep);
  return b[1]? b[1].length : 0;
}

console.log(countPlaces(2.343)); // 3
console.log(countPlaces(2.3));   // 1
console.log(countPlaces(343.0)); // 0
console.log(countPlaces(343));   // 0
RobG
  • 142,382
  • 31
  • 172
  • 209
0

Based on Gosha_Fighten's solution, for compatibility with integers:

function countPlaces(num) {
    var text = num.toString();
    var index = text.indexOf(".");
    return index == -1 ? 0 : (text.length - index - 1);
}
LePatay
  • 172
  • 1
  • 8
0

based on LePatay's solution, also take care of the Scientific notation (ex: 3.7e-7) and with es6 syntax:

function countDecimals(num) {
  let text = num.toString()
  if (text.indexOf('e-') > -1) {
    let [base, trail] = text.split('e-')
    let elen = parseInt(trail, 10)
    let idx = base.indexOf(".")
    return idx == -1 ? 0 + elen : (base.length - idx - 1) + elen
  }
  let index = text.indexOf(".")
  return index == -1 ? 0 : (text.length - index - 1)
}
gasolin
  • 2,196
  • 1
  • 18
  • 20
-1
var value = 888;
var valueLength = value.toString().length;
Jun Bin
  • 82
  • 6