How to check if a JavaScript number is a real, valid number?
Solution 1
If you want to check whether a number is a real number, you should also check whether it's finite:
function isNumber(n){
return typeof n == 'number' && !isNaN(n) && isFinite(n);
}
Another method (explanation below):
function isNumber(n){
return typeof n == 'number' && !isNaN(n - n);
}
Update: Two expressions to validate a real number
Since JavaScript numbers are representing real numbers, the substraction operand on the same number should produce the zero value (additive identity). Numbers out of range should (and will) be invalid, NaN
.
1 - 1 = 0 // OK
Infinity - Infinity = NaN // Expected
NaN - NaN = NaN // Expected
NaN - Infinity = NaN
Solution 2
JS numbers can be among the following values:
- Finite numbers
-
+Infinity
and-Infinity
NaN
Then there also non-number values which are coercible to numbers, e.g. number objects. You might want to consider them numerical.
If you only want to test finite numbers, simply use Number.isFinite
:
Number.isFinite(value)
var isNumber = Number.isFinite;
assert('isNumber(1)', true);
assert('isNumber(1.1)', true);
assert('isNumber(+0)', true);
assert('isNumber(-0)', true);
assert('isNumber(-1.1)', true);
assert('isNumber(Math.PI)', true);
assert('isNumber(1e300)', true);
assert('isNumber(+Infinity)', false);
assert('isNumber(-Infinity)', false);
assert('isNumber(NaN)', false);
assert('isNumber(null)', false);
assert('isNumber(undefined)', false);
assert('isNumber(true)', false);
assert('isNumber(false)', false);
assert('isNumber("123")', false);
assert('isNumber("foo")', false);
assert('isNumber(new Number(1))', false);
assert('isNumber([])', false);
assert('isNumber({})', false);
assert('isNumber(function(){})', false);
function assert(code, expected) {
var result = eval(code);
console.log('Test ' + (result===expected ? 'pass' : 'FAIL') + ': ', code, ' -> ', result);
}
If you want to include infinities, check the type and exclude NaN
:
typeof value === "number" && !Number.isNaN(value)
function isNumber(value) {
return typeof value === "number" && !Number.isNaN(value);
}
assert('isNumber(1)', true);
assert('isNumber(1.1)', true);
assert('isNumber(+0)', true);
assert('isNumber(-0)', true);
assert('isNumber(-1.1)', true);
assert('isNumber(Math.PI)', true);
assert('isNumber(1e300)', true);
assert('isNumber(+Infinity)', true);
assert('isNumber(-Infinity)', true);
assert('isNumber(NaN)', false);
assert('isNumber(null)', false);
assert('isNumber(undefined)', false);
assert('isNumber(true)', false);
assert('isNumber(false)', false);
assert('isNumber("123")', false);
assert('isNumber("foo")', false);
assert('isNumber(new Number(1))', false);
assert('isNumber([])', false);
assert('isNumber({})', false);
assert('isNumber(function(){})', false);
function assert(code, expected) {
var result = eval(code);
console.log('Test ' + (result===expected ? 'pass' : 'FAIL') + ': ', code, ' -> ', result);
}
If you want to consider number objects as numbers, you can unwrap them using
value = Number.valueOf.call(value); // throws if value was not a number object
function isNumber(value) {
try { value = Number.prototype.valueOf.call(value); } catch(err) { }
return Number.isFinite(value);
}
assert('isNumber(1)', true);
assert('isNumber(1.1)', true);
assert('isNumber(+0)', true);
assert('isNumber(-0)', true);
assert('isNumber(-1.1)', true);
assert('isNumber(Math.PI)', true);
assert('isNumber(1e300)', true);
assert('isNumber(+Infinity)', false);
assert('isNumber(-Infinity)', false);
assert('isNumber(NaN)', false);
assert('isNumber(null)', false);
assert('isNumber(undefined)', false);
assert('isNumber(true)', false);
assert('isNumber(false)', false);
assert('isNumber("123")', false);
assert('isNumber("foo")', false);
assert('isNumber(new Number(1))', true);
assert('isNumber([])', false);
assert('isNumber({})', false);
assert('isNumber(function(){})', false);
function assert(code, expected) {
var result = eval(code);
console.log('Test ' + (result===expected ? 'pass' : 'FAIL') + ': ', code, ' -> ', result);
}
If you want to include arbitrary values coercible to numbers, you can use the unary +
to coerce.
value = +value; // throws if value was not number-coercible
There is also the isNaN
function (not to be confused with Number.isNaN
), which will first coerce and then compare with NaN
. But be aware whitespace strings and null
are coerced to +0
, not NaN
. So you might be interested in Validate decimal numbers in JavaScript - IsNumeric()
Related videos on Youtube
Rob W
I like to develop useful software, web apps and browser extensions. Reply faster by getting real-time Desktop notifications for your SE inbox (for Firefox / Chrome) or install the user script / Chrome extension to “View Vote totals” without 1000 rep.
Updated on June 04, 2022Comments
-
Rob W almost 2 years
MY code is:
function isNumber(n){ return typeof n == 'number' && !isNaN(n); } window.onload=function(){ var a=0,b=1,c=2.2,d=-3,e=-4.4,f=10/3; var shouldBeTrue=[a,b,c,d,e,f]; var aa="0",bb="1",cc="2.2",dd="-3",ee="-4.4",ff="10/3"; var shouldBeFalse=[aa,bb,cc,dd,ee,ff]; var aaa,bbb=true,ccc=false,ddd=document.getElementsByTagName('html'); var alsoTheseBeFalse=[aaa,bbb,ccc,ddd,""," ",,null,NaN]; for(var i=0;i<shouldBeTrue.length;i++) if(isNumber(shouldBeTrue[i]) != true) alert("x"); for(i=0;i<shouldBeFalse.length;i++) if(isNumber(shouldBeFalse[i]) != false) alert("x"); for(i=0;i<alsoTheseBeFalse.length;i++) if(isNumber(alsoTheseBeFalse[i]) != false) alert("x"); }
What else should I check against to ensure my function is 101% perfect in all ways? (also, if you know a better function please tell me)
-
frenchie over 12 yearswhich function are you looking to make perfect? You could start by giving your variables more meaningful names...
-
Rob WSide note, inside your test cases, you're using
!= false
. This is not needed, because yourisNumber
function always return a boolean (true
orfalse
). Withinif ( ... )
, an expressions is always treathed as a boolean.if (isNumber(a) != false)
is equivalent toif (isNumber(a) == true)
is equivalent toif (isNumber(a))
.
-
-
Admin over 12 yearsWell, your code is larger and do 1 more operation. The only way I would use it is if you to tell me a way that my current function would fail and yours not
-
Rob W over 12 years@TuxedoKnightChess Input the following value:
Infinity
. It passes the first two tests, while it's not a useful real number:isNumber(Infinity)
returns true for your current function. -
Admin over 12 yearswhat would be the result for
var n=2E30;
? -
RightSaidFred over 12 years@TuxedoKnightChess: There's a real easy way to find out.
-
Rob W over 12 years@TuxedoKnightChess I've updated the answer with another method. Two tests instead of one.
-
Admin over 12 yearsJust to double check, both of your functions do exactly the same thing?
-
Rob W over 12 years@TuxedoKnightChess The methods slightly differ, but the results are exactely equal.
-
RightSaidFred over 12 years@down-voter: Give a reason. Please tell me how
new Number(123)
will pass theisNumber
test in the question. -
Rob W over 12 yearsI did not downvote, but your code only shows an example of something that breaks the code, without proposing a solution. The OP did not ask how to break the function, but how to improve the function.
-
Dmitri Zaitsev almost 8 yearsReal numbers are finite per definition.
-
João Pimentel Ferreira about 5 yearshow come this function is not embedded in Javascript, is for me a big huge surprise. Dealing with true numbers (integers or float) is a basic task of any programming language
-
João Pimentel Ferreira about 5 yearsbtw, can I give 10 of my points to you. I feel like +1 is just not enough
-
João Pimentel Ferreira about 5 yearsyour
isNumber(n)
function is perfect . No variable coercion and all that typical mess of javascript, nostring
, no"1"
, notrue
, no"true"
, noNaN
, nonull
, no1/0
.n
must simply be a finite valid number (integer or float). And0
returns true as it should be. -
João Pimentel Ferreira about 5 years@DmitriZaitsev what the OP meant is not real in the mathematical sense, but merely a true number (natural, integer, rational or real numbers, in the mathematical sense). Javascript is a mess dealing with types and type coercion and believe me that this function is very, very important.