Only decimal number validation in javascript

The accepted answer failed your test #7 and I guess it's because you changed your mind. So this is a response to the accepted answer, with which I had issues.

During some projects I have needed to validate some data and be as certain as possible that it is a javascript numerical value that can be used in mathematical operations.

jQuery, and some other javascript libraries already include such a function, usually called isNumeric. There is also a post on stackoverflow that has been widely accepted as the answer, the same general routine that the afore mentioned libraries are using.

function isNumber[n] {
  return !isNaN[parseFloat[n]] && isFinite[n];
}

First, the code above would return true if the argument was an array of length 1, and that single element was of a type deemed as numeric by the above logic. In my opinion, if it's an array then its not numeric.

To alleviate this problem, I added a check to discount arrays from the logic

function isNumber[n] {
  return Object.prototype.toString.call[n] !== '[object Array]' &&!isNaN[parseFloat[n]] && isFinite[n];
}

Of course, you could also use Array.isArray, jquery $.isArray or prototype Object.isArray instead of Object.prototype.toString.call[n] !== '[object Array]'

My second issue was that Negative Hexadecimal integer literal strings ["-0xA" -> -10] were not being counted as numeric. However, Positive Hexadecimal integer literal strings ["0xA" -> 10] were treated as numeric. I needed both to be valid numeric.

I then modified the logic to take this into account.

function isNumber[n] {
  return Object.prototype.toString.call[n] !== '[object Array]' &&!isNaN[parseFloat[n]] && isFinite[n.toString[].replace[/^-/, '']];
}

If you are worried about the creation of the regex each time the function is called then you could rewrite it within a closure, something like this

var isNumber = [function [] {
  var rx = /^-/;

  return function [n] {
      return Object.prototype.toString.call[n] !== '[object Array]' &&!isNaN[parseFloat[n]] && isFinite[n.toString[].replace[rx, '']];
  };
}[]];

I then took CMSs +30 test cases and cloned the testing on jsfiddle added my extra test cases and my above described solution.

It may not replace the widely accepted/used answer but if this is more of what you are expecting as results from your isNumeric function then hopefully this will be of some help.

EDIT: As pointed out by Bergi, there are other possible objects that could be considered numeric and it would be better to whitelist than blacklist. With this in mind I would add to the criteria.

I want my isNumeric function to consider only Numbers or Strings

With this in mind, it would be better to use

function isNumber[n] {
  return [Object.prototype.toString.call[n] === '[object Number]' || Object.prototype.toString.call[n] === '[object String]'] &&!isNaN[parseFloat[n]] && isFinite[n.toString[].replace[/^-/, '']];
}

Test the solutions

var testHelper = function[] {

  var testSuite = function[] {
    test["Integer Literals", function[] {
      ok[isNumber["-10"], "Negative integer string"];
      ok[isNumber["0"], "Zero string"];
      ok[isNumber["5"], "Positive integer string"];
      ok[isNumber[-16], "Negative integer number"];
      ok[isNumber[0], "Zero integer number"];
      ok[isNumber[32], "Positive integer number"];
      ok[isNumber["040"], "Octal integer literal string"];
      ok[isNumber[0144], "Octal integer literal"];
      ok[isNumber["-040"], "Negative Octal integer literal string"];
      ok[isNumber[-0144], "Negative Octal integer literal"];
      ok[isNumber["0xFF"], "Hexadecimal integer literal string"];
      ok[isNumber[0xFFF], "Hexadecimal integer literal"];
      ok[isNumber["-0xFF"], "Negative Hexadecimal integer literal string"];
      ok[isNumber[-0xFFF], "Negative Hexadecimal integer literal"];
    }];

    test["Foating-Point Literals", function[] {
      ok[isNumber["-1.6"], "Negative floating point string"];
      ok[isNumber["4.536"], "Positive floating point string"];
      ok[isNumber[-2.6], "Negative floating point number"];
      ok[isNumber[3.1415], "Positive floating point number"];
      ok[isNumber[8e5], "Exponential notation"];
      ok[isNumber["123e-2"], "Exponential notation string"];
    }];

    test["Non-Numeric values", function[] {
      equals[isNumber[""], false, "Empty string"];
      equals[isNumber["        "], false, "Whitespace characters string"];
      equals[isNumber["\t\t"], false, "Tab characters string"];
      equals[isNumber["abcdefghijklm1234567890"], false, "Alphanumeric character string"];
      equals[isNumber["xabcdefx"], false, "Non-numeric character string"];
      equals[isNumber[true], false, "Boolean true literal"];
      equals[isNumber[false], false, "Boolean false literal"];
      equals[isNumber["bcfed5.2"], false, "Number with preceding non-numeric characters"];
      equals[isNumber["7.2acdgs"], false, "Number with trailling non-numeric characters"];
      equals[isNumber[undefined], false, "Undefined value"];
      equals[isNumber[null], false, "Null value"];
      equals[isNumber[NaN], false, "NaN value"];
      equals[isNumber[Infinity], false, "Infinity primitive"];
      equals[isNumber[Number.POSITIVE_INFINITY], false, "Positive Infinity"];
      equals[isNumber[Number.NEGATIVE_INFINITY], false, "Negative Infinity"];
      equals[isNumber[new Date[2009, 1, 1]], false, "Date object"];
      equals[isNumber[new Object[]], false, "Empty object"];
      equals[isNumber[function[] {}], false, "Instance of a function"];
      equals[isNumber[[]], false, "Empty Array"];
      equals[isNumber[["-10"]], false, "Array Negative integer string"];
      equals[isNumber[["0"]], false, "Array Zero string"];
      equals[isNumber[["5"]], false, "Array Positive integer string"];
      equals[isNumber[[-16]], false, "Array Negative integer number"];
      equals[isNumber[[0]], false, "Array Zero integer number"];
      equals[isNumber[[32]], false, "Array Positive integer number"];
      equals[isNumber[["040"]], false, "Array Octal integer literal string"];
      equals[isNumber[[0144]], false, "Array Octal integer literal"];
      equals[isNumber[["-040"]], false, "Array Negative Octal integer literal string"];
      equals[isNumber[[-0144]], false, "Array Negative Octal integer literal"];
      equals[isNumber[["0xFF"]], false, "Array Hexadecimal integer literal string"];
      equals[isNumber[[0xFFF]], false, "Array Hexadecimal integer literal"];
      equals[isNumber[["-0xFF"]], false, "Array Negative Hexadecimal integer literal string"];
      equals[isNumber[[-0xFFF]], false, "Array Negative Hexadecimal integer literal"];
      equals[isNumber[[1, 2]], false, "Array with more than 1 Positive interger number"];
      equals[isNumber[[-1, -2]], false, "Array with more than 1 Negative interger number"];
    }];
  }

  var functionsToTest = [

    function[n] {
      return !isNaN[parseFloat[n]] && isFinite[n];
    },

    function[n] {
      return !isNaN[n] && !isNaN[parseFloat[n]];
    },

    function[n] {
      return !isNaN[[n]];
    },

    function[n] {
      return !isNaN[parseFloat[n]];
    },

    function[n] {
      return typeof[n] != "boolean" && !isNaN[n];
    },

    function[n] {
      return parseFloat[n] === Number[n];
    },

    function[n] {
      return parseInt[n] === Number[n];
    },

    function[n] {
      return !isNaN[Number[String[n]]];
    },

    function[n] {
      return !isNaN[+['' + n]];
    },

    function[n] {
      return [+n] == n;
    },

    function[n] {
      return n && /^-?\d+[\.\d+]?$/.test[n + ''];
    },

    function[n] {
      return isFinite[Number[String[n]]];
    },

    function[n] {
      return isFinite[String[n]];
    },

    function[n] {
      return !isNaN[n] && !isNaN[parseFloat[n]] && isFinite[n];
    },

    function[n] {
      return parseFloat[n] == n;
    },

    function[n] {
      return [n - 0] == n && n.length > 0;
    },

    function[n] {
      return typeof n === 'number' && isFinite[n];
    },

    function[n] {
      return !Array.isArray[n] && !isNaN[parseFloat[n]] && isFinite[n.toString[].replace[/^-/, '']];
    }

  ];


  // Examines the functionsToTest array, extracts the return statement of each function
  // and fills the toTest select element.
  var fillToTestSelect = function[] {
    for [var i = 0; i < functionsToTest.length; i++] {
      var f = functionsToTest[i].toString[];
      var option = /[\s\S]*return [[\s\S]*];/.exec[f][1];
      $["#toTest"].append['' + [i + 1] + '. ' + option + ''];
    }
  }

  var performTest = function[functionNumber] {
    reset[]; // Reset previous test
    $["#tests"].html[""]; //Clean test results
    isNumber = functionsToTest[functionNumber]; // Override the isNumber global function with the one to test
    testSuite[]; // Run the test

    // Get test results
    var totalFail = 0;
    var totalPass = 0;
    $["b.fail"].each[function[] {
      totalFail += Number[$[this].html[]];
    }];
    $["b.pass"].each[function[] {
      totalPass += Number[$[this].html[]];
    }];
    $["#testresult"].html[totalFail + " of " + [totalFail + totalPass] + " test failed."];

    $["#banner"].attr["class", ""].addClass[totalFail > 0 ? "fail" : "pass"];
  }

  return {
    performTest: performTest,
    fillToTestSelect: fillToTestSelect,
    testSuite: testSuite
  };
}[];


$[document].ready[function[] {
  testHelper.fillToTestSelect[];
  testHelper.performTest[0];

  $["#toTest"].change[function[] {
    testHelper.performTest[$[this].children[":selected"].val[]];
  }];
}];



isNumber Test Cases

Mozilla/5.0 [X11; Linux x86_64] AppleWebKit/537.11 [KHTML, like Gecko] Chrome/23.0.1271.95 Safari/537.11

Select function to test:
  1. Integer Literals [0, 10, 10]
    1. Negative integer string
    2. Zero string
    3. Positive integer string
    4. Negative integer number
    5. Zero integer number
    6. Positive integer number
    7. Octal integer literal string
    8. Octal integer literal
    9. Hexadecimal integer literal string
    10. Hexadecimal integer literal
  2. Foating-Point Literals [0, 6, 6]
    1. Negative floating point string
    2. Positive floating point string
    3. Negative floating point number
    4. Positive floating point number
    5. Exponential notation
    6. Exponential notation string
  3. Non-Numeric values [0, 18, 18]
    1. Empty string: false
    2. Whitespace characters string: false
    3. Tab characters string: false
    4. Alphanumeric character string: false
    5. Non-numeric character string: false
    6. Boolean true literal: false
    7. Boolean false literal: false
    8. Number with preceding non-numeric characters: false
    9. Number with trailling non-numeric characters: false
    10. Undefined value: false
    11. Null value: false
    12. NaN value: false
    13. Infinity primitive: false
    14. Positive Infinity: false
    15. Negative Infinity: false
    16. Date object: false
    17. Empty object: false
    18. Instance of a function: false
This page contains tests for a set of isNumber functions. To see them, take a look at the source.

Tests completed in 0 milliseconds.
0 tests of 0 failed.

How do you validate decimal numbers?

A decimal number can start with dot also, like . 34, -. 12, so dot also can be at the first position. But a decimal number should have only one dot.

How do you check if a number has a decimal in JavaScript?

function number_test[n] { var result = [n - Math. floor[n]] !== 0; if [result] return 'Number has a decimal place.

How do I limit the number of decimals in JavaScript?

To limit decimal places in JavaScript, use the toFixed[] method by specifying the number of decimal places. This method: Rounds the number. Converts it into a string.

How do you validate decimal values in regex?

A better regex would be /^\d*\.?\ d+$/ which would force a digit after a decimal point..
^ - Beginning of the line;.
\d* - 0 or more digits;.
\.? - An optional dot [escaped, because in regex, . is a special character];.
\d* - 0 or more digits [the decimal part];.
$ - End of the line..

Chủ Đề