Reputation: 5509
How do I check if a variable is an integer in JavaScript, and throw an alert if it isn't? I tried this, but it doesn't work:
<html>
<head>
<script type="text/javascript">
var data = 22;
alert(NaN(data));
</script>
</head>
</html>
Upvotes: 528
Views: 786902
Reputation: 11
In modern JS, we can use Number.isInteger
which is native and should always be the first choice.
But let's assume our JS version is old. Maybe we run in an old browser or an old NodeJS version.
In this case the solution will always be based on comparing the number we have with its "integer version".
And here we can use different techniques to make the var an integer.
The fastest technique is to use ~
operator to omit the floating point (if exist), like this: ~~num
.
Not everyone are familiar with this operator and rather not to use it. Therefore, we also have Math.trunc(num)
, which does the same, but it's only in ES2015
.
In any case, the function could be implemented like this:
const isInteger = (value) => {
return value === Math.trunc(value);
};
After few successes and failures, I came up with this solution:
const isInt = (value) => {
return String(parseInt(value, 10)) === String(value)
}
I liked the idea above of checking the value for not being NaN and use parseFloat, but when I tried it in React infrastructure it didn't work for some reason.
Edit: I found a nicer way without using strings:
var isInt = function (str) {
return str == '0' || !!~~str;
}
I think it's the shortest answer. Maybe even the most efficient, but I could be stand corrected. :)
Upvotes: 1
Reputation: 3154
In ES6 2 new methods are added for Number Object.
In it Number.isInteger() method returns true if the argument is an integer, otherwise returns false.
Important Note: The method will also return true for floating point numbers that can be represented as integer. Eg: 5.0 (as it is exactly equal to 5 )
Example usage :
Number.isInteger(0); // true
Number.isInteger(1); // true
Number.isInteger(5.0); // true
Number.isInteger(-100000); // true
Number.isInteger(99999999999999999999999); // true
Number.isInteger(0.1); // false
Number.isInteger(Math.PI); // false
Number.isInteger(NaN); // false
Number.isInteger(Infinity); // false
Number.isInteger(-Infinity); // false
Number.isInteger('10'); // false
Number.isInteger(true); // false
Number.isInteger(false); // false
Number.isInteger([1]); // false
Number.isInteger(5.000000000000001); // false
Number.isInteger(5.0000000000000001); // true
Upvotes: 35
Reputation: 75
Try the following function:
function isInteger (num) {
return num == parseInt(+num,10) && !isNaN(parseInt(num));
}
console.log ( isInteger(42)); // true
console.log ( isInteger("42")); // true
console.log ( isInteger(4e2)); // true
console.log ( isInteger("4e2")); // true
console.log ( isInteger(" 1 ")); // true
console.log ( isInteger("")); // false
console.log ( isInteger(" ")); // false
console.log ( isInteger(42.1)); // false
console.log ( isInteger("1a")); // false
console.log ( isInteger("4e2a")); // false
console.log ( isInteger(null)); // false
console.log ( isInteger(undefined)); // false
console.log ( isInteger(NaN)); // false
console.log ( isInteger(false)); // false
console.log ( isInteger(true)); // false
console.log ( isInteger(Infinity)); // false
Upvotes: 1
Reputation: 130175
a >= 1e+21
→ Only pass for very large numbers. This will cover all cases for sure, unlike other solutions which has been provided in this discussion.
a === (a|0)
→ if the given function's argument is exactly the same (===) as the bitwise-transformed value, it means that the argument is an integer.
a|0
→ return 0
for any value of a
that isn't a number, and if a
is indeed a number, it will strip away anything after the decimal point, so 1.0001
will become 1
const isInteger = n => n >= 1e+21 ? true : n === (n|0);
// tests:
[
[1, true],
[1000000000000000000000, true],
[4e2, true],
[Infinity, true],
[1.0, true],
[1.0000000000001, false],
[0.1, false],
["0", false],
["1", false],
["1.1", false],
[NaN, false],
[[], false],
[{}, false],
[true, false],
[false, false],
[null, false],
[undefined, false],
].forEach(([test, expected]) =>
console.log(
isInteger(test) === expected,
typeof test,
test
)
)
Upvotes: 3
Reputation: 2499
With todays browsers Number.isInteger()
is way to go just like many answers before this explained but I came across problem which is common and it ocured when I was building API
.
So in API
request, we receive properties as string
, so Number.isInteger()
will return false
.
If we try checking it with Number.isInteger(parseInt())
then values like 1.1
or 1.asd
will return true
To solve this problem I created function which checks if value is integer
regarding it passed as integer
or string
function isNumber(value) {
return ([...value.toString()]
.filter(x => [ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' ]
.indexOf(x) >= 0))
.length == Math.max(value.toString().length, 1)
}
Math.max()
part is needed to handle empty strings
Upvotes: 1
Reputation: 4754
The Accepted answer not worked for me as i needed to check for int/float and alphabet. so try this at will work for both int/float and alphabet check
function is_int(value){
if( (parseInt(value) % 1 === 0 )){
return true;
}else{
return false;
}
}
usage
is_int(44); // true
is_int("44"); // true
is_int(44.55); // true
is_int("44.55"); // true
is_int("aaa"); // false
Upvotes: 6
Reputation: 4783
So many options in the answers.
isNaN
can be tricky for pure integer and you still need other checks that make it obsolete.
Number.isInteger()
isn't officially supported in IE (most wont care but there are stragglers out there).
I ended up writing something myself:
function isInteger(valueToCheck) {
return typeof valueToCheck !== 'undefined'
&& (valueToCheck === parseInt(valueToCheck, 10));
}
let undefinedValue;
const testValues = [
1,
'',
undefinedValue,
1.1,
'1',
'1.1',
'1-2',
'bob',
false,
[],
[1],
{},
{foo: 1}
];
testValues.forEach(value => {
console.log(`${value} - ${isInteger(value)}`);
})
Results:
1 - true
'' - false
undefined - false
1.1 - false
'1' - false
'1.1' - false
'1-2' - false
'bob' - false
false - false
[] - false
[1] - false
{} - false
{foo: 1} - false
Some test values are overkill but their existence just shows clearly nothing gets through. You could possibly omit the undefined check in the function, but I find undefined things can be weird in JS so felt more secure it being there.
Upvotes: 0
Reputation: 22817
bigint
)?Most of these answers fail on large integers (253 and larger): Bitwise tests(e.g. (x | 0) === x
), testing typeof x === 'number'
, regular int functions (e.g. parseInt
), regular arithmetics fail on large integers. This can be resolved by using BigInt
.
I've compiled several answers into one snippet to show the results. Most outright fail with large integers, while others work, except when passed the type BigInt
(e.g. 1n
). I've not included duplicate answers and have also left out any answers that allow decimals or don't attempt to test type)
// these all fail
n = 1000000000000000000000000000000
b = 1n
// These all fail on large integers
//https://stackoverflow.com/a/14636652/3600709
console.log('fail',1,n === parseInt(n, 10))
//https://stackoverflow.com/a/14794066/3600709
console.log('fail',2,!isNaN(n) && parseInt(Number(n)) == n && !isNaN(parseInt(n, 10)))
console.log('fail',2,!isNaN(n) && (parseFloat(n) | 0) === parseFloat(n))
console.log('fail',2,!isNaN(n) && (function(x) { return (x | 0) === x; })(parseFloat(n)))
//https://stackoverflow.com/a/21742529/3600709
console.log('fail',3,n == ~~n)
//https://stackoverflow.com/a/28211631/3600709
console.log('fail',4,!isNaN(n) && parseInt(n) == parseFloat(n))
//https://stackoverflow.com/a/41854178/3600709
console.log('fail',5,String(parseInt(n, 10)) === String(n))
// These ones work for integers, but not BigInt types (e.g. 1n)
//https://stackoverflow.com/a/14636725/3600709
console.log('partial',1,typeof n==='number' && (n%1)===0) // this one works
console.log('partial',1,typeof b==='number' && (b%1)===0) // this one fails
//https://stackoverflow.com/a/27424770/3600709
console.log('partial',2,Number.isInteger(n)) // this one works
console.log('partial',2,Number.isInteger(b)) // this one fails
//https://stackoverflow.com/a/14636638/3600709
console.log('partial',3,n % 1 === 0)
console.log('partial',3,b % 1 === 0) // gives uncaught type on BigInt
If you actually want to test the incoming value's type to ensure it's an integer, use this instead:
function isInt(value) {
try {
BigInt(value)
return !['string','object','boolean'].includes(typeof value)
} catch(e) {
return false
}
}
function isInt(value) {
try {
BigInt(value)
return !['string','object','boolean'].includes(typeof value)
} catch(e) {
return false
}
}
console.log('--- should be false')
console.log(isInt(undefined))
console.log(isInt(''))
console.log(isInt(null))
console.log(isInt({}))
console.log(isInt([]))
console.log(isInt(1.1e-1))
console.log(isInt(1.1))
console.log(isInt(true))
console.log(isInt(NaN))
console.log(isInt('1'))
console.log(isInt(function(){}))
console.log(isInt(Infinity))
console.log('--- should be true')
console.log(isInt(10))
console.log(isInt(0x11))
console.log(isInt(0))
console.log(isInt(-10000))
console.log(isInt(100000000000000000000000000000000000000))
console.log(isInt(1n))
If you don't care if the incoming type is actually boolean, string, etc. converted into a number, then just use the following:
function isInt(value) {
try {
BigInt(value)
return true
} catch(e) {
return false
}
}
function isInt(value) {
try {
BigInt(value)
return true
} catch(e) {
return false
}
}
console.log('--- should be false')
console.log(isInt(undefined))
console.log(isInt(null))
console.log(isInt({}))
console.log(isInt(1.1e-1))
console.log(isInt(1.1))
console.log(isInt(NaN))
console.log(isInt(function(){}))
console.log(isInt(Infinity))
console.log('--- should be true')
console.log(isInt(10))
console.log(isInt(0x11))
console.log(isInt(0))
console.log(isInt(-10000))
console.log(isInt(100000000000000000000000000000000000000))
console.log(isInt(1n))
// gets converted to number
console.log(isInt(''))
console.log(isInt([]))
console.log(isInt(true))
console.log(isInt('1'))
Upvotes: 4
Reputation: 425
The 'accepted' answer is wrong (as some comments below point out). this modification can make it work:
if (data.toString() === parseInt(data, 10).toString())
alert("data is a valid integer")
else
alert("data is not a valid integer")
Upvotes: 3
Reputation: 79
Just try this:
let number = 5;
if (Number.isInteger(number)) {
//do something
}
Upvotes: 4
Reputation: 2154
you can also try it this way
var data = 22;
if (Number.isInteger(data)) {
console.log("integer");
}else{
console.log("not an integer");
}
or
if (data === parseInt(data, 10)){
console.log("integer");
}else{
console.log("not an integer");
}
Upvotes: 2
Reputation: 7117
That depends, do you also want to cast strings as potential integers as well?
This will do:
function isInt(value) {
return !isNaN(value) &&
parseInt(Number(value)) == value &&
!isNaN(parseInt(value, 10));
}
Simple parse and check
function isInt(value) {
var x = parseFloat(value);
return !isNaN(value) && (x | 0) === x;
}
Short-circuiting, and saving a parse operation:
function isInt(value) {
if (isNaN(value)) {
return false;
}
var x = parseFloat(value);
return (x | 0) === x;
}
Or perhaps both in one shot:
function isInt(value) {
return !isNaN(value) && (function(x) { return (x | 0) === x; })(parseFloat(value))
}
Tests:
isInt(42) // true
isInt("42") // true
isInt(4e2) // true
isInt("4e2") // true
isInt(" 1 ") // true
isInt("") // false
isInt(" ") // false
isInt(42.1) // false
isInt("1a") // false
isInt("4e2a") // false
isInt(null) // false
isInt(undefined) // false
isInt(NaN) // false
Here's the fiddle: http://jsfiddle.net/opfyrqwp/28/
Testing reveals that the short-circuiting solution has the best performance (ops/sec).
// Short-circuiting, and saving a parse operation
function isInt(value) {
var x;
if (isNaN(value)) {
return false;
}
x = parseFloat(value);
return (x | 0) === x;
}
Here is a benchmark: http://jsben.ch/#/htLVw
If you fancy a shorter, obtuse form of short circuiting:
function isInt(value) {
var x;
return isNaN(value) ? !1 : (x = parseFloat(value), (0 | x) === x);
}
Of course, I'd suggest letting the minifier take care of that.
Upvotes: 604
Reputation: 9295
You can use a simple regular expression:
function isInt(value) {
var er = /^-?[0-9]+$/;
return er.test(value);
}
Upvotes: 32
Reputation: 419
Why hasnt anyone mentioned Number.isInteger()
?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger
Works perfectly for me and solves the issue with the NaN
beginning a number.
Upvotes: 7
Reputation: 3700
Add class numOnly for the textbox,
$(document).on("input", ".numOnly", function(e) {
this.value = this.value.replace(/[^0-9\$]/g,'');
if(this.value!=""){
alert('Integer Number.');
}else{
alert('Not an Integer Number.');
}
});
It works for me.. Try this one
You can use keypres,keyup,keydown etc., instead input.
Upvotes: -2
Reputation: 5039
Ok got minus, cause didn't describe my example, so more examples:):
I use regular expression and test method:
var isInteger = /^[0-9]\d*$/;
isInteger.test(123); //true
isInteger.test('123'); // true
isInteger.test('sdf'); //false
isInteger.test('123sdf'); //false
// If u want to avoid string value:
typeof testVal !== 'string' && isInteger.test(testValue);
Upvotes: 1
Reputation: 5622
Use the === operator (strict equality) as below,
if (data === parseInt(data, 10))
alert("data is integer")
else
alert("data is not an integer")
Upvotes: 393
Reputation: 4779
Number.isInteger()
seems to be the way to go.
MDN has also provided the following polyfill for browsers not supporting Number.isInteger()
, mainly all versions of IE.
Number.isInteger = Number.isInteger || function(value) {
return typeof value === "number" &&
isFinite(value) &&
Math.floor(value) === value;
};
Upvotes: 169
Reputation: 401
var x = 1.5;
if(!isNaN(x)){
console.log('Number');
if(x % 1 == 0){
console.log('Integer');
}
}else {
console.log('not a number');
}
Upvotes: 3
Reputation: 71
The simplest and cleanest pre-ECMAScript-6 solution (which is also sufficiently robust to return false even if a non-numeric value such as a string or null is passed to the function) would be the following:
function isInteger(x) { return (x^0) === x; }
The following solution would also work, although not as elegant as the one above:
function isInteger(x) { return Math.round(x) === x; }
Note that Math.ceil() or Math.floor() could be used equally well (instead of Math.round()) in the above implementation.
Or alternatively:
function isInteger(x) { return (typeof x === 'number') && (x % 1 === 0); }
One fairly common incorrect solution is the following:
function isInteger(x) { return parseInt(x, 10) === x; }
While this parseInt-based approach will work well for many values of x, once x becomes quite large, it will fail to work properly. The problem is that parseInt() coerces its first parameter to a string before parsing digits. Therefore, once the number becomes sufficiently large, its string representation will be presented in exponential form (e.g., 1e+21). Accordingly, parseInt() will then try to parse 1e+21, but will stop parsing when it reaches the e character and will therefore return a value of 1. Observe:
> String(1000000000000000000000)
'1e+21'
> parseInt(1000000000000000000000, 10)
1
> parseInt(1000000000000000000000, 10) === 1000000000000000000000
false
Upvotes: 7
Reputation: 4796
You could tryNumber.isInteger(Number(value))
if value
might be an integer in string form e.g var value = "23"
and you want this to evaluate to true
. Avoid trying Number.isInteger(parseInt(value))
because this won't always return the correct value. e.g if var value = "23abc"
and you use the parseInt
implementation, it would still return true.
But if you want strictly integer values then probably Number.isInteger(value)
should do the trick.
Upvotes: 3
Reputation: 47
Number.isInteger()
is the best way if your browser support it, if not, I think there are so many ways to go:
function isInt1(value){
return (value^0) === value
}
or:
function isInt2(value){
return (typeof value === 'number') && (value % 1 === 0);
}
or:
function isInt3(value){
return parseInt(value, 10) === value;
}
or:
function isInt4(value){
return Math.round(value) === value;
}
now we can test the results:
var value = 1
isInt1(value) // return true
isInt2(value) // return true
isInt3(value) // return true
isInt4(value) // return true
var value = 1.1
isInt1(value) // return false
isInt2(value) // return false
isInt3(value) // return false
isInt4(value) // return false
var value = 1000000000000000000
isInt1(value) // return false
isInt2(value) // return true
isInt3(value) // return false
isInt4(value) // return true
var value = undefined
isInt1(value) // return false
isInt2(value) // return false
isInt3(value) // return false
isInt4(value) // return false
var value = '1' //number as string
isInt1(value) // return false
isInt2(value) // return false
isInt3(value) // return false
isInt4(value) // return false
So, all of these methods are works, but when the number is very big, parseInt and ^ operator would not works well.
Upvotes: 3
Reputation: 19718
Lodash https://lodash.com/docs#isInteger (since 4.0.0) has function to check if variable is an integer:
_.isInteger(3);
// → true
_.isInteger(Number.MIN_VALUE);
// → false
_.isInteger(Infinity);
// → false
_.isInteger('3');
// → false
Upvotes: 0
Reputation: 48396
Besides, Number.isInteger()
. Maybe Number.isSafeInteger()
is another option here by using the ES6-specified.
To polyfill Number.isSafeInteger(..)
in pre-ES6 browsers:
Number.isSafeInteger = Number.isSafeInteger || function(num) {
return typeof num === "number" &&
isFinite(num) &&
Math.floor(num) === num &&
Math.abs( num ) <= Number.MAX_SAFE_INTEGER;
};
Upvotes: 2
Reputation: 48753
ECMA-262 6.0 (ES6) standard include Number.isInteger function.
In order to add support for old browser I highly recommend using strong and community supported solution from:
https://github.com/paulmillr/es6-shim
which is pure ES6 JS polyfills library.
Note that this lib require es5-shim, just follow README.md.
Upvotes: 5
Reputation: 11
For positive integer values without separators:
return ( data !== '' && data === data.replace(/\D/, '') );
Tests 1. if not empty and 2. if value is equal to the result of a replace of a non-digit char in its value.
Upvotes: 1
Reputation: 11
This will solve one more scenario (121.), a dot at end
function isInt(value) {
var ind = value.indexOf(".");
if (ind > -1) { return false; }
if (isNaN(value)) {
return false;
}
var x = parseFloat(value);
return (x | 0) === x;
}
Upvotes: 1
Reputation: 4571
function isInteger(argument) { return argument == ~~argument; }
Usage:
isInteger(1); // true<br>
isInteger(0.1); // false<br>
isInteger("1"); // true<br>
isInteger("0.1"); // false<br>
or:
function isInteger(argument) { return argument == argument + 0 && argument == ~~argument; }
Usage:
isInteger(1); // true<br>
isInteger(0.1); // false<br>
isInteger("1"); // false<br>
isInteger("0.1"); // false<br>
Upvotes: 1
Reputation: 22428
You can use regexp to do this:
function isInt(data){
if(typeof(data)=='number'){
var patt=/^[0-9e+]+$/;
data=data+"";
data=data.match(patt);
if(data==null){return false;}
else {return true;}}
else{return false;}
}
It will return false
if data isn't an integer, true
otherwise.
Upvotes: -2