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.
Réponses
Trop de publicités?-
Math.floor() La fonction renvoie le plus grand nombre entier inférieur ou égal à un nombre donné.
console.log('Math.floor : ', Math.floor(3.5)); console.log('Math.floor : ', Math.floor(-3.5));
-
Math.ceil() arrondit toujours un nombre à l'entier supérieur.
console.log('Math.ceil : ', Math.ceil(3.5)); console.log('Math.ceil : ', Math.ceil(-3.5));
-
Math.round() La fonction renvoie la valeur d'un nombre arrondi à l'entier le plus proche.
console.log('Math.round : ', Math.round(3.5)); console.log('Math.round : ', Math.round(-3.5));
-
Math.trunc() La fonction renvoie la partie entière d'un nombre en supprimant tous les chiffres fractionnaires.
console.log('Math.trunc : ', Math.trunc(3.5)); console.log('Math.trunc : ', Math.trunc(-3.5));
Il y a beaucoup de suggestions ici. La fonction OU bit à bit semble être de loin la plus simple. Voici une autre solution courte qui fonctionne également avec les nombres négatifs en utilisant l'opérateur modulo. Elle est probablement plus facile à comprendre que le OU bit à bit :
intval = floatval - floatval%1;
Cette méthode fonctionne également avec des nombres de grande valeur pour lesquels ni '|0', ni '~~', ni '>>0' ne fonctionnent correctement :
> n=4294967295;
> n|0
-1
> ~~n
-1
> n>>0
-1
> n-n%1
4294967295
Performance
Aujourd'hui 2020.11.28 j'effectue des tests sur MacOs HighSierra 10.13.6 sur Chrome v85, Safari v13.1.2 et Firefox v80 pour les solutions choisies.
Résultats
- pour tous les navigateurs, toutes les solutions (sauf B et K) donnent des résultats de vitesse très similaires
- les solutions B et K sont lentes
Détails
J'ai effectué un test de cas que vous pouvez exécuter ICI
L'extrait ci-dessous présente les différences entre les solutions A B C D E F G H I J K L
function A(float) {
return Math.trunc( float );
}
function B(float) {
return parseInt(float);
}
function C(float) {
return float | 0;
}
function D(float) {
return ~~float;
}
function E(float) {
return float >> 0;
}
function F(float) {
return float - float%1;
}
function G(float) {
return float ^ 0;
}
function H(float) {
return Math.floor( float );
}
function I(float) {
return Math.ceil( float );
}
function J(float) {
return Math.round( float );
}
function K(float) {
return float.toFixed(0);
}
function L(float) {
return float >>> 0;
}
// ---------
// TEST
// ---------
[A,B,C,D,E,F,G,H,I,J,K,L]
.forEach(f=> console.log(`${f.name} ${f(1.5)} ${f(-1.5)} ${f(2.499)} ${f(-2.499)}`))
This snippet only presents functions used in performance tests - it not perform tests itself!
Et voici des exemples de résultats pour le chrome
Firefox 16 a Number.toInteger
:
assertEq(Number.toInteger(4.), 4);
assertEq(Number.toInteger(4.3), 4);
assertEq(Number.toInteger(-4), -4);
assertEq(Number.toInteger(-4.), -4);
assertEq(Number.toInteger(-4.3), -4);
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.
1 votes
Également utile : comparaison de la vitesse de toutes les méthodes jsperf.com/math-floor-vs-math-round-vs-parseint/33
0 votes
@mcherm pourquoi ne pas piéger le caractère décimal et ne pas autoriser son utilisation ? N'est-ce pas une meilleure expérience pour l'utilisateur ? De plus, si votre code ne permet à l'utilisateur que de saisir [0..9], vous n'avez pas besoin de convertir en entier. Cette question reste utile.
1 votes
@karl : Si j'accepte une entrée dans un champ, je pourrais être en mesure de contrôler les caractères que j'accepte, mais je pourrais effectuer toutes sortes de traitements en Javascript, et pas seulement accepter l'entrée de l'utilisateur. Même dans ce cas, je pourrais en avoir besoin pour des choses comme le support du collage.