Obtenez la partie décimale d'un nombre avec JavaScript


248

J'ai des nombres flottants comme 3.2et 1.6.

J'ai besoin de séparer le nombre en partie entière et décimale. Par exemple, une valeur de 3.2serait divisée en deux nombres, c'est 3-à- dire et0.2

Obtenir la partie entière est facile:

n = Math.floor(n);

Mais j'ai du mal à obtenir la partie décimale. J'ai essayé ceci:

remainer = n % 2; //obtem a parte decimal do rating

Mais cela ne fonctionne pas toujours correctement.

Le code précédent a la sortie suivante:

n = 3.1 => remainer = 1.1

Qu'est-ce qui me manque ici?


1
Notez que n = Math.floor(n);ne renvoie que le résultat souhaité (la partie entière) pour les nombres non négatifs
tsemer

Simplfy use % 1not% 2
masterxilo

Réponses:


366

Utilisez 1pas 2.

js> 2.3 % 1
0.2999999999999998

60
Dans un monde où 0,299999999999999998 est égal à 0,3, cela peut être acceptable. Pour moi, ce n'est pas ... Par conséquent, pour résoudre ce défi, je m'abstiendrais d'utiliser Math.*ou d' %opérations.
Marcel Stör

62
Pour éviter les problèmes d'arrondi en virgule flottante notés, l'utilisation toFixedpourrait aider dans certaines situations, par exemple (2.3 % 1).toFixed(4)== "0.3000".
Brian M. Hunt

12
(2.3 % 1).toFixed(4).substring(2)= "3000"si vous en avez besoin sans0.
Simon_Weaver

14
Dans un monde où le nombre 2.3est apparu, et non 2ou 3, le nombre 0.2999999999999998est parfaitement acceptable malgré son insulte aux yeux des humains.
Gershom

1
@GershomMaes il y a une variété de circonstances où ce nombre n'est pas acceptable.
Adam Leggett

92
var decimal = n - Math.floor(n)

Bien que cela ne fonctionne pas pour les nombres négatifs, nous devrons peut-être faire

n = Math.abs(n); // Change to positive
var decimal = n - Math.floor(n)

Si vous avez déjà la partie entière, il n'est pas nécessaire d'appeler à Math.floor()nouveau - utilisez simplement la partie entière que vous avez calculée.
tvanfosson

4
var n = 3.2, integr = Math.floor(n), decimal = n - integr;utilisez Math.floor () une seule fois. integr = 3; decimal = 0.20000000000000018;
Nurlan

2
Pour travailler avec un nombre négatif, échangez simplement Math.flooravec Math.trunc.
Igor Silva

cela renvoyait un nombre non exact comme je m'attendais à obtenir 0,80 de 100,80, pas 0,79999 ... J'ai résolu cela en ajoutant decimal.toFixed (2)
Luis Febro

77

Vous pouvez convertir en chaîne, non?

n = (n + "").split(".");

17
Cela fonctionne bien partout sauf en Europe continentale où une virgule est le séparateur décimal. Si vous prévoyez de l'utiliser, n'oubliez pas d'en tenir compte si vous êtes multinational et ciblez l'Europe, car cette solution ne fera pas un excellent travail pour eux.
cdmdotnet

8
Je viens d'Europe continentale avec un Firefox français et ça marche. Normalement, nous utiliserions la virgule comme séparateur décimal en France. La raison étant qu'en JavaScript, aucune culture n'est impliquée lors de la conversion d'un nombre en chaîne, bien que je préfère utiliser n.toString()plutôt que n + ""parce qu'il est plus lisible.
Gabriel Hautclocq

2
Si la vitesse est critique, elle n + ""est en effet meilleure (voir jsperf.com/number-vs-number-tostring-vs-string-number )
Gabriel Hautclocq

@cdmdotnet JS utilise .comme séparateur décimal, donc tout va bien si le type de votre variable d'entrée est float. Vous ne devez résoudre ce problème que si votre entrée est une chaîne. Je dois également noter que cette réponse renvoie une chaîne dans un tableau. Une solution plus complète estparseFloat('0.' + (n + '').split('.')[1])
totymedli

La solution indépendante de l'emplacement @cdmdotnet est ici: stackoverflow.com/a/59469716/1742529
user1742529

32

En quoi 0,299999999999999998 est-il une réponse acceptable? Si j'étais le demandeur, je voudrais une réponse de .3. Ce que nous avons ici est une fausse précision, et mes expériences avec le plancher,%, etc. indiquent que Javascript aime la fausse précision pour ces opérations. Je pense donc que les réponses qui utilisent la conversion en chaîne sont sur la bonne voie.

Je ferais ceci:

var decPart = (n+"").split(".")[1];

Plus précisément, j'utilisais 100233.1 et je voulais la réponse ".1".


6
Je suis généralement d'accord, mais vous ne pouvez pas compter sur "." l'expression régulière comme séparateur décimal est un caractère i18n .
Marcel Stör

1
@jomofrodo En fait, certains voudront peut-être la valeur non arrondie. Je ne me souviens pas que l'OP ait demandé une valeur arrondie, juste des valeurs fractionnées.
VVV

1
@VVV oui, certains voudront peut-être la valeur non arrondie. Mais ce n'est pas parce que vous souhaitez une précision à 9 décimales que vos données d'entrée le prennent réellement en charge. C'est pourquoi on l'appelle "fausse précision". Si votre saisie est 3.1, la réponse la plus précise possible peut être des dixièmes, c'est-à-dire 0,1. Si vous répondez à .09, cela signifie que vous avez réellement calculé / mesuré jusqu'à 100 centièmes de précision, alors qu'en fait l'entrée d'origine n'était précise qu'à 10 millièmes de précision près.
jomofrodo

1
@ MarcelStör qui peut être facilement géré: var decPart = (n.toLocaleString ("en")). Split (".") [1];
jem

1
.toString()ne considère pas i18n. Le séparateur décimal sera toujours . conforme à MDN et à la spécification ECMA
Andrewmat

18

Voici comment je le fais, ce qui, selon moi, est le moyen le plus simple de le faire:

var x = 3.2;
int_part = Math.trunc(x); // returns 3
float_part = Number((x-int_part).toFixed(2)); // return 0.2

15

Une façon simple de le faire est:

var x = 3.2;
var decimals = x - Math.floor(x);
console.log(decimals); //Returns 0.20000000000000018

Malheureusement, cela ne renvoie pas la valeur exacte. Cependant, cela est facilement corrigé:

var x = 3.2;
var decimals = x - Math.floor(x);
console.log(decimals.toFixed(1)); //Returns 0.2

Vous pouvez l'utiliser si vous ne connaissez pas le nombre de décimales:

var x = 3.2;
var decimals = x - Math.floor(x);

var decimalPlaces = x.toString().split('.')[1].length;
decimals = decimals.toFixed(decimalPlaces);

console.log(decimals); //Returns 0.2


9

Manière indépendante de la langue:

var a = 3.2;
var fract = a * 10 % 10 /10; //0.2
var integr = a - fract; //3

notez qu'il ne corrige que pour les nombres avec une longueur fractioanale)


3
Pouvez-vous expliquer pourquoi vous pensez que cela est indépendant de la langue? C'est JavaScript.
hotzst

4
@hotzst, il n'y a pas de fonction spécifique au langage
Nurlan

1
Indépendant de la langue parce que c'est juste des mathématiques pures. Solution pratique. Avec la longueur de fraction souhaitée:var factor = Math.pow(10, desiredFractionLength); var fract = a * factor % factor / factor;
muratgozel

6

Vous pouvez utiliser la parseInt()fonction pour obtenir la partie entière que celle utilisée pour extraire la partie décimale

var myNumber = 3.2;
var integerPart = parseInt(myNumber);
var decimalPart = myNumber - integerPart;

Ou vous pouvez utiliser l'expression régulière comme:

splitFloat = function(n){
   const regex = /(\d*)[.,]{1}(\d*)/;
   var m;

   if ((m = regex.exec(n.toString())) !== null) {
       return {
          integer:parseInt(m[1]),
          decimal:parseFloat(`0.${m[2]}`)
       }
   }
}

decimalPart arrive 0.20000000000000018... cela devient vraiment difficile à faire car 0.2 < 0.20000000000000018retourne vrai .. 3.2 censé retourner 0.2: P faisant tant d'irrégularités et utilisant la .toFixed(2)chaîne de retour: P
Himanshu Bansal

@HimanshuBansal c'est un problème de JavaScript (une question stackeoverflow à cela). Vous pouvez utiliser la deuxième méthode que j'ai suggérée.
Sheki

Eh bien, j'ai un petit problème différent ... J'ai utilisé les deux façons: P pour le résoudre .. ^^
Himanshu Bansal

@HimanshuBansal heureux que mon message ait aidé à résoudre votre problème!
Sheki

5

Ce qui suit fonctionne indépendamment des paramètres régionaux pour le séparateur décimal ... à condition qu'un seul caractère soit utilisé pour un séparateur.

var n = 2015.15;
var integer = Math.floor(n).toString();
var strungNumber = n.toString();
if (integer.length === strungNumber.length)
  return "0";
return strungNumber.substring(integer.length + 1);

Ce n'est pas joli, mais c'est précis.


Il s'agit bien sûr d'une chaîne, vous devrez donc d'abord analyser parseInt () si vous le souhaitez sous forme de nombre. Vous ne devriez pas avoir besoin d'analyser Float () ... sauf s'il y a quelque chose qui me manque ici avec des nombres en base 8 et non en base 10 ... quelque chose dont je me souviens vaguement il y a des années
cdmdotnet

5

Si la précision est importante et que vous avez besoin de résultats cohérents, voici quelques propositions qui renverront la partie décimale de n'importe quel nombre sous forme de chaîne, y compris le "0" principal. Si vous en avez besoin comme flotteur, ajoutez simplement var f = parseFloat( result )à la fin.

Si la partie décimale est égale à zéro, "0,0" sera retourné. Les nombres nuls, NaN et non définis ne sont pas testés.

1. String.split

var nstring = (n + ""),
    narray  = nstring.split("."),
    result  = "0." + ( narray.length > 1 ? narray[1] : "0" );

2. String.substring, String.indexOf

var nstring = (n + ""),
    nindex  = nstring.indexOf("."),
    result  = "0." + (nindex > -1 ? nstring.substring(nindex + 1) : "0");

3. Math.floor, Number.toFixed, String.indexOf

var nstring = (n + ""),
    nindex  = nstring.indexOf("."),
    result  = ( nindex > -1 ? (n - Math.floor(n)).toFixed(nstring.length - nindex - 1) : "0.0");

4. Math.floor, Number.toFixed, String.split

var nstring = (n + ""),
    narray  = nstring.split("."),
    result  = (narray.length > 1 ? (n - Math.floor(n)).toFixed(narray[1].length) : "0.0");

Voici un lien jsPerf: https://jsperf.com/decpart-of-number/

Nous pouvons voir que la proposition n ° 2 est la plus rapide.


n'utilisez aucun de ceux-ci. ils se briseront dès que le rendu des nombres passera à l'ingénierie. ils ne sont pas non plus sensibles aux paramètres régionaux.
Spongman

Pourriez-vous expliquer "le rendu des nombres passe à l'ingénierie"? De plus, la localisation n'est pas pertinente car nous voulons juste la partie décimale d'un nombre, pas une chaîne localisée représentant un nombre.
Gabriel Hautclocq

4

Vous pouvez le convertir en chaîne et utiliser la replaceméthode pour remplacer la partie entière par zéro, puis reconvertir le résultat en nombre:

var number = 123.123812,
    decimals = +number.toString().replace(/^[^\.]+/,'0');

Cette solution ne fonctionnerait-elle pas en Europe continentale où la virgule est le séparateur décimal ??
preston

@preston Vous pouvez remplacer le point dans l'expression régulière par tout autre caractère de séparation que vous aimez (comme /^[^,]/), mais vous devez ensuite laisser le résultat sous forme de chaîne (supprimer l' +opérateur) afin d'éviter les NaNrésultats.
gion_13

4

Selon l'utilisation que vous en ferez ensuite, cette solution simple pourrait également vous aider.

Je ne dis pas que c'est une bonne solution, mais pour certains cas concrets, ça marche

var a = 10.2
var c = a.toString().split(".")
console.log(c[1] == 2) //True
console.log(c[1] === 2)  //False

Mais cela prendra plus de temps que la solution proposée par @Brian M. Hunt

(2.3 % 1).toFixed(4)

1
Cela fonctionne bien partout sauf en Europe continentale où une virgule est le séparateur décimal. Si vous envisagez de l'utiliser, n'oubliez pas d'en tenir compte si vous êtes multinational et ciblez l'Europe, car cette solution ne fera pas un excellent travail pour eux.
cdmdotnet

1

J'ai eu un cas où je savais que tous les nombres en question n'auraient qu'une décimale et je voulais obtenir la partie décimale sous forme d'entier, j'ai donc fini par utiliser ce type d'approche:

var number = 3.1,
    decimalAsInt = Math.round((number - parseInt(number)) * 10); // returns 1

Cela fonctionne bien aussi avec des entiers, retournant 0 dans ces cas.


1

J'utilise:

var n = -556.123444444;
var str = n.toString();
var decimalOnly = 0;

if( str.indexOf('.') != -1 ){ //check if has decimal
    var decimalOnly = parseFloat(Math.abs(n).toString().split('.')[1]);
}

Entrée: -556.123444444

Résultat: 123444444


1

Les fonctions mathématiques sont plus rapides, mais retournent toujours des valeurs attendues non natives. Le moyen le plus simple que j'ai trouvé est

(3.2+'').replace(/^[-\d]+\./, '')

1

Une bonne option consiste à transformer le nombre en chaîne, puis à le diviser.

// Decimal number
let number = 3.2;

// Convert it into a string
let string = number.toString();

// Split the dot
let array = string.split('.');

// Get both numbers
// The '+' sign transforms the string into a number again
let firstNumber  = +array[0]; // 3
let secondNumber = +array[1]; // 2

En une seule ligne de code

let [firstNumber, secondNumber] = [+number.toString().split('.')[0], +number.toString().split('.')[1]];

0

Après avoir examiné plusieurs d'entre eux, j'utilise maintenant ...

var rtnValue = Number(7.23);
var tempDec = ((rtnValue / 1) - Math.floor(rtnValue)).toFixed(2);


0

Bien que je sois très en retard pour répondre à cette question, veuillez consulter le code.

let floatValue = 3.267848;
let decimalDigits = floatValue.toString().split('.')[1];
let decimalPlaces = decimalDigits.length;
let decimalDivider = Math.pow(10, decimalPlaces);
let fractionValue = decimalDigits/decimalDivider;
let integerValue = floatValue - fractionValue;

console.log("Float value: "+floatValue);
console.log("Integer value: "+integerValue);
console.log("Fraction value: "+fractionValue)

0

Le signe décimal à virgule flottante et le format numérique peuvent dépendre du pays ( .,), donc la solution indépendante, qui a conservé la partie à virgule flottante, est:

getFloatDecimalPortion = function(x) {
    x = Math.abs(parseFloat(x));
    let n = parseInt(x);
    return Number((x - n).toFixed(Math.abs((""+x).length - (""+n).length - 1)));
}

- c'est une solution internationalisée, plutôt que dépendante de l'emplacement:

getFloatDecimalPortion = x => parseFloat("0." + ((x + "").split(".")[1]));

Description de la solution étape par étape:

  1. parseFloat() pour garantir la cocrection d'entrée
  2. Math.abs() pour éviter les problèmes avec les nombres négatifs
  3. n = parseInt(x) pour obtenir la partie décimale
  4. x - n pour soustraire la partie décimale
  5. Nous avons maintenant un numéro avec une partie décimale nulle, mais JavaScript pourrait nous donner des chiffres de partie flottante supplémentaires, ce que nous ne voulons pas
  6. Donc, limitez les chiffres supplémentaires en appelant toFixed()avec le nombre de chiffres dans la partie flottante du numéro flottant d'origine x. Le nombre est calculé comme la différence entre la longueur du nombre d'origine xet le nombre ndans leur représentation sous forme de chaîne.

-1

Utilisez celui-ci:

function isNatural(n) {
    n = +n
    if (isNaN(n)) return 'NaN';
    return (n >= 0.0) && (Math.floor(n) === n) && n !== Infinity;
  }

Math.frac = function frac(x, m) {
    x = +x
    if (isNaN(x)) return NaN;
    if (isNatural(x) === true) return 0;
    m = +m || 1

      if (isNatural(x) === false && m === 1){
        var a = x.toString()
        var b = a.split('.')[1]
        var c = '0.' + b
        var d = +c
        return d;
      }

      if (isNatural(x) === false && m === 2){
        var a = x.toString()
        var b = a.split('.')[1]
        var c = +b
        return c;
      }

      if (isNatural(x) === false && m === 3){
        var a = x.toString()
        var b = a.split('.')[1]
        var c = '0.' + b
        var d = +c * 100
        return d;
      }    
  }

La Math.fracfonction a ici 3 modes:

Math.frac(11.635) //0.635
Math.frac(11.635, 1) //0.635 - default mode is 1
Math.frac(11.635, 2) //635
Math.frac(11.635, 3) //63,5 (%)

C'est simple :)


-9
float a=3.2;
int b=(int)a; // you'll get output b=3 here;
int c=(int)a-b; // you'll get c=.2 value here

4
cela ne ressemble pas à javascript pour moi!
Ch'marr

1
Ce n'est pas un script java
Amrut

En JS, cela devrait être comme: var a = 3.2; var b = parseInt (a, 10); var c = a - b;
Ju-v
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.