IsNumeric in C#, WHY NOT? - The Bumpy Blog
in

dotnet.org.za

South African .NET Developer Portal

The Bumpy Blog

Bumpy's Bedside Story

IsNumeric in C#, WHY NOT?

This is something that has bothered me for a long while now.  Why doesn't C# have a IsNumeric(string num) function like VB.NET?
I have used every kind of IsNumeric code you van think of...  This is what I started with.

public bool IsNumeric(string s)
{
      try
      {
            Int32.Parse(s);
      }
      catch
      {
            
return false;
      }
      return true;
}

But we all no the unspoken rule, NEVER use try, catch for functionality...  So I tried this.

internal static bool IsNumeric(string numberString)
{
      char [] ca = numberString.ToCharArray();
      for (int i = 0; i < ca.Length;i++)
      { 
            if (ca[i] > 57 || ca[i] < 48)
            return false;
      }
      return true;
}

Then I found char.IsNumber:  (Why do they have a char.IsNumber, but no string.IsNumeric???)

internal static bool IsNumeric(string numberString)
{
      char [] ca = numberString.ToCharArray();
      for (int i = 0; i < ca.Length;i++)
      { 
            if (!char.IsNumber(ca[i]))
            return false;
      }
      return true;
}

With the help of some friend (Thanks Dawid), I finally got this.  What do you think?

public static bool IsNumeric(object Expression)
{
      bool isNum;
      double retNum;
      isNum = Double.TryParse(Convert.ToString(Expression), System.Globalization.NumberStyles.Any,System.Globalization.NumberFormatInfo.InvariantInfo, out retNum );
      return isNum;
}

Luckily, as far as I heard, Whidbey has a IsNumeric build in.

Comments

 

Ernst Kuschke said:

This is quite a popular request! It seems you might be disappointed, though - C# whidbey doesn't have it.
Instead you can do a

int.TryParse(string s, out int result)

which is quite nice, as you get the result back if the parse can be done successfully ;)
July 6, 2004 10:26 AM
 

Thea Burger said:

Deon, I am using exactly the same one you have there :)
July 6, 2004 1:50 PM
 

senkwe said:

I believe this was discussed (among other things) with Anders Hejl......berg during a whiteboard session at TechEd (USA). Apparently, a video of that session will be up on MSDNTV at some point.
July 7, 2004 10:42 AM
 

MaLio said:

we had a discussion on the forum at sadeveleoper about htis very topic ...

http://www.sadeveloper.net/Forum/ShowPost.aspx?PostID=9668
July 7, 2004 11:48 AM
 

Sujal Raju said:

Good Job Guys.
August 4, 2004 4:02 PM
 

Sammy said:

Because numbers are for idiots ;-)
October 20, 2004 10:24 AM
 

I would do said:

This might be a little bit faster

internal static bool IsNumeric(string numberString)
{
foreach (char c in numberString)
{
if (!char.IsNumber(c))
return false;
}
return true;
}
April 6, 2005 12:08 AM
 

Larry Smith said:

This method (as posted) just solved my problems. Yippeeee.

public static bool IsNumeric(object Expression)
{
bool isNum;
double retNum;
isNum = Double.TryParse(Convert.ToString(Expression), System.Globalization.NumberStyles.Any,System.Globalization.NumberFormatInfo.InvariantInfo, out retNum );
return isNum;
}
May 4, 2005 9:48 PM
 

Darkman said:

Try this ...
static bool IsNumeric(string input)
{
bool flag = true;

//Valid user input
string pattern = @"^[0-9]*$";
Regex validate = new Regex(pattern);

//Check the user input format
if(!validate.IsMatch(input))
{
flag = false;
}

return flag;
}
June 23, 2005 7:01 PM
 

jeff said:

Even easier:

static bool IsNumeric(string inputString)
{
return Regex.IsMatch(inputString, "^[0-9]+$");
}
August 4, 2005 5:58 AM
 

jayson knight said:

I posted an article about this as well (as it relates to performance):

http://jaysonknight.com/blog/articles/1756.aspx
September 1, 2005 11:04 PM
 

keef67 said:

I haven't taken the time to check all of these great examples out, but I did notice with the second example from the bottom (in the article) that the function did not return true or false if an empty string was submitted.
(this is for an asp.net page I am testing)

I added a simple if statement using string.Empty that would return false if the string was empty.

internal static bool IsNumeric(string numberString)
{


if (numberString==string.Empty) return false;

     char [] ca = numberString.ToCharArray();
     for (int i = 0; i < ca.Length;i++)
     {
           if (!char.IsNumber(caIdea [I]))
           return false;
     }
     return true;
}
May 10, 2006 10:47 PM
 

Dutch said:

Another option ..

I'm not knowledgeable enough to know if there are perfomance issues associated with referencing a component.

(1)  Create a class in visual basic such as ..

Public Class VB

    Public Shared Function IsNumeric(ByVal s As String) As Boolean

         Return Microsoft.VisualBasic.IsNumeric(s)

    End Function

End Class

(2)  Reference your class in C# and use it like ...

   if( VB.IsNumeric("some string") ) {;}

August 4, 2006 6:29 PM
 

Paul Russell said:

Why create a class? Just reference the function directly from the Microsoft.VisualBasic library, i.e.

using Microsoft.VisualBasic;

...

if (Information.IsNumeric(myString)) ...

November 13, 2006 1:52 PM
 

mluckham said:

Brilliant - using VB functions in a C# program, why not!  I am going to try that one.

Many of the functions presented here forget that decimal points, commas, and minus signs are part of numeric fields also!  And those that try converting to integers forgot about decimal numbers I guess.

Here is my offering:

/// <summary>

/// IsANumber() - returns TRUE if the input string contains only number characters.

///                      Empty strings are considered non-numeric.

/// </summary>

/// <param name="text"></param>

/// <returns></returns>

private bool IsANumber(string text)

{

bool isnumber = false;

if (text.Length > 0)

{

char[] legalchars = "0123456789,.-".ToCharArray();

isnumber = true; // innocent until proven guilty

// look for the first non-numeric character in the input string

for (int i = 0; i < text.Length; i++)

{

// if the character is NOT in the list of valid characters, it is not a number

if (text.LastIndexOfAny(legalchars,i,1) < 0)

{

isnumber = false;

break;

}

}

}

return isnumber;

}

November 29, 2006 6:14 AM
 

Fateme said:

Hello

you can test this one.

public static bool IsNumeric(string theValue)

{

  Regex _isNumber = new Regex(@"^\d+$");

  Match m = _isNumber.Match(theValue);

  return m.Success;

}

May 6, 2007 7:38 AM
 

Adaptable Objects said:

You stupid stupid people...

---

using System.Text.RegularExpressions;

public bool IsNumeric(string str)

{

   return Regex.IsMatch(str, "^[0-9]+$");

}

June 26, 2007 11:35 PM
 

gsb said:

TO: Adaptable Objects

try to parse str = "01" with regex.

July 3, 2007 2:42 PM
 

joe cool said:

For all those VB fans (And I am one of them). The VB IsNumeric interally actually does a try catch so is no better than C#'s  Int32.Parse(s);

July 3, 2007 5:53 PM
 

Tha Bolistaff said:

Thanks guys... This was quite helpful...

I guess I might need to bookmark this site, as I'm still a newbie in C# and I might need useful thoughts of other C# programmers...

July 10, 2007 11:34 AM
 

Zenjbela Tariq said:

Thanks Sir:

Very well,u doing very well job.Keep it up!

July 15, 2007 1:20 PM
 

AC said:

easy....

using System.Text.RegularExpressions;

           MessageBox.Show(Regex.IsMatch("Hi","^[0-9]").ToString());   //false

           MessageBox.Show(Regex.IsMatch("1", "^[0-9]").ToString());  //true

           MessageBox.Show(Regex.IsMatch("123", "^[0-9]").ToString());  //true

           MessageBox.Show(Regex.IsMatch("01", "^[0-9]").ToString());  //true

           MessageBox.Show(Regex.IsMatch("0", "^[0-9]").ToString());   //true

           MessageBox.Show(Regex.IsMatch("-1", "^[0-9]").ToString());   //false

by further tailoring the expression a tiny bit, you can allow or disallow leading zeros, negatives, decimals, etc...

just do a google on how to use Regex.

July 26, 2007 5:05 AM
 

Andreas Blixt said:

It's funny how there's not a single solution in the comments that will give the correct result for all of the following:

123..4 (Not a number)

12Hello (Not a number)

-12.34 (Number)

0123 (Number; octal, not decimal)

Here's a regular expression that only matches valid decimal numbers:

^-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?$

You would use it like so:

public static bool IsNumeric(string value) {

return Regex.IsMatch(value, @"^-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?$");

}

It was made for non-formatted numbers and will not match thousand separators (besides, some countries use space as separators and commas as the decimal point, etc.)

One could argue that it should also match decimal numbers with zero omitted (.123), but that would require a more complex regular expression (or if you make sure the string is not empty or equal to "-" and add a ? after the first group, that will work too).

It returns false for numbers like 0123 (this is a number, but an octal/base-8 one.)

What's even more funny is that the originally proposed solution is just as good (except it reads 0123 as decimal 123, but on the other hand it reads .123 as 0.123):

decimal result;

if (Decimal.TryParse(value, out result))

{

// It's a number and you now have its value in the result variable.

}

August 7, 2007 4:07 PM
 

Chris Tagg said:

Any ideas for an IsDate()?

October 25, 2007 3:45 PM
 

Txomin said:

This one matches thousand separators

private bool isNumeric(string stringToCheck)

{

System.Text.RegularExpressions.Regex _isNumber =

new System.Text.RegularExpressions.Regex

(@"(^[-+]?\d+(,?\d*)*\.?\d*([Ee][-+]\d*)?$)|(^[-+]?\d?(,?\d*)*\.\d+([Ee][-+]\d*)?$)");

return _isNumber.Match(stringToCheck).Success;

}

January 28, 2008 10:37 AM
 

sambo said:

private bool IsNumeric(string inputString)

{

    return Regex.IsMatch(inputString, "^[0-9]+$");

}

Good practice and performance, my think.

March 18, 2008 1:32 PM
 

Dave said:

Using the VB namespace is the best way to go. Just look at how many code samples were presented with errors.

March 20, 2008 8:58 PM
 

senthil said:

protected bool CheckforNumber()

   {

       string no = "";

       try

       {

           Int64 no1 = Convert.ToInt64(no);

           return true;

       }

       catch (FormatException FE)

       {

           return false;

       }

   }

April 25, 2008 6:57 AM
 

senthilkumar said:

protected bool CheckforNumber(string strNumber)

   {  

       try

       {

           Int64 no1 = Convert.ToInt64(strNumber);

           return true;

       }

       catch (FormatException FE)

       {

           return false;

       }

   }

April 25, 2008 7:00 AM
 

Ken Palmer said:

TryParse() is a viable alternative to Try/Catch. When a conversion fails it returns False rather than an exception.

The code I'm using below was adapted from Microsoft and Scott Hanselman's blog:

support.microsoft.com/.../329488

www.hanselman.com/.../ExploringIsNumericForC.aspx

public static bool IsNumeric(object expression)

{

   if (expression == null) { return false; }

   double retNum; // Collects out parameter of TryParse().  If conversion fails the out parameter is zero.

   // TryParse() returns True when conversion passes and False when conversion fails.  It doesn't generate an exception.

   return Double.TryParse(Convert.ToString(expression), System.Globalization.NumberStyles.Any, System.Globalization.NumberFormatInfo.InvariantInfo, out retNum);

}

May 28, 2008 2:15 PM
 

Wilby Jackson said:

This also works as a replacement:

public bool isNumeric(string str)

   {

       bool isNumber = false;

       foreach (char c in str)

       {

           if (char.IsNumber(c))

           {

               isNumber = true;

           }

       }

       return isNumber;

   }

June 3, 2008 7:59 PM
 

James McConville said:

I Like this method... (apologies if its already on the coversation, i didn't read all the posts)

...

int output;

if (int.TryParse("123", out output))

           {

               return true;

           }

           else

           {

               return false;

           }

June 19, 2008 12:36 PM
 

zamkinos said:

thanks a lot.

July 16, 2008 9:08 AM
 

Deon van Staden said:

Looking at this old blog, I decided to add something else.  I found this very nice link and thought I should share it.

sadeveloper.net/.../8887.aspx

The part I really agree with it w.r.t. RegEx.

Here is a snippet from the post:

   // Define a regular expression for currency values.

     Regex rx = new Regex(@"^-?\d+(\.\d{2})?$");

      // Define some test strings.

     string[] tests = {"-42", "19.99", "0.001", "100 USD"};

     // Check each test string against the regular expression.

     foreach (string test in tests)

     {

         if (rx.IsMatch(test))

         {

             Console.WriteLine("{0} is a currency value.", test);

         }

         else

         {

             Console.WriteLine("{0} is not a currency value.", test);

         }

     }

And then this part also enhances this a lot:

To add negative validation to the beginning, start the regular expression with an optional hyphen.

Immediately after the "start of text" marker (which looks like "^") put in a hyphen and a question mark.  The question mark allows zero or one of the preceding character (a hyphen) but no more.

^-?\d+$  (this is for negative and positive integers)

^-?\d+([\.]{1}\d*)?$ (this is for negative and positive decimals)

Spread the word about Regular Expressions.  I love them.   They become much easier if you use a tool like "Expresso". I have created a regular expression that I use to validate password complexity in javascript on the client browser (more than 6 chars, includes number or capitals or special characters in various combinations - its one long string or about five readable lines when broken apart).

Thanks jamesh.  I think this one wins the competition thus far.  I would like to see what Microsoft is going to come up with when they wake up with IsNumeric?

August 1, 2008 12:14 AM
 

Wilby Jackson said:

Revised to actually check for a number either int or decimal.

public static bool isNumeric(string str)

       {

          //number of decimals in string

          int decCounter = 0;

          //loop through checking each char for a number or dec.

          foreach (char c in str)

          {

              if (!char.IsNumber(c) && !c.Equals('.'))

              {  

                  return false;

              }

              else if (c.Equals('.') && decCounter >= 1)

              {

                  return false;

              }

              else if (c.Equals('.'))

              {

                 decCounter += 1;

              }

          }

           //before returning true make sure there is not a decimal at the end of the string

          if (!(decCounter > 1))

          {

              return true;

          }

          else

          {

              return false;

          }

       }

August 6, 2008 5:28 PM
 

Ultimate Solutions from IT Expert » isNumeric in c# said:

Pingback from  Ultimate Solutions from IT Expert &raquo; isNumeric in c#

August 8, 2008 10:05 AM
 

Praveen said:

In .Net 2005 the best form of IsNumeric is as follows.

public static bool IsNumeric(string argument)

{

           float result ;

           return float.TryParse(argument,out result);

}

August 18, 2008 7:34 AM
 

kam said:

Hi all,

i'm having problem in custom paging using web application..there is an error saying "Input string was not in a correct format."

Here is my coding..

protected void NavigationLink_Click ( Object sender, CommandEventArgs e )

{

switch ( e.CommandName )

{

case "First":

_currentPageNumber = 1;

break;

case "Last":

_currentPageNumber = Int32.Parse(TotalPages.Text);

break;

case "Next":

_currentPageNumber = Int32.Parse(CurrentPage.Text) + 1;

break;

case "Prev":

_currentPageNumber = Int32.Parse(CurrentPage.Text) - 1;

break;

}

BindData();

}

public void BindData()

{

OdbcConnection myconn;

myconn= new OdbcConnection ("DSN=myodbc2;SERVER=localhost;DATABASE=misdb;UID=root;PORT=3306");

OdbcCommand cmd2 = new OdbcCommand("Select * from registration", myconn);

cmd2.CommandType=CommandType.StoredProcedure;

cmd2.Parameters.Add(new OdbcParameter ("@CurrentPage",OdbcType.Numeric,10)).Value=_currentPageNumber;

cmd2.Parameters.Add(new OdbcParameter("@PageSize",OdbcType.Numeric,10)).Value=DataGrid.PageSize;

cmd2.Parameters.Add(new OdbcParameter("@TotalRecords",OdbcType.Numeric,10)).Direction =ParameterDirection.Output;

try

{

myconn.Open();

DataGrid.DataSource=cmd2.ExecuteReader();

DataGrid.DataBind();

}

finally

{

myconn.Close();

}

CurrentPage.Text=_currentPageNumber.ToString();

Double _totalPages = 1;

if ( !Page.IsPostBack )

{

Int32 _totalRecords = (Int32) cmd2.Parameters["@TotalRecords"].Value;

totalPages = _totalRecords / DataGrid.PageSize;

TotalPages.Text =(System.Math.Ceiling(_totalPages)).ToString();

}

else

{

_totalPages = Double.Parse(TotalPages.Text);

}

if ( _currentPageNumber == 1 )

{

PreviousPage.Enabled = false;

if ( _totalPages > 1 )

{

NextPage.Enabled = true;

}

else

{

NextPage.Enabled = false;

}

}

else

{

PreviousPage.Enabled = true;

if ( _currentPageNumber == _totalPages )

{

NextPage.Enabled = false;

}

else

{

NextPage.Enabled = true;

}

}

}

Pls help me..

November 17, 2008 5:46 AM
 

Ayuda con valores numericos | hilpers said:

Pingback from  Ayuda con valores numericos | hilpers

January 20, 2009 9:37 PM
 

Ctype from string to double not behaving as expected. | keyongtech said:

Pingback from  Ctype from string to double not behaving as expected. | keyongtech

January 22, 2009 3:07 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add
Powered by Community Server (Commercial Edition), by Telligent Systems