web-dev-qa-db-fra.com

Javascript: Comment récupérer le nombre de décimales d'un nombre * string *?

J'ai un ensemble de numéros de chaîne comportant des décimales, par exemple: 23.456, 9.450, 123.01 ... J'ai besoin de récupérer le nombre de décimales pour chaque nombre, sachant que ils ont au moins 1 décimale.

En d'autres termes, la méthode retr_dec() doit retourner ce qui suit:

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

Les zéros de fin comptent comme une décimale dans ce cas, contrairement à ce question connexe .

Existe-t-il une méthode facile/fournie pour y parvenir en Javascript ou dois-je calculer la position du point décimal et calculer la différence avec la longueur de la chaîne? Merci

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

La complexité supplémentaire est de gérer la notation scientifique afin

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

Puisqu'il n'y a pas déjà de réponse basée sur l'expression rationnelle:

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

Notez que cela "échoue" pour les entiers, mais selon la spécification du problème, ils ne se produiront jamais.

4
Phrogz

Vous pouvez obtenir la longueur de la partie décimale de votre numéro de cette façon:

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

Il fait du nombre une chaîne, divise la chaîne en deux (au point décimal) et renvoie la longueur du deuxième élément du tableau renvoyé par l'opération de fractionnement et la stocke dans la variable 'length'.

3
Kamlesh Kumar

Essayez d'utiliser String.prototype.match() avec RegExp/\..*/ , revenir .length de la chaîne correspondante -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"
)
2
guest271314

J'ai dû gérer de très petits nombres, j'ai donc créé une version qui peut gérer des nombres comme 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>");
1
Orden

Un peu un hybride de deux autres ici, mais cela a fonctionné pour moi. Les cas extérieurs dans mon code n'ont pas été traités par d'autres ici. Cependant, j'avais supprimé le compteur de la décimale scientifique. Ce que j'aurais adoré à uni!

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

Une légère modification de la réponse actuellement acceptée, cela s'ajoute au prototype Number, permettant ainsi à toutes les variables numériques d'exécuter cette méthode:

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

Il peut être utilisé comme ceci:

// 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.");

En utilisant notre code existant, le deuxième cas pourrait également être facilement ajouté au prototype String comme ceci:

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

Utilisez ceci comme:

console.debug("45.2342".getDecimals());
1
Gabriel Nahmias
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];

}
0
dke

Sur la base de la réponse de Liam Middleton, voici ce que j'ai fait (sans notation scientifique):

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

            return match[1].length;
        };
        
alert(numberOfDecimalPlaces(42.21));
0
Fl4v