# Validate that a string is a positive integer

## Validate that a string is a positive integer

I would like the simplest fail-safe test to check that a string in JavaScript is a positive integer.
isNaN(str) returns true for all sorts of non-integer values and parseInt(str) is returning integers for float strings, like “2.5”. And I don’t want to have to use some jQuery plugin either.

### Solution 1:

• Based on parsing

• Regular expression

Note that in both cases, I’ve interpreted “positive integer” to include `0`, even though `0` is not positive. I include notes if you want to disallow `0`.

### Based on Parsing

If you want it to be a normalized decimal integer string over a reasonable range of values, you can do this:

``````function isNormalInteger(str) {
var n = Math.floor(Number(str));
return n !== Infinity && String(n) === str && n >= 0;
}
``````

Live testbed:

``````function isNormalInteger(str) {
var n = Math.floor(Number(str));
return String(n) === str && n >= 0;
}
function gid(id) {
return document.getElementById(id);
}
function test(str, expect) {
console.log(str + ": " + (isNormalInteger(str) ? "Yes" : "No"));
}
"click",
function() {
test(gid("text").value);
},
false
);
test("1");
test("1.23");
test("1234567890123");
test("1234567890123.1");``````
``````<label>
String:
<input id="text" type="text" value="">
<label>
<input id="btn" type="button" value="Check">``````

If you want to disallow `0`, just change `>= 0` to `> 0`.

How that works:

1. `Number(str)`: Convert `str` to a number; the number may well have a fractional portion, or may be `NaN`.

2. `Math.floor`: Truncate the number (chops off any fractional portion).

3. `String(...)`: Converts the result back into a normal decimal string. For really big numbers, this will go to scientific notation, which may break this approach. (I don’t quite know where the split is, the details are in the spec, but for whole numbers I believe it’s at the point you’ve exceeded 21 digits [by which time the number has become very imprecise, as IEEE-754 double-precision numbers only have roughtly 15 digits of precision..)

4. `... === str`: Compares that to the original string.

5. `n >= 0`: Check that it’s positive.

Note that this fails for the input `"+1"`, any input in scientific notation that doesn’t turn back into the same scientific notation at the `String(...)` stage, and for any value that the kind of number JavaScript uses (IEEE-754 double-precision binary floating point) can’t accurately represent which parses as closer to a different value than the given one (which includes many integers over 9,007,199,254,740,992; for instance, `1234567890123456789` will fail). The former is an easy fix, the latter two not so much.

### Regular Expression

The other approach is to test the characters of the string via a regular expression, if your goal is to just allow (say) an optional `+` followed by either `0` or a string in normal decimal format:

``````function isNormalInteger(str) {
return /^\+?(0|[1-9]\d*)\$/.test(str);
}
``````

Live testbed:

``````function isNormalInteger(str) {
return /^\+?(0|[1-9]\d*)\$/.test(str);
}
function gid(id) {
return document.getElementById(id);
}
function test(str, expect) {
console.log(str + ": " + (isNormalInteger(str) ? "Yes" : "No"));
}
"click",
function() {
test(gid("text").value);
},
false
);
test("1");
test("1.23");
test("1234567890123");
test("1234567890123.1");``````
``````<label>
String:
<input id="text" type="text" value="">
<label>
<input id="btn" type="button" value="Check">``````

How that works:

1. `^`: Match start of string

2. `\+?`: Allow a single, optional `+` (remove this if you don’t want to)

3. `(?:...|...)`: Allow one of these two options (without creating a capture group):

1. `(0|...)`: Allow `0` on its own…

2. `(...|[1-9]\d*)`: …or a number starting with something other than `0` and followed by any number of decimal digits.

4. `\$`: Match end of string.

If you want to disallow `0` (because it’s not positive), the regular expression becomes just `/^\+?[1-9]\d*\$/` (e.g., we can lose the alternation that we needed to allow `0`).

If you want to allow leading zeroes (0123, 00524), then just replace the alternation `(?:0|[1-9]\d*)` with `\d+`

``````function isNormalInteger(str) {
return /^\+?\d+\$/.test(str);
}
``````

Note for when you convert that to a number: On modern engines it would probably be fine to use `+str` or `Number(str)` to do it, but older ones might extend those in a non-standard (but formerly-allowed) way that says a leading zero means octal (base 8), e.g “010” => 8. Once you’ve validated the number, you can safely use `parseInt(str, 10)` to ensure that it’s parsed as decimal (base 10). `parseInt` would ignore garbage at the end of the string, but we’ve ensured there isn’t any with the regex.

# Solution 1

If we consider a JavaScript integer to be a value of maximum `4294967295` (i.e. `Math.pow(2,32)-1`), then the following short solution will perfectly work:

``````function isPositiveInteger(n) {
return n >>> 0 === parseFloat(n);
}
``````

DESCRIPTION:

1. Zero-fill right shift operator does three important things:
• truncates decimal part
• `123.45 >>> 0 === 123`
• does the shift for negative numbers
• `-1 >>> 0 === 4294967295`
• “works” in range of `MAX_INT`
• `1e10 >>> 0 === 1410065408`
• `1e7 >>> 0 === 10000000`
2. `parseFloat` does correct parsing of string numbers (setting `NaN` for non numeric strings)

TESTS:

``````"0"                     : true
"23"                    : true
"-10"                   : false
"10.30"                 : false
"-40.1"                 : false
"string"                : false
"1234567890"            : true
"129000098131766699.1"  : false
"-1e7"                  : false
"1e7"                   : true
"1e10"                  : false
"1edf"                  : false
" "                     : false
""                      : false
``````

# Solution 2

Another way is good for all numeric values which are valid up to `Number.MAX_VALUE`, i.e. to about `1.7976931348623157e+308`:

``````function isPositiveInteger(n) {
return 0 === n % (!isNaN(parseFloat(n)) && 0 <= ~~n);
}
``````

DESCRIPTION:

1. `!isNaN(parseFloat(n))` is used to filter pure string values, e.g. `""`, `" "`, `"string"`;
2. `0 <= ~~n` filters negative and large non-integer values, e.g. `"-40.1"`, `"129000098131766699"`;
3. `(!isNaN(parseFloat(n)) && 0 <= ~~n)` returns `true` if value is both numeric and positive;
4. `0 === n % (...)` checks if value is non-float — here `(...)` (see 3) is evaluated as `0` in case of `false`, and as `1` in case of `true`.

TESTS:

``````"0"                     : true
"23"                    : true
"-10"                   : false
"10.30"                 : false
"-40.1"                 : false
"string"                : false
"1234567890"            : true
"129000098131766699.1"  : false
"-1e10"                 : false
"1e10"                  : true
"1edf"                  : false
" "                     : false
""                      : false
``````

The previous version:

``````function isPositiveInteger(n) {
return n == "0" || ((n | 0) > 0 && n % 1 == 0);
}
``````

### Solution 3:

Looks like a regular expression is the way to go:

``````var isInt = /^\+?\d+\$/.test('the string');
``````

### Solution 4:

The modern solution that works in node and across over 90% of all browsers (except IE and Opera Mini) is to use Number.isInteger followed by a simple positive check.

``````Number.isInteger(x) && x > 0
``````

This was finalized in ECMAScript 2015.

``````function isPositiveInteger(x) {
return Number.isInteger(x) && x > 0
}
``````

The Polyfil is:

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

If you need to support input that might be in string or number form then you can use this function I wrote a large test suite against after all the existing answers (2/1/2018) failed on some form of input.

``````function isPositiveInteger(v) {
var i;
return v && (i = parseInt(v)) && i > 0 && (i === v || ''+i === v);
}
``````

### Solution 5:

This is almost a duplicate question fo this one:

Validate decimal numbers in JavaScript – IsNumeric()

``````function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
``````

so, a positive integer would be:

``````function isPositiveInteger(n) {
var floatN = parseFloat(n);
return !isNaN(floatN) && isFinite(n) && floatN > 0
&& floatN % 1 == 0;
}
``````

### Solution 6:

``````return ((parseInt(str, 10).toString() == str) && str.indexOf('-') === -1);
``````

won’t work if you give a string like ‘0001’ though