0

I'm checking for integer values in node.js using IsNaN function. Unexpectedly, this function validates the strings like 1E267146, 1E656716 , 914E6583 to be numbers, as these strings are exponential values. Any way to work around this? In actual scenario i wont get any exponential values.

Prem
  • 5,685
  • 15
  • 52
  • 95
  • Those numbers are too big to be managed correctly by JS, so they are evaluated as Infinite. No, there is no way to get them correctly, you have to write them "manually"(but I don't suggest to do something like this) – Niccolò Campolungo Sep 28 '13 at 09:13
  • 1
    see [this answer](http://stackoverflow.com/questions/18082/validate-numbers-in-javascript-isnumeric/1830844#1830844) – GuiDocs Sep 28 '13 at 09:33
  • What is your definition of an Integer? for example `1E267146` is a big integer written in scientific notation. javascript otherwise only handles integers in the range MIN_INTEGER = -9007199254740992, MAX_INTEGER = 9007199254740991 – Xotic750 Sep 28 '13 at 10:01
  • 1
    Another question is whether the value should be number-typed or if string values such as `"0"` should be considered integers, too. – Ingo Bürk Sep 28 '13 at 10:07

4 Answers4

3

ECMA6 defines Number.isInteger as follows:

Javascript

function isInteger(nVal) {
    return typeof nVal === "number" && isFinite(nVal) && nVal > -9007199254740992 && nVal < 9007199254740992 && Math.floor(nVal) === nVal;
}

but this will also accept scientific notation

console.log(isInteger(1e6));
console.log(isInteger(+"1e6"));

jsfiddle

You need to be clear as to what your definitions/expectations are.

My guess is that you may want something like this, if you are testing strings and have no limits on the max or min integer.

Javascript

function isStringNumericalInteger(testValue) {
    return typeof testValue === "string" && /^[\-+]?[1-9]{1}\d+$|^[\-+]?0$/.test(testValue);
}

console.log(isStringNumericalInteger("9007199254740991"));
console.log(isStringNumericalInteger("-123216848516878975616587987846516879844651654847"));
console.log(isStringNumericalInteger("1.1"));
console.log(isStringNumericalInteger("-1.1"));
console.log(isStringNumericalInteger("1e10"));
console.log(isStringNumericalInteger("010"));
console.log(isStringNumericalInteger("0x9"));
console.log(isStringNumericalInteger(""));
console.log(isStringNumericalInteger(" "));
console.log(isStringNumericalInteger());
console.log(isStringNumericalInteger(null));
console.log(isStringNumericalInteger([]));
console.log(isStringNumericalInteger({}));

Output

true
true
false
false
false
false
false
false
false
false
false
false
false 

jsfiddle

If you want to bound the range to what javascript can represent numerically as an integer then you will need to add a test for && +testValue > -9007199254740992 && +testValue < 9007199254740992

If you don't like using RegExs, you can also accomplish this with a parser. Something like this:

Javascript

function isCharacterDigit(testCharacter) {
    var charCode = testCharacter.charCodeAt(0);

    return charCode >= 48 && testCharacter <= 57;
}

function isStringNumericalInteger(testValue) {
    var start = 0,
        character,
        index,
        length;

    if (typeof testValue !== "string") {
        return false;
    }

    character = testValue.charAt(start);
    if (character === "+" || character === "-") {
        start += 1;
        character = testValue.charAt(start);
    }

    start += 1;
    length = testValue.length;
    if ((length > start && character === "0") || !isCharacterDigit(character)) {
        return false;
    }

    for (index = start; index < length; index += 1) {
        if (!isCharacterDigit(testValue.charAt(index))) {
            return false;
        }
    }

    return true;
}

jsfiddle

Xotic750
  • 22,914
  • 8
  • 57
  • 79
-2

I would use something like below code to validate number input. First I parse the given value to float and then check isNaN().

var isNumber = function (obj) {
    return !isNaN(parseFloat(obj)) && isFinite(obj);
};
Gaurang Jadia
  • 1,516
  • 15
  • 18
-2

I think this is what you need in your case (i hate regex because this is not very good for the performance but..)

http://jsbin.com/EQiBada/1/

var NMAX = Math.pow(2, 53);
function isNumeric(n) {
  n = n < 0 ? n * -1 : n;
  var r = /^\d+$/.test(n);
  if (r === true)
  {
    return parseInt(n, 10) >= (NMAX * -1) + 1 && parseInt(n, 10) <= NMAX;
  }
  return false;
}

Minified

var NMAX = Math.pow(2, 53);
function isNumericMin(n) {
  n = n < 0 ? n * -1 : n;
  return /^\d+$/.test(n) === true ? parseInt(n, 10) >= (NMAX * -1) + 1 && parseInt(n, 10) <= NMAX : false;
}
Paul Rad
  • 4,820
  • 1
  • 22
  • 23
  • `true` for `10000000000000000000000000000000`, which is clearly too large for an integer. – Prinzhorn Sep 28 '13 at 10:09
  • Damn, i fix this case – Paul Rad Sep 28 '13 at 10:10
  • I meant `'10000000000000000000000000000000'` (string). Also `parseInt` will never return anything that is larger than `MAX_VALUE` or smaller than `MIN_VALUE`. Also you're accepting string in hex or octet notation, because you didn't pass `10` as second parameter to `parseInt` – Prinzhorn Sep 28 '13 at 10:19
-2

var i = '1E267146' if(isNaN(i) || !isFinite(i) !! i=="") { // do stuff } else { // do stuff }

Prem
  • 5,685
  • 15
  • 52
  • 95