Javascript:как получить количество десятичных знаков числа* string*?


у меня есть набор строковых чисел с десятичными знаками, например:23.456,9.450,123.01... Мне нужно получить количество десятичных знаков для каждого числа, зная, что они имеют по крайней мере 1 десятичный знак.

иными словами,retr_dec() метод должен возвращать следующие:

retr_dec("23.456") -> 3
retr_dec("9.450")  -> 3
retr_dec("123.01") -> 2

конечные нули в этом случае считаются десятичными, в отличие от этого связанного вопроса.

есть ли простой / доставленный метод для достижения этого в Javascript или я должен вычислить позицию десятичной точки и вычислить разницу с длиной строки? Спасибо

11 54

11 ответов:

function decimalPlaces(num) {
  var match = (''+num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
  if (!match) { return 0; }
  return Math.max(
       0,
       // Number of digits right of decimal point.
       (match[1] ? match[1].length : 0)
       // Adjust for scientific notation.
       - (match[2] ? +match[2] : 0));
}

дополнительная сложность заключается в обработке научной нотации так

decimalPlaces('.05')
2
decimalPlaces('.5')
1
decimalPlaces('1')
0
decimalPlaces('25e-100')
100
decimalPlaces('2.5e-99')
100
decimalPlaces('.5e1')
0
decimalPlaces('.25e1')
1
function retr_dec(num) {
  return (num.split('.')[1] || []).length;
}
function retr_dec(numStr) {
    var pieces = numStr.split(".");
    return pieces[1].length;
}

поскольку уже нет ответа на основе регулярных выражений:

/\d*$/.exec(strNum)[0].length

обратите внимание, что это "не удается" для целых чисел, но в спецификации проблемы они никогда не будут происходить.

вы можете получить длину десятичной части вашего числа таким образом:

var value = 192.123123;
stringValue = value.toString();
length = stringValue.split('.')[1].length;

он делает число строкой, разбивает строку на две (в десятичной точке) и возвращает длину второго элемента массива, возвращенного операцией разделения, и сохраняет его в переменной "length".

небольшая модификация принятого в настоящее время ответа, это добавляет к Number прототип, тем самым позволяя всем числовым переменным выполнять этот метод:

if (!Number.prototype.getDecimals) {
    Number.prototype.getDecimals = function() {
        var num = this,
            match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
        if (!match)
            return 0;
        return Math.max(0, (match[1] ? match[1].length : 0) - (match[2] ? +match[2] : 0));
    }
}

его можно использовать так:

// Get a number's decimals.
var number = 1.235256;
console.debug(number + " has " + number.getDecimals() + " decimal places.");

// Get a number string's decimals.
var number = "634.2384023";
console.debug(number + " has " + parseFloat(number).getDecimals() + " decimal places.");

используя наш существующий код, второй случай также может быть легко добавлен в String прототип вот так:

if (!String.prototype.getDecimals) {
    String.prototype.getDecimals = function() {
        return parseFloat(this).getDecimals();
    }
}

использовать это как:

console.debug("45.2342".getDecimals());

немного гибрид двух других здесь, но это сработало для меня. Внешние случаи в моем коде не обрабатывались другими здесь. Тем не менее, я удалил научный десятичный счетчик. Который мне бы очень понравился в универе!

numberOfDecimalPlaces: function (number) {
    var match = ('' + number).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
    if (!match || match[0] == 0) {
        return 0;
    }
     return match[0].length;
}

попробуйте использовать String.prototype.match() С RegExp/\..*/ , вернуть .length из соответствующей строки -1

function retr_decs(args) {
  return /\./.test(args) && args.match(/\..*/)[0].length - 1 || "no decimal found"
}

console.log(
  retr_decs("23.456") // 3
  , retr_decs("9.450") // 3
  , retr_decs("123.01") // 2
  , retr_decs("123") // "no decimal found"
)

мне пришлось иметь дело с очень маленькими числами, поэтому я создал версию, которая может обрабатывать числа, такие как 1e-7.

Number.prototype.getPrecision = function() {
  var v = this.valueOf();
  if (Math.floor(v) === v) return 0;
  var str = this.toString();
  var ep = str.split("e-");
  if (ep.length > 1) {
    var np = Number(ep[0]);
    return np.getPrecision() + Number(ep[1]);
  }
  var dp = str.split(".");
  if (dp.length > 1) {
    return dp[1].length;
  }
  return 0;
}
document.write("NaN => " + Number("NaN").getPrecision() + "<br>");
document.write("void => " + Number("").getPrecision() + "<br>");
document.write("12.1234 => " + Number("12.1234").getPrecision() + "<br>");
document.write("1212 => " + Number("1212").getPrecision() + "<br>");
document.write("0.0000001 => " + Number("0.0000001").getPrecision() + "<br>");
document.write("1.12e-23 => " + Number("1.12e-23").getPrecision() + "<br>");
document.write("1.12e8 => " + Number("1.12e8").getPrecision() + "<br>");

основываясь на ответе Лиама Миддлтона, вот что я сделал (без научной нотации):

numberOfDecimalPlaces = (number) => {
            let match = (number + "").match(/(?:\.(\d+))?$/);
            if (!match || !match[1]) {
                return 0;
            }

            return match[1].length;
        };
        
alert(numberOfDecimalPlaces(42.21));
function decimalPlaces(n) {
  if (n === NaN || n === Infinity)
    return 0;
  n = ('' + n).split('.');
  if (n.length == 1) {
    if (Boolean(n[0].match(/e/g)))
      return ~~(n[0].split('e-'))[1];
    return 0;

  }
  n = n[1].split('e-');
  return n[0].length + ~~n[1];

}