Comment vérifier qu'un nombre est flottant ou entier?

717

Comment trouver qu'un nombre est floatou integer?

1.25 --> float  
1 --> integer  
0 --> integer  
0.25 --> float
coure2011
la source
47
Je comprends ce que vous demandez ici, mais juste pour être clair: <nit-pick>JavaScript n'a pas différents types numériques entiers et flottants. Chaque numéro en JavaScript n'est qu'un Number. </nit-pick>
Matt Ball
4
Est-ce Infinityune valeur entière ou non entière en ce qui vous concerne? Les réponses ici sont réparties assez uniformément sur ce point.
Mike Samuel
11
@MikeSamuel Pour être mathématiquement précis: puisque l'infini n'est pas un nombre réel et que tous les entiers sont des nombres réels, Infinityne peut pas être considéré comme un entier.
rvighne
@rvighne, La question porte sur "float", pas "real". Quoi qu'il en soit, les réels ne sont pas pertinents car les ordinateurs ne peuvent représenter que des nombres calculables .
Mike Samuel
2
@rvighne, je pense que nous sommes d'accord que le fait que les infinis et NaN ne soient pas des nombres réels signifie que les flottants IEEE-754 ne sont pas un sous-ensemble de nombres réels. Toute analyse numérique basée sur IEEE-754 doit tenir compte de ce fait. Ce que je ne comprends pas, c'est comment vous pensez que ce fait détermine comment is_integral devrait se comporter par rapport aux cardinalités. Personnellement, je pense que ((x% 1) == 0) est un bon proxy et est entièrement spécifié par IEEE-754, il n'est donc pas nécessaire de discuter des correspondances entre les différentes lignes numériques.
Mike Samuel

Réponses:

1256

vérifier un reste lors de la division par 1:

function isInt(n) {
   return n % 1 === 0;
}

Si vous ne savez pas que l'argument est un nombre, vous avez besoin de deux tests:

function isInt(n){
    return Number(n) === n && n % 1 === 0;
}

function isFloat(n){
    return Number(n) === n && n % 1 !== 0;
}

Mise à jour 2019 5 ans après la rédaction de cette réponse, une solution a été normalisée dans ECMA Script 2015. Cette solution est couverte dans cette réponse .

kennebec
la source
138
Attention, ce sera aussi vrai pour revenir une chaîne vide, une chaîne représentant un nombre entier, true, false, null, un tableau vide, un tableau contenant un seul nombre entier, un tableau contenant une chaîne représentant un nombre entier, et peut - être plus.
Dagg Nabbit,
17
Belle astuce mais pas la bonne réponse car elle ne vérifie pas la chaîne vide ""et 1.0 isInt("");&& les isInt(1.0);deux résultent en truevoir cette démo jsbin.com/elohuq/1/edit
Champ
9
Ina, l'utilisation de === est encouragée par rapport à == en général, car elle conduit à plus de sécurité de type et à un comportement plus prévisible et uniforme. Comme l'ont dit les précédents répondants, cette réponse est absolument 100% incorrecte. Les valeurs null, chaîne vide, 1.0 et bien d'autres s'enregistrent toutes incorrectement en tant qu'entiers (même avec la vérification ===).
whoblitz
54
La question était de savoir comment vérifier si un nombre est un entier, pas comment vérifier une valeur.
kennebec
24
Beaucoup de commentaires hostiles sur la façon dont il ne valide pas les chaînes. Cela ne fait pas partie de la question du PO. Si je passe à SO pour poser une question sur la récupération du dernier élément d'un tableau et que quelqu'un y répond function last (array) { return array[array.length - 1]; }, est-ce "juste faux" ou "pire réponse sur SO" parce qu'il ne vérifie pas si l'argument est un tableau en premier? Oui, bonne pratique pour vérifier les arguments, mais c'est la responsabilité du développeur. Les réponses SO doivent être courtes et répondre directement à la question aussi clairement que possible.
M Miller
150

Essayez ces fonctions pour tester si une valeur est une valeur primitive numérique qui n'a pas de partie fractionnaire et se situe dans les limites de taille de ce qui peut être représenté comme un entier exact.

function isFloat(n) {
    return n === +n && n !== (n|0);
}

function isInteger(n) {
    return n === +n && n === (n|0);
}
Dagg Nabbit
la source
5
heh exploit génial, c'est à peu près le mien ( n===+npour vérifier le numérique, n|0pour l'arrondir), mais avec des opérateurs intégrés. funky
Claudiu
7
@John Hartsock une chaîne ne sera jamais une valeur numérique. C'est une chaîne. Le but de cette fonction est de tester si une valeur est une valeur numérique Javascript qui n'a pas de partie fractionnaire et se situe dans les limites de taille de ce qui peut être représenté comme un entier exact. Si vous voulez vérifier une chaîne pour voir si elle contient une séquence de caractères qui représentent un nombre, vous appelez d' parseFloat()abord.
Pointy
4
@John Hartsock: il ne reviendra pas vrai à moins qu'une primitive numérique n'ait été passée. Je pense que cela a du sens étant donné les noms des fonctions. Tout le reste doit être candidat à isString, isBoolean, etc. si de telles fonctions sont en cours d'écriture.
Dagg Nabbit
4
@Pointy: les flottants double précision peuvent représenter des valeurs entières exactement jusqu'à 2 ^ 53. Cela dépend donc si l'OP posait des questions sur l'entier dans le sens mathématique (nombres entiers) ou dans le sens des données 32 bits. Si c'est le dernier, votre solution est parfaite.
djd
8
en javascript, les opérateurs au niveau du bit comme |(OR) ne fonctionnent que sur des entiers 32 bits signés. OP n'indique pas si l'objectif est de vérifier les valeurs int32 signées. Cela ne fonctionnera donc pas avec des numéros hors plage. isInteger(5000000000)reviendra falsequi est faux!
Onur Yıldırım
93

Pourquoi pas quelque chose comme ça:

var isInt = function(n) { return parseInt(n) === n };
warfares
la source
C'est en fait le cœur d'une bonne solution pour moi. Je devais autoriser les entiers positifs et interdire les flottants, les chaînes et les entiers négatifs.
Imran-UK
4
Cela semble être une solution bien meilleure que les autres dans ce fil. La communauté pourrait-elle émettre des critiques, peut-être?
sbichenko
5
var y = 1,00; y === parseInt (y, 10); // cela revient vrai pour moi, ce qui n'est pas vraiment ce que nous voulons.
whoughton
Le seul "inconvénient" que je vois est que le nombre donné nest converti en chaîne par parseInt. Voir MDN . Mais je vais utiliser cette solution. :)
RhinoDevel
2
@ekussberg: Pourquoi cela devrait-il retourner faux? 1 est un int. et 02, le deuxième argument, est ignoré.
Flimzy
88

Il existe une méthode appelée Number.isInteger()qui est actuellement implémentée dans tout sauf IE. MDN fournit également un polyfill pour les autres navigateurs:

Number.isInteger = Number.isInteger || function(value) {
  return typeof value === 'number' && 
    isFinite(value) && 
    Math.floor(value) === value;
};

Cependant, pour la plupart des cas d'utilisation, il vaut mieux utiliser Number.isSafeInteger ce qui vérifie également si la valeur est si élevée / basse que les décimales auraient été perdues de toute façon. MDN a également un polyfil pour cela. (Vous avez également besoin du isIntegerpollyfill ci-dessus.)

if (!Number.MAX_SAFE_INTEGER) {
    Number.MAX_SAFE_INTEGER = 9007199254740991; // Math.pow(2, 53) - 1;
}
Number.isSafeInteger = Number.isSafeInteger || function (value) {
   return Number.isInteger(value) && Math.abs(value) <= Number.MAX_SAFE_INTEGER;
};
paperstreet7
la source
Cela fonctionne aussi dans mon Chrome et probablement la voie à suivre à l'avenir
Dukeatcoding
1
À mon avis, la meilleure solution.
Automatico
1
Ceci avec le polyfill est la solution la plus fiable et la plus simple.
Francesco Pasa
2
@SergeyPanfilov 12.0 ∈ ℤ.
Константин Ван
1
Je ne sais pas si la spécification a changé depuis que cette réponse a été fournie, mais notez que la fonction ci-dessus n'est pas un polyfill correct pour Number.isInteger. Il s'agit cependant d'un polyfill correct pour Number.isSafeInteger. Number.isIntegerne doit pas vérifier si le nombre est un "entier sûr". Voir sur MDN: isInteger et isSafeInteger .
nunocastromartins
33

Vous pouvez utiliser une expression régulière simple:

function isInt(value) {

    var er = /^-?[0-9]+$/;

    return er.test(value);
}

Ou vous pouvez également utiliser les fonctions ci-dessous, selon vos besoins. Ils sont développés par le projet PHPJS .

is_int() => Vérifier si le type de variable est entier et si son contenu est entier

is_float() => Vérifier si le type de variable est float et si son contenu est float

ctype_digit() => Vérifier si le type de variable est une chaîne et si son contenu n'a que des chiffres décimaux

Mise à jour 1

Maintenant, il vérifie également les nombres négatifs, merci pour le commentaire @ChrisBartley !

Marcio Mazzucato
la source
1
Idéal pour tester de simples entiers non signés.
tothemario
7
Un paquebot:/^[0-9]+$/.test(String(value))
tothemario
One-liner plus court et légèrement moins lisible:/^[0-9]+$/.test(''+value)
skeggse
3
Ne gère pas les entiers négatifs. Vous n'avez pas besoin non plus de l'opérateur ternaire puisque test () renvoie un booléen. Cela devrait le faire:return /^-?\d+$/.test(String(value));
Chris Bartley
@ChrisBartley, merci! J'ai fait une mise à jour, y compris vos crédits. Veuillez vérifier si tout va bien maintenant.
Marcio Mazzucato
19

Voici des fonctions efficaces qui vérifient si la valeur est un nombre ou peut être convertie en toute sécurité en nombre:

function isNumber(value) {
    if ((undefined === value) || (null === value)) {
        return false;
    }
    if (typeof value == 'number') {
        return true;
    }
    return !isNaN(value - 0);
}

Et pour les entiers (renvoie false si la valeur est un flottant):

function isInteger(value) {
    if ((undefined === value) || (null === value)) {
        return false;
    }
    return value % 1 == 0;
}

L'efficacité ici est que parseInt (ou parseNumber) est évité lorsque la valeur est déjà un nombre. Les deux fonctions d'analyse se convertissent toujours en chaîne d'abord, puis tentent d'analyser cette chaîne, ce qui serait un gaspillage si la valeur est déjà un nombre.

Merci aux autres articles ici pour avoir fourni d'autres idées d'optimisation!

Tal Liron
la source
3
Cette fonction échoue sur la chaîne vide: isNumber ('') est vrai.
Jason Grout
14
function isInteger(x) { return typeof x === "number" && isFinite(x) && Math.floor(x) === x; }
function isFloat(x) { return !!(x % 1); }

// give it a spin

isInteger(1.0);        // true
isFloat(1.0);          // false
isFloat(1.2);          // true
isInteger(1.2);        // false
isFloat(1);            // false
isInteger(1);          // true    
isFloat(2e+2);         // false
isInteger(2e+2);       // true
isFloat('1');          // false
isInteger('1');        // false
isFloat(NaN);          // false
isInteger(NaN);        // false
isFloat(null);         // false
isInteger(null);       // false
isFloat(undefined);    // false
isInteger(undefined);  // false
carillon
la source
4
Apparemment, les flottants qui se terminent par .0 sont automatiquement castés en Int en JavaScript.
a échoué avec 1.2. Toujours tester les fonctions numériques avec 0,1 0,2 0,3
Lukas Liesis
@LukasLies n'est pas pour moi.
doubleOrt
Ici, aucun des opérateurs d'égalité strictes n'est nécessaire.
doubleOrt
isFloat (1563457121531) renvoie faux
Aalex Gabi
9
function isInt(n) 
{
    return n != "" && !isNaN(n) && Math.round(n) == n;
}
function isFloat(n){
    return n != "" && !isNaN(n) && Math.round(n) != n;
}

fonctionne pour tous les cas.

Deepak Yadav
la source
2
+1 C'est bien. isInt('1')renvoie truecomme prévu (au moins pour moi). Assez étrange, bien que, retourne trueà isInt([5])aussi bien. Cela n'avait pas d'importance pour moi, mais peut pour vous, alors faites attention.
acdcjunior
2
isFloat (12.0) est faux
django
6

Comme d'autres l'ont mentionné, vous n'avez que des doubles en JS. Alors, comment définissez-vous un nombre étant un entier? Vérifiez simplement si le nombre arrondi est égal à lui-même:

function isInteger(f) {
    return typeof(f)==="number" && Math.round(f) == f;
}
function isFloat(f) { return typeof(f)==="number" && !isInteger(f); }
Claudiu
la source
3
Pourrait vouloir vérifier que la valeur est numérique ... isFloat('abc')renvoietrue
Dagg Nabbit
isFloat(NaN) // true
shime
@shime: Bonne capture. NaN est techniquement un nombre à virgule flottante, bien que ... cela dépend du cas d'utilisation, je suppose.
Claudiu
6

Celui-ci, ça va?

isFloat(num) {
    return typeof num === "number" && !Number.isInteger(num);
}
Goehybrid
la source
Essayez des console.log(isFloat(1.0));résultats faux.
Fabian Picone
5

Voici ce que j'utilise pour les entiers:

Math.ceil(parseFloat(val)) === val

Bref, sympa :) Fonctionne tout le temps. C'est ce que suggère David Flanagan si je ne me trompe pas.

Arman McHitarian
la source
J'aime celui-ci parce que c'est une réponse courte et simple qui ne repose pas sur des opérations cryptiques au niveau du bit.
Jim
Pourquoi parseFloat?
doubleOrt
4

Cela dépend vraiment de ce que vous voulez réaliser. Si vous voulez "émuler" des langues fortement typées, je vous suggère de ne pas essayer. Comme d'autres l'ont mentionné, tous les nombres ont la même représentation (le même type).

Utiliser quelque chose comme Claudiu a fourni:

isInteger( 1.0 ) -> vrai

qui semble bien pour le bon sens, mais dans quelque chose comme C, vous obtiendrez false

gblazex
la source
4

Tout nombre flottant avec une partie décimale nulle (par exemple 1.0, 12.00, 0.0) est implicitement converti en entier, il n'est donc pas possible de vérifier s'il est flottant ou non.

Mike Mancini
la source
4
!!(24%1) // false
!!(24.2%1) // true
Виктор Дакалов
la source
!!(24.0%1)est faux
Rohmer
3

Ça n'a pas besoin d'être si compliqué. La valeur numérique des équivalents parseFloat () et parseInt () d'un entier sera la même. Ainsi, vous pouvez faire comme ça:

function isInt(value){ 
    return (parseFloat(value) == parseInt(value)) && !isNaN(value);
}

alors

if (isInt(x)) // do work

Cela permettra également de vérifier les chaînes et n'est donc pas strict. Si vous voulez une solution de type fort (aka, ne fonctionnera pas avec des chaînes):

function is_int(value){ return !isNaN(parseInt(value * 1) }
SpYk3HH
la source
isInteger (12.0) est vrai
django
3
var isInt = function (n) { return n === (n | 0); };

Je n'ai pas eu de cas où cela n'a pas fait l'affaire.

ankr
la source
hey désolé pourquoi cela retourne faux? console.log (isInt (7932938942839482938));
itsme
4
Parce que cela dépasse MaxInt.
ankr
mais vous pouvez définir une longueur int max non? que faire si je ne sais pas la longueur int est retournée?
itsme
1
@ekussberg Oui car 2est un entier et 23est considéré comme un deuxième argument de la fonction. En javascript, les décimales sont écrites en utilisant le point comme séparateur - il devrait donc en être ainsi 2.23.
ankr
1
Ou c'est une excellente occasion d'en apprendre davantage sur les opérations au niveau du bit. Vous en tirerez beaucoup d'avantages à l'avenir.
2017
2

CECI EST LE CODE FINAL POUR LA VÉRIFICATION À LA FOIS INT ET FLOTTEUR

function isInt(n) { 
   if(typeof n == 'number' && Math.Round(n) % 1 == 0) {
       return true;
   } else {
       return false;
   }
} 

OU

function isInt(n) {   
   return typeof n == 'number' && Math.Round(n) % 1 == 0;   
}   
Ken Le
la source
Cela ne teste le flottant que si n se trouve être un nombre
hacklikecrack
2
function isInteger(n) {
   return ((typeof n==='number')&&(n%1===0));
}

function isFloat(n) {
   return ((typeof n==='number')&&(n%1!==0));
}

function isNumber(n) {
   return (typeof n==='number');
}
Vitim.us
la source
Un entier n'est pas un flotteur? Des nouvelles pour moi.
Maarten Bodewes
2

C'est aussi simple que:

if( n === parseInt(n) ) ...

Essayez ceci dans la console:

x=1;
x===parseInt(x); // true
x="1";
x===parseInt(x); // false
x=1.1;
x===parseInt(x); // false, obviously

// BUT!

x=1.0;
x===parseInt(x); // true, because 1.0 is NOT a float!

Cela déroute beaucoup de gens. Chaque fois que quelque chose est .0, ce n'est plus un flotteur. C'est un entier. Ou vous pouvez simplement l'appeler "une chose numérique" car il n'y a pas de distinction stricte comme à l'époque en C. Bon vieux temps.

Donc, fondamentalement, tout ce que vous pouvez faire est de vérifier l'entier en acceptant le fait que 1.000 est un entier.

Note de côté intéressante

Il y a eu un commentaire sur un nombre énorme. Des nombres énormes signifient AUCUN problème pour cette approche; chaque fois que parseInt est incapable de gérer le nombre (car il est trop grand), il retournera autre chose que la valeur réelle, donc le test retournera FAUX. C'est une bonne chose car si vous considérez quelque chose comme un "nombre", vous vous attendez normalement à ce que JS puisse calculer avec lui - donc oui, les nombres sont limités et parseInt en tiendra compte , pour le dire de cette façon.

Essaye ça:

<script>

var a = 99999999999999999999;
var b = 999999999999999999999; // just one more 9 will kill the show!
var aIsInteger = (a===parseInt(a))?"a is ok":"a fails";
var bIsInteger = (b===parseInt(b))?"b is ok":"b fails";
alert(aIsInteger+"; "+bIsInteger);

</script>

Dans mon navigateur (IE8), cela renvoie "a est correct; b échoue", ce qui est exactement dû au nombre énorme de b. La limite peut varier mais je suppose que 20 chiffres "devraient suffire à tout le monde", pour citer un classique :)

dkellner
la source
C'est très bien si vous avez seulement besoin de vérifier les nombres entiers (à partir d'un PDV mathématique), mais si vous voulez vous assurer qu'ils fonctionnent réellement comme des nombres entiers (à partir d'un PDV informatique), cela va être incorrect pour les nombres énormes. Voir ce commentaire .
Dagg Nabbit
Mmmmmmm ... Pourquoi pensez-vous cela? Je veux dire, si parseInt renvoie quelque chose et qu'il semble égal à la variable elle-même, vous pouvez être sûr que votre n fonctionne vraiment comme un entier. J'ai trouvé que 9999999999999999999999 (c'est-à-dire 20 fois "9") est un nombre tandis que l'ajout d'un "9" entraîne l'échec de parseInt (retour 1). Cela peut dépendre du navigateur; cependant, OUI, il y a une limite et NON, tout ce qui est hors de cette limite ne retournera pas vrai pour la vérification ci-dessus.
dkellner
Ce que je veux dire, c'est que les opérateurs au niveau du bit (qui traitent les nombres comme des entiers 32 bits) ne donneront pas les résultats attendus sur les nombres qui ne peuvent pas être représentés comme des entiers 32 bits, donc ces nombres ne doivent pas être identifiés comme des entiers. Cela est conforme au fonctionnement du projet Number.isInteger.
Dagg Nabbit
Quelque chose peut être un vrai entier sans être stocké d'une manière spécifique. Je vois votre point mais les entiers sont des entiers parce qu'ils n'ont pas de partie fractionnaire et peuvent être ajoutés / soustraits arbitrairement sans obtenir des résultats flottants. Si vous traitez les nombres comme des champs de bits, vous supposez quelque chose sur la façon dont ils sont stockés, ce qui est - à mon avis - un moyen pratiquement fonctionnel mais pas fiable à 100%. Si vous recherchez "un entier stocké d'une certaine manière", eh bien, je ne suis pas sûr qu'il existe un test sur une seule ligne que vous pouvez utiliser en toute sécurité sur toutes les plates-formes.
dkellner
Les nombres qui peuvent être exprimés en entiers 32 bits fonctionnent de manière fiable à 100% avec les opérateurs au niveau du bit. Vous ne "supposez rien sur la façon dont ils sont stockés;" les nombres sont convertis en entiers complétés à deux bits signés big-endian 32 bits, par spécification. Les nombres qui ne peuvent pas être représentés dans ce format ne doivent pas être considérés comme des nombres entiers. Encore une fois, cela correspond à la façon dont Number.isIntegerfonctionne. Un test sur une seule ligne est n === (n | 0)comme indiqué dans une autre réponse.
Dagg Nabbit
2

Cette solution a fonctionné pour moi.

<html>
<body>
  <form method="post" action="#">
    <input type="text" id="number_id"/>
    <input type="submit" value="send"/>
  </form>
  <p id="message"></p>
  <script>
    var flt=document.getElementById("number_id").value;
    if(isNaN(flt)==false && Number.isInteger(flt)==false)
    {
     document.getElementById("message").innerHTML="the number_id is a float ";
    }
   else 
   {
     document.getElementById("message").innerHTML="the number_id is a Integer";
   }
  </script>
</body>
</html>
Abdelraouf GR
la source
1

Pour les entiers, j'utilise ceci

function integer_or_null(value) {
    if ((undefined === value) || (null === value)) {
        return null;
    }
    if(value % 1 != 0) {
        return null;
    }
    return value;
}
neoneye
la source
1

Dans le script java, tous les nombres sont les internally 64 bit floating pointmêmes que le double en java. Il n'y a pas de types différents en javascript, tous sont représentés par type number. Vous ne pourrez donc pas faire de instanceofchèque. Cependant, vous pouvez utiliser les solutions ci-dessus pour savoir s'il s'agit d'un nombre fractionnaire. les concepteurs de script java ont ressenti avec un seul type qu'ils peuvent éviter de nombreuses erreurs de transtypage.

Punith Raj
la source
1

Parfois, les objets Number ne vous permettent pas d'utiliser directement l'opérateur mod (%), si vous êtes confronté à ce cas, vous pouvez utiliser cette solution.

if(object instanceof Number ){
   if( ((Number) object).doubleValue() % 1 == 0 ){
      //your object is an integer
   }
   else{
      //your object is a double
   }
}
toddsalpen
la source
1

En essayant certaines des réponses ici, j'ai fini par écrire cette solution. Cela fonctionne également avec des nombres à l'intérieur d'une chaîne.

function isInt(number) {
    if(!/^["|']{0,1}[-]{0,1}\d{0,}(\.{0,1}\d+)["|']{0,1}$/.test(number)) return false;
    return !(number - parseInt(number));
}

function isFloat(number) {
    if(!/^["|']{0,1}[-]{0,1}\d{0,}(\.{0,1}\d+)["|']{0,1}$/.test(number)) return false;
    return number - parseInt(number) ? true : false;
}

    var tests = {
        'integer' : 1,
        'float' : 1.1,
        'integerInString' : '5',
        'floatInString' : '5.5',
        'negativeInt' : -345,
        'negativeFloat' : -34.98,
        'negativeIntString' : '-45',
        'negativeFloatString' : '-23.09',
        'notValidFalse' : false,
        'notValidTrue' : true,
        'notValidString' : '45lorem',
        'notValidStringFloat' : '4.5lorem',
        'notValidNan' : NaN,
        'notValidObj' : {},
        'notValidArr' : [1,2],
    };

    function isInt(number) {
        if(!/^["|']{0,1}[-]{0,1}\d{0,}(\.{0,1}\d+)["|']{0,1}$/.test(number)) return false;
        return !(number - parseInt(number));
    }
    
    function isFloat(number) {
        if(!/^["|']{0,1}[-]{0,1}\d{0,}(\.{0,1}\d+)["|']{0,1}$/.test(number)) return false;
        return number - parseInt(number) ? true : false;
    }

    function testFunctions(obj) {
        var keys = Object.keys(obj);
        var values = Object.values(obj);

        values.forEach(function(element, index){
            console.log(`Is ${keys[index]} (${element}) var an integer? ${isInt(element)}`);
            console.log(`Is ${keys[index]} (${element}) var a float? ${isFloat(element)}`);
        });
    }

    testFunctions(tests);

Alejandro Hernandez
la source
0

Ce n'est peut-être pas aussi performant que la réponse%, ce qui vous empêche d'avoir à convertir d'abord en chaîne, mais je n'ai encore vu personne la publier, alors voici une autre option qui devrait fonctionner correctement:

function isInteger(num) {
    return num.toString().indexOf('.') === -1;
}
Essieu
la source
Bonne approche à mon humble avis
Sergei Panfilov
J'ajouterais que la méthode ES6 comprend () rend cette réponse encore plus simple
Axle
0

Pour les curieux, en utilisant Benchmark.js, j'ai testé les réponses les plus votées (et celle publiée aujourd'hui) sur ce post, voici mes résultats:

var n = -10.4375892034758293405790;
var suite = new Benchmark.Suite;
suite
    // kennebec
    .add('0', function() {
        return n % 1 == 0;
    })
    // kennebec
    .add('1', function() {
        return typeof n === 'number' && n % 1 == 0;
    })
    // kennebec
    .add('2', function() {
        return typeof n === 'number' && parseFloat(n) == parseInt(n, 10) && !isNaN(n);
    })

    // Axle
    .add('3', function() {
        return n.toString().indexOf('.') === -1;
    })

    // Dagg Nabbit
    .add('4', function() {
        return n === +n && n === (n|0);
    })

    // warfares
    .add('5', function() {
        return parseInt(n) === n;
    })

    // Marcio Simao
    .add('6', function() {
        return /^-?[0-9]+$/.test(n.toString());
    })

    // Tal Liron
    .add('7', function() {
        if ((undefined === n) || (null === n)) {
            return false;
        }
        if (typeof n == 'number') {
            return true;
        }
        return !isNaN(n - 0);
    });

// Define logs and Run
suite.on('cycle', function(event) {
    console.log(String(event.target));
}).on('complete', function() {
    console.log('Fastest is ' + this.filter('fastest').pluck('name'));
}).run({ 'async': true });

0 x 12,832,357 ops/sec ±0.65% (90 runs sampled)
1 x 12,916,439 ops/sec ±0.62% (95 runs sampled)
2 x 2,776,583 ops/sec ±0.93% (92 runs sampled)
3 x 10,345,379 ops/sec ±0.49% (97 runs sampled)
4 x 53,766,106 ops/sec ±0.66% (93 runs sampled)
5 x 26,514,109 ops/sec ±2.72% (93 runs sampled)
6 x 10,146,270 ops/sec ±2.54% (90 runs sampled)
7 x 60,353,419 ops/sec ±0.35% (97 runs sampled)

Fastest is 7 Tal Liron
jnthnjns
la source
0

Voici mon code. Il vérifie que ce n'est pas une chaîne vide (qui passera autrement), puis la convertit au format numérique. Maintenant, selon que vous voulez que «1.1» soit égal à 1.1, cela peut ou non être ce que vous recherchez.

var isFloat = function(n) {
    n = n.length > 0 ? Number(n) : false;
    return (n === parseFloat(n));
};
var isInteger = function(n) {
    n = n.length > 0 ? Number(n) : false;
    return (n === parseInt(n));
};

var isNumeric = function(n){

   if(isInteger(n) || isFloat(n)){
        return true;
   }
   return false;

};
Michael Ryan Soileau
la source
0

J'aime cette petite fonction, qui retournera true pour les entiers positifs et négatifs:

function isInt(val) {
    return ["string","number"].indexOf(typeof(val)) > -1 && val !== '' && !isNaN(val+".0");
}

Cela fonctionne parce que 1 ou "1" devient "1.0", ce qui isNaN () renvoie false sur (que nous annulons ensuite et retournons), mais 1.0 ou "1.0" devient "1.0.0", tandis que "string" devient "string. 0 ", dont aucun n'est un nombre, donc isNaN () renvoie false (et, encore une fois, est annulé).

Si vous ne voulez que des entiers positifs, il y a cette variante:

function isPositiveInt(val) {
    return ["string","number"].indexOf(typeof(val)) > -1 && val !== '' && !isNaN("0"+val);
}

ou, pour les entiers négatifs:

function isNegativeInt(val) {
    return `["string","number"].indexOf(typeof(val)) > -1` && val !== '' && isNaN("0"+val);
}

isPositiveInt () fonctionne en déplaçant la chaîne numérique concaténée avant la valeur à tester. Par exemple, isPositiveInt (1) a pour résultat que isNaN () évalue "01", ce qui est faux. Pendant ce temps, isPositiveInt (-1) a pour résultat que isNaN () évalue "0-1", ce qui est vrai. Nous nions la valeur de retour et cela nous donne ce que nous voulons. isNegativeInt () fonctionne de la même manière, mais sans annuler la valeur de retour de isNaN ().

Éditer:

Mon implémentation d'origine retournerait également true sur les tableaux et les chaînes vides. Cette implémentation n'a pas ce défaut. Il a également l'avantage de revenir plus tôt si val n'est pas une chaîne ou un nombre, ou s'il s'agit d'une chaîne vide, ce qui le rend plus rapide dans ces cas. Vous pouvez le modifier en remplaçant les deux premières clauses par

typeof(val) != "number"

si vous souhaitez uniquement faire correspondre les nombres littéraux (et non les chaînes)

Éditer:

Je ne peux pas encore poster de commentaires, alors j'ajoute ceci à ma réponse. L'indice de référence publié par @Asok est très informatif; cependant, la fonction la plus rapide ne correspond pas aux exigences, car elle renvoie également TRUE pour les flottants, les tableaux, les booléens et les chaînes vides.

J'ai créé la suite de tests suivante pour tester chacune des fonctions, en ajoutant également ma réponse à la liste (fonction 8, qui analyse les chaînes, et fonction 9, qui ne le fait pas):

funcs = [
    function(n) {
        return n % 1 == 0;
    },
    function(n) {
        return typeof n === 'number' && n % 1 == 0;
    },
    function(n) {
        return typeof n === 'number' && parseFloat(n) == parseInt(n, 10) && !isNaN(n);
    },
    function(n) {
        return n.toString().indexOf('.') === -1;
    },
    function(n) {
        return n === +n && n === (n|0);
    },
    function(n) {
        return parseInt(n) === n;
    },
    function(n) {
        return /^-?[0-9]+$/.test(n.toString());
    },
    function(n) {
        if ((undefined === n) || (null === n)) {
            return false;
        }
        if (typeof n == 'number') {
            return true;
        }
        return !isNaN(n - 0);
    },
    function(n) {
        return ["string","number"].indexOf(typeof(n)) > -1 && n !== '' && !isNaN(n+".0");
    }
];
vals = [
    [1,true],
    [-1,true],
    [1.1,false],
    [-1.1,false],
    [[],false],
    [{},false],
    [true,false],
    [false,false],
    [null,false],
    ["",false],
    ["a",false],
    ["1",null],
    ["-1",null],
    ["1.1",null],
    ["-1.1",null]
];

for (var i in funcs) {
    var pass = true;
    console.log("Testing function "+i);
    for (var ii in vals) {
        var n = vals[ii][0];
        var ns;
        if (n === null) {
            ns = n+"";
        } else {
            switch (typeof(n)) {
                case "string":
                    ns = "'" + n + "'";
                    break;
                case "object":
                    ns = Object.prototype.toString.call(n);
                    break;
                default:
                    ns = n;
            }
            ns = "("+typeof(n)+") "+ns;
        }

        var x = vals[ii][1];
        var xs;
        if (x === null) {
            xs = "(ANY)";
        } else {
            switch (typeof(x)) {
                case "string":
                    xs = "'" + n + "'";
                    break;
                case "object":
                    xs = Object.prototype.toString.call(x);
                    break;
                default:
                    xs = x;
            }
            xs = "("+typeof(x)+") "+xs;
        }

        var rms;
        try {
            var r = funcs[i](n);
            var rs;
            if (r === null) {
                rs = r+"";
            } else {
                switch (typeof(r)) {
                    case "string":
                        rs = "'" + r + "'";
                        break;
                    case "object":
                        rs = Object.prototype.toString.call(r);
                        break;
                    default:
                        rs = r;
                }
                rs = "("+typeof(r)+") "+rs;
            }

            var m;
            var ms;
            if (x === null) {
                m = true;
                ms = "N/A";
            } else if (typeof(x) == 'object') {
                m = (xs === rs);
                ms = m;
            } else {
                m = (x === r);
                ms = m;
            }
            if (!m) {
                pass = false;
            }
            rms = "Result: "+rs+", Match: "+ms;
        } catch (e) {
            rms = "Test skipped; function threw exception!"
        }

        console.log("    Value: "+ns+", Expect: "+xs+", "+rms);
    }
    console.log(pass ? "PASS!" : "FAIL!");
}

J'ai également relancé le benchmark avec la fonction # 8 ajoutée à la liste. Je ne publierai pas le résultat, car ils sont un peu gênants (par exemple, cette fonction n'est PAS rapide) ...

Les résultats (abrégés - j'ai supprimé les tests réussis, car la sortie est assez longue) sont les suivants:

Testing function 0
Value: (object) [object Array], Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (boolean) true, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (boolean) false, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: null, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (string) '', Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (string) '1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
FAIL!

Testing function 1
Value: (string) '1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

Testing function 2
Value: (string) '1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

Testing function 3
Value: (object) true, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (object) false, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (boolean) [object Array], Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (boolean) [object Object], Expect: (boolean) false, Result: (boolean) true, Match: false
Value: null, Expect: (boolean) false, Test skipped; function threw exception!
Value: (string) '', Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (string) 'a', Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (string) '1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
FAIL!

Testing function 4
Value: (string) '1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

Testing function 5
Value: (string) '1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

Testing function 6
Value: null, Expect: (boolean) false, Test skipped; function threw exception!
Value: (string) '1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

Testing function 7
Value: (number) 1.1, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (number) -1.1, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (object) true, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (boolean) [object Array], Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (boolean) [object Object], Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (string) '', Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (string) '1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) true, Match: N/A
FAIL!

Testing function 8
Value: (string) '1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

Testing function 9
Value: (string) '1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

J'ai laissé des échecs pour que vous puissiez voir où chaque fonction échoue et les tests (chaîne) '#' pour que vous puissiez voir comment chaque fonction gère les valeurs entières et flottantes dans les chaînes, car certains peuvent vouloir que ces analyses soient analysées en tant que nombres et d'autres Peut-être pas.

Sur les 10 fonctions testées, celles qui correspondent réellement aux exigences de l'OP sont [1,3,5,6,8,9]

KeMBro2012
la source
0

Condition de validation flottante:

if (lnk.value == +lnk.value && lnk.value != (lnk.value | 0)) 

Condition pour la validation entière:

if (lnk.value == +lnk.value && lnk.value == (lnk.value | 0)) 

J'espère que cela pourrait être utile.

Joe Mike
la source
0
function int(a) {
  return a - a === 0 && a.toString(32).indexOf('.') === -1
}

function float(a) {
  return a - a === 0 && a.toString(32).indexOf('.') !== -1
}

Vous pouvez ajouter typeof a === 'number'si vous souhaitez exclure des chaînes.

Mirek Rusin
la source