1554 votes

Comment convertir un nombre flottant en un nombre entier en JavaScript ?

J'aimerais convertir un flottant en un nombre entier en JavaScript. En fait, j'aimerais savoir comment effectuer les DEUX conversions standard : en tronquant et en arrondissant. Et de manière efficace, pas en convertissant en une chaîne de caractères et en l'analysant.

105 votes

Si vous ne le saviez pas, tous les nombres en javascript sont des flottants. De la spécification :

8 votes

4.3.20 Type de numéro : Le type Number est un ensemble de valeurs représentant des nombres. Dans l'ECMAScript, l'ensemble de valeurs représente les valeurs IEEE 754 en double précision sur 64 bits, y compris les valeurs spéciales "Not-a-Number" (NaN), l'infini positif et l'infini négatif.

13 votes

Oui, Javascript ne dispose pas d'un type "entier" distinct, mais il n'est pas rare de devoir effectuer cette conversion. Par exemple, dans mon application, les utilisateurs ont tapé un nombre (incluant éventuellement des centimes). Je devais tronquer les centimes et les afficher avec des virgules. L'étape 1 consistait à convertir en int.

2234voto

moonshadow Points 28302
var intvalue = Math.floor( floatvalue );
var intvalue = Math.ceil( floatvalue ); 
var intvalue = Math.round( floatvalue );

// `Math.trunc` was added in ECMAScript 6
var intvalue = Math.trunc( floatvalue );

Référence de l'objet mathématique


Exemples

Positif

// value=x        //  x=5          5<x<5.5      5.5<=x<6  

Math.floor(value) //  5            5            5
Math.ceil(value)  //  5            6            6
Math.round(value) //  5            5            6
Math.trunc(value) //  5            5            5
parseInt(value)   //  5            5            5
~~value           //  5            5            5
value | 0         //  5            5            5
value >> 0        //  5            5            5
value >>> 0       //  5            5            5
value - value % 1 //  5            5            5

Négatif

// value=x        // x=-5         -5>x>=-5.5   -5.5>x>-6

Math.floor(value) // -5           -6           -6
Math.ceil(value)  // -5           -5           -5
Math.round(value) // -5           -5           -6
Math.trunc(value) // -5           -5           -5
parseInt(value)   // -5           -5           -5
value | 0         // -5           -5           -5
~~value           // -5           -5           -5
value >> 0        // -5           -5           -5
value >>> 0       // 4294967291   4294967291   4294967291
value - value % 1 // -5           -5           -5

Positif - Des chiffres plus importants

// x = Number.MAX_SAFE_INTEGER/10 // =900719925474099.1

// value=x            x=900719925474099    x=900719925474099.4  x=900719925474099.5

Math.floor(value) //  900719925474099      900719925474099      900719925474099
Math.ceil(value)  //  900719925474099      900719925474100      900719925474100
Math.round(value) //  900719925474099      900719925474099      900719925474100
Math.trunc(value) //  900719925474099      900719925474099      900719925474099
parseInt(value)   //  900719925474099      900719925474099      900719925474099
value | 0         //  858993459            858993459            858993459
~~value           //  858993459            858993459            858993459
value >> 0        //  858993459            858993459            858993459
value >>> 0       //  858993459            858993459            858993459
value - value % 1 //  900719925474099      900719925474099      900719925474099

Négatif - Chiffres plus élevés

// x = Number.MAX_SAFE_INTEGER/10 * -1 // -900719925474099.1

// value = x      // x=-900719925474099   x=-900719925474099.5 x=-900719925474099.6

Math.floor(value) // -900719925474099     -900719925474100     -900719925474100
Math.ceil(value)  // -900719925474099     -900719925474099     -900719925474099
Math.round(value) // -900719925474099     -900719925474099     -900719925474100
Math.trunc(value) // -900719925474099     -900719925474099     -900719925474099
parseInt(value)   // -900719925474099     -900719925474099     -900719925474099
value | 0         // -858993459           -858993459           -858993459
~~value           // -858993459           -858993459           -858993459
value >> 0        // -858993459           -858993459           -858993459
value >>> 0       //  3435973837           3435973837           3435973837
value - value % 1 // -900719925474099     -900719925474099     -900719925474099

91 votes

Comme mentionné dans une autre réponse, un troncature à sécurité négative peut être effectué en utilisant var intValue = ~~floatValue; . Si la notation est trop obscure à votre goût, il suffit de la cacher dans une fonction : function toInt(value) { return ~~value; } . (Cela convertit également les chaînes de caractères en nombres entiers, si vous le souhaitez).

6 votes

Je donnerais une note plus élevée si cette réponse comportait un exemple d'entrée/sortie.

12 votes

Concernant le commentaire, ~~ limite la valeur à des entiers signés de 32 bits, alors que Math.floor/ceil/round peut gérer jusqu'à 53 bits (Number.MAX_SAFE_INTEGER 9007199254740991). Ceci est mentionné dans la réponse ci-dessous, mais il est utile de le répéter ici pour ceux qui lisent ces commentaires.

344voto

Robert Koritnik Points 45499

Opérateur OR par bit

L'opérateur bit à bit ou peut être utilisé pour tronquer les chiffres en virgule flottante et il fonctionne aussi bien pour les positifs que pour les négatifs :

function float2int (value) {
    return value | 0;
}

Résultats

float2int(3.1) == 3
float2int(-3.1) == -3
float2int(3.9) == 3
float2int(-3.9) == -3

Comparaison des performances ?

J'ai créé un Test JSPerf qui compare les performances entre :

  • Math.floor(val)
  • val | 0 par bit OU
  • ~~val par bit PAS
  • parseInt(val)

qui ne fonctionne qu'avec des nombres positifs. Dans ce cas, vous pouvez utiliser les opérations de type bitwise comme Math.floor fonction.

Mais si vous avez besoin que votre code travailler avec les points positifs comme avec les points négatifs alors une opération par bit est la plus rapide (OR étant la préférée). Cet autre test JSPerf compare les mêmes où il est assez évident qu'en raison de la vérification supplémentaire du signe Les mathématiques sont maintenant les plus lentes des quatre.

Note

Comme indiqué dans les commentaires, les opérateurs BITWISE opèrent sur des entiers signés de 32 bits, donc de grands nombres seront convertis, exemple :

1234567890  | 0 => 1234567890
12345678901 | 0 => -539222987

0 votes

@FabioPoloni : oui super simple et il semble que les opérateurs bitwise soient les plus rapides. En particulier, l'opérateur OR est toujours le plus rapide, souvent égalé par NOT et les opérations mathématiques, bien que les opérations mathématiques soient les plus lentes lorsque vous devez également prendre en charge les nombres négatifs, car cela ajoute une vérification supplémentaire du signe du nombre.

12 votes

@thefourtheye : Toutes les opérations de type bit, à l'exception du décalage à droite non signé, fonctionnent sur des entiers 32 bits signés. Par conséquent, l'utilisation d'opérations par bit sur des valeurs à virgule flottante les convertira en un nombre entier en supprimant les chiffres après le point décimal.

0 votes

Bitwise Not est puissant en termes de vitesse.

101voto

Remarque : Vous ne pouvez pas utiliser Math.floor() en remplacement de truncate, car Math.floor(-3.1) = -4 et non -3 ! !

Un remplacement correct de truncate serait :

function truncate(value)
{
    if (value < 0) {
        return Math.ceil(value);
    }

    return Math.floor(value);
}

50voto

brad Points 12878

Un double pas par bit peut être utilisé pour tronquer les flottants. Les autres opérations que vous avez mentionnées sont disponibles via Math.floor , Math.ceil y Math.round .

> ~~2.5
2
> ~~(-1.4)
-1

Plus de détails à la courtoisie de James Padolsey.

1 votes

C'est probablement une mauvaise chose à faire pour le code de production (puisque c'est obscur) mais c'était exactement ce dont j'avais besoin pour le code-golfing. mon <canvas> moteur de rendu des polices en JS . Merci !

11 votes

Ceci peut également être accompli avec n | 0.

20 votes

Notez que les deux méthodes (~~n ou n|0) ne fonctionnent que sur les nombres jusqu'à 2^31-1, ou 2147483647. 2147483648 ou plus renvoie un résultat incorrect ; par exemple, 2147483647|0 renvoie -2147483648, et 4294967295|0 renvoie -1, ce qui n'est presque jamais ce que vous voulez.

43voto

Mike Points 4226

Pour tronquer :

var intvalue = Math.floor(value);

Pour la ronde :

var intvalue = Math.round(value);

7 votes

Math.floor ne tronque pas les valeurs négatives. Voir la réponse ci-dessus. Sinon, bonne réponse.

0 votes

Si vous êtes intéressé par les performances, j'ai mis un petit test ici : jsperf.com/dsafdgdfsaf/2 (var | 0 gagne ici).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X