Ismail Gunes
Ismail Gunes

Reputation: 558

Checking digits with decimal separator defined

I have a function as below (I am not to much familiar with linq)

    public static bool IsNumber(string s, char dec_sep)
    {
        return s.Length > 0 && s.All(c => Char.IsDigit(c));
    }

If the number contains a decimal separator I get false as a fact. I want to check if my defined decimal separator is in the number Is it possible modify this function for this purpose ? Or should I write another function ?

For being more clear

If in the string there ise decimal separator such as 72.5 it returns false (my defined separator is "." ). It already returns true if the string is 72 or 725. I want this function returns TRUE even with a decimal separator.

Upvotes: 1

Views: 560

Answers (2)

Akshay Katoch
Akshay Katoch

Reputation: 75

If you are a fan of regex you can also try "^\\d+\\.??(\\d*)?$"

Upvotes: 1

Zohar Peled
Zohar Peled

Reputation: 82474

I would advise against writing your own "IsNumber" function.

The framework already has TryParse of all built in value types - so I suggest using either float.TryParse, double.TryParse or decimal.TryParse depending on the size and precision of number you're expecting (23, 64 or 128 bit).

Writing your own "IsNumber" function is bound to have some difficulties, especially if you're going to attempt to parse user input (or any input you can't control, for that matter) - because like many other "simple" things, numbers are nothing but simple.

First, Numbers can have a thousands separator - in English, 1,234.56 is a valid number.
Second, string representations of numbers are culture dependent - 1,234.56 is invalid in some cultures - where the decimal separator is a comma and the thousands separator is a dot - so you would actually write it like this: 1.234,56
Note that these are two different ways to write the same number - one thousand, two hundred thirty-four and fifty-six hundredths.
Even worst, you can write the same number in different numerals altogether - Thai, Arabic, Chinese or Hebrew - all of these languages (and probably many more languages) have their own symbols for numbers - and I'm not sure that IsDigit covers them all (though it's probably culture dependent also).


Having said all that, your current function will throw a NullReferenceException if the string is null - the very least you should do is either throw an ArgumentNullException or simply return false if the string is null.
Further more, there are going to be valid use-case where you want to know if a char exists exactly zero or once in a string - one way to do it is by subtracting IndexOf from LastIndexOf and check that the result of this subtruction is 0. To combine that with your current method, you also want to change the condition in the All method to allow the char to either be a digit or your designated decimal separator.

If you really have to write your own method, here's how I would start it:

public static bool IsNumber(string s, char dec_sep)
{
    return !string.IsNullOrEmpty(s)
        && s.LastIndexOf(dec_sep) - s.IndexOf(dec_sep) == 0 
        && s.All(c => Char.IsDigit(c) || c == dec_sep);
} 

The first condition will return false if the string is null or empty,
the second one will return false only if the string contains dec_sep more than once,
and the third will return false only if the string contains any char that is neither a digit nor dec_sep.

Upvotes: 2

Related Questions