I have value 0.075445054945055 for a variable corrected count and have the following function. Basically I need a function which would see if the value is a numeric and greater than 0. My current function only works for integers and not for values like 0.075 etc.
The field correctedCount comes from a file when its parsed.
var correctedCount
int num;
bool isNumeric = int.TryParse(correctedCount, out num);
if (isNumeric)
{
}
You can use decimal.TryParse or double.TryParse
You could treat it as a double like so:
double num;
if (double.TryParse(correctedCount, out num))
{
// it's at least a number, now verify it's > 0
return num > 0;
}
else
{
return false;
}
Edit: this works because numbers without decimal parts (e.g., "4") are still valid doubles, as well as "0.075"
Related
I have read the second line in a text file which contains 2.75 and I am trying to get it to do something if it meets certain criteria. I'm sure I have done this before and has a simple answer but I can't seen to figure it out.
string SecondLine;
using (var reader = new StreamReader(SPFile2))
{
reader.ReadLine();
SecondLine = reader.ReadLine();
}
int NewValue;
NewValue = Convert.ToInt32(SecondLine);
if ((NewValue >= 2) && (NewValue <= 2.99))
{
// Do Something
}
if ((NewValue >= 3) && (NewValue <= 3.99))
{
// Do something else
}
What have I missed out?
You are converting a decimal number to an Int32 that does not hold decimals. This will turn the number in NewValue into 2 as it truncates towards zero. You need to store the variable in a double, float or decimal whichever is best for your requirements.
See the following example that uses a double and Parse:
double newValue = Double.Parse(secondLine);
Note that if you are unsure if the value will be a double you should use Double.TryParse
double newValue;
bool result = Double.TryParse(secondLine, out newValue);
if (!result) //Parse failed
Note that if the parsing fails it may be down to your culture settings i.e. a ',' for the decimal separator not a '.'. However there is an overload for Parse and TryParse that allows you to pass culture information in.
You are trying to parse a string that represents a double into a integer
that will cause a
System.IFormatException
{"Input string was not in a correct
format."}{"Input string was not in a correct format."}
if you know it is a number with decimal part then do:
var newValue = Convert.ToDouble(secondLine);
if you know it is an integer then try:
var newValue = Convert.ToInt32(secondLine);
I am seeing lots of these in a method in our code:
int num1 = 0;
if (Char.IsDigit(myStr[2]) && Int32.TryParse(myStr[2].ToString(), out num1) == false)
{
valid = false;
}
So are they just making sure the third character us a digit?
The code shown parses the 3rd character only - checking if it is digit, then parsing the string representation of that single character. Instead, just use the numeric value of that character:
if(myStr[2] >= '0' && myStr[2] <= '9') {
num1 = (int)myStr[2] - (int)'0';
} else {
valid = false
}
You can safely skip the IsDigit() check as it's redundant.
TryParse() will fail if it's not a digit.
As it has been pointed out by others, Char.IsDigit() is quicker. If your code is performance sensitive the check makes sense.
If you leave the IsDigit check in place, then you can reduce TryParse to Int32.Parse() as at that point the parsing won't fail.
It looks like the code that you have is doing this for efficiency. Whoever coded this, knows the structure of the string in myStr to sometimes have a non-numeric symbol in the third position. That's why he made this optimization to check the third symbol before paying for the conversion of the character array to string which then gets parsed.
Chances are, this optimization is premature: although making a temporary throw-away string is not free, this optimization would make sense only in situations when you do it a lot in a very tight loop. In other words, you do it only if it shows up near the top in your performance profiler's output.
You can optimize this check to avoid if:
int num1 = 0;
valid &= !Char.IsDigit(myStr[2]) || Int32.TryParse(myStr[2].ToString(), out num1);
I don't believe you need the first part (it could also throw an IndexOutOfRangeException).
So I would probably use:
int num1 = 0;
if (myStr.Length > 2 && Int32.TryParse(myStr[2].ToString(), out num1) == false)
{
valid = false;
}
Char.IsDigit Method (String, Int32)
Indicates whether the character at the specified position in a specified string is categorized as a decimal digit.
Link
Int32.TryParse Method
Converts the string representation of a number to its 32-bit signed integer equivalent. A return value indicates whether the operation succeeded. This member is overloaded.
Link
Edit:
First I wrote that you can skip any of the check but now I am writing that you can not because
if (Char.IsDigit(myStr[2]) && Int32.TryParse(myStr[2].ToString(), out num1) == false)
{ }
Char.IsDigit() will return true if myStr[2] contains any of the Unicode characters listed here but Int.TryParse() will not convert any numbers except for 0-9 (not sure about this, as I have not checked all of them) so it will return false which is you are checking...
The condition you are checking can be understood by the following example:
string x = "AS௭s";
int s = 0;
if (Char.IsDigit(x[2]) && int.TryParse(x[2].ToString(), out s) == false)
{
// even if '௭` is Tamil Digit Seven and 'Char.IsDigit()' will return true but
// int.TryParse() will return false because it can not convert it
// so you are setting valid = false when the myStr contains a valid Unicode Character
// for a digit but It can not be converted to integer by TryParse method...
valid = false;
}
#Marc Gravell♦'s answer is the best solution for checking this condition...
Here's how I'd write it:
int num1 = 0;
try
{
num1 = Int32.Parse(myStr[2].ToString());
}
catch (Exception)
{
valid = false;
}
This does the same thing and is a lot easier to read imho, oh & you can log failed parses inside the catch.
Or you can do:
int num1 = 0;
valid = Int32.TryParse(myStr[2].ToString(), out num1);
I'm having a problem getting TryParse to work correctly for me. I have a list of values that I am almost assured are valid (as they come from another component in our system) but I would like to make sure there is proper error handling in place.
Here is an example list of my values:
20.00
20.00
-150.00
And here is the method I originally wrote:
private decimal CalculateValue(IEnumerable<XElement> summaryValues)
{
decimal totalValue = 0;
foreach (XElement xElement in summaryValues)
{
decimal successful;
Decimal.TryParse(xElement.Value, out successful);
if (successful > 0)
totalValue += Decimal.Parse(xElement.Value);
}
return totalValue;
}
The variable 'successful' was returning false for -150.00, so I added NumberStyles:
private decimal CalculateValue(IEnumerable<XElement> summaryValues)
{
decimal totalValue = 0;
foreach (XElement xElement in summaryValues)
{
decimal successful;
Decimal.TryParse(xElement.Value, NumberStyles.AllowLeadingSign, null, out successful);
if (successful > 0)
totalValue += Decimal.Parse(xElement.Value, NumberStyles.AllowLeadingSign);
}
return totalValue;
}
However, now that I have the NumberStyles in there, none of the numbers will parse! I feel good about having IFormatProvider set to null as this is all within our system. Does anyone see what I may be doing wrong?
This is not how you are supposed to use TryParse.
TryParse returns a boolean (true/false), so your code above should be:
private decimal CalculateValue(IEnumerable<XElement> summaryValues)
{
decimal totalValue = 0;
foreach (XElement xElement in summaryValues)
{
decimal valueReturned;
bool successful = Decimal.TryParse(xElement.Value, out valueReturned);
if (successful)
totalValue += valueReturned;
}
return totalValue;
}
or more succinctly,
private decimal CalculateValue(IEnumerable<XElement> summaryValues)
{
decimal totalValue = 0;
foreach (XElement xElement in summaryValues)
{
decimal valueReturned;
if (Decimal.TryParse(xElement.Value, out valueReturned))
totalValue += valueReturned;
}
return totalValue;
}
Others are explaining how to do it right, but not really explaining what you're doing wrong.
Where you're using "successful" above isn't the success value, it's the actual number that is being parsed. So if you're parsing "-150.00" of course successful will be negative. The out value of TryParse is the actual parsed value and the boolean indicating whether the process was successful or not is the returned value. Using what you have to help understand would be something like:
string inputValue = "-150.00";
decimal numericValue;
bool isSucessful = Decimal.TryParse(inputValue , out numericValue);
In this case, isSuccessful will be TRUE, numericValue will be -150. When you're using user-provided values instead of the hardcoded one I used above you'll want to check:
if(isSuccessful)
{
// Do something with numericValue since we know it to be a valid decimal
}
else
{
// Inform User, throw exception, etc... as appropriate, Don't use numericValue because we know it's wrong.
}
The other answers have got the right idea with regard to the proper way to use Decimal.TryParse. However, if I were writing the method in question, I'd use LINQ to work with LINQ-to-XML objects:
private decimal CalculateValue(IEnumerable<XElement> summaryValues)
{
return summaryValues
.Sum(el =>
{
decimal value;
if (Decimal.TryParse(el.Value, out value))
return value;
return 0M;
});
}
This version works the exact same way, but it uses the Enumerable.Sum method to calculate the total. All I have to supply is an inline function that extracts decimal values from an XElement.
Came in from Google. Answer for me was the incoming culture was wrong - specifically in an incoming JSON file.
Use
totalValue += decimal.Parse(xElement.Value, NumberStyles.Any, CultureInfo.InvariantCulture);
or
bool successful = decimal.TryParse(xElement.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out value);
your successful is going to be negative for a negative value being parsed. your if (successful > 0) is what's tripping you up.
If they are almost positively going to be valid values, try using Convert.ToDecimal:
decimal val = Convert.ToDecimal(xElement.Value);
Otherwise, change your logic a bit to be more like:
decimal val;
if (Decimal.TryParse(xElement.Value, out val)){
// valid number
}
I would suggest you to tell XElement which node value it should look for as in:
XElement.Element("nodename").Value
Instead of XElement.Value. at least that is what I would do :)
private int FindNumber(string sPar)
{
// Get the last number
int len = sPar.Length;
string s = sPar.Substring(len-1);
return new (int)Decimal(s);
}
In this I am getting the error ; required . Can any ine help me on this.
Thank You!
Change your code to this:
private int FindNumber(string sPar)
{
int len = sPar.Length;
string s = sPar.Substring(len - 1);
return Convert.ToInt32(s);
}
Or, even shorter:
private int FindNumber(string sPar)
{
return Convert.ToInt32(sPar.Substring(sPar.Length - 1));
}
I'm not 100% what you are trying to do here, but if you want to get 4 as the result from the string "17894" i guess you want to write it like this with minimum number of changes:
private int FindNumber(string sPar) {
// Get the last number
int len = sPar.Length;
string s = sPar.Substring(len-1);
return int.Parse(s);
}
No reason to include a decimal and parse it to an int if you are only taking one char of the string anyway.
Note that this will give an exception if the last char of the string for any reason is not a number.
what is Decimal(s)? If you mean "parse as a decimal, then cast to int":
return (int)decimal.Parse(s);
If it is known to be an integer, just:
return int.Parse(s);
Actually, since you are only interested in the last digit, you could cheat:
private static int FindNumber(string sPar)
{
char c = sPar[sPar.Length - 1];
if (c >= '0' && c <= '9') return (int)(c - '0');
throw new FormatException();
}
Decimal(s) is not a valid call since Decimal is a type. Try Decimal.Parse(s) instead if you are certain that s is a valid decimal, stored as a string. If not, use Decimal.TryParse instead.
Please take into account different Culture related problems also, check out the overload that takes an IFormatProvider (I think, not sure about the exact name)
Do you just want to parse the digit from the last position in the string?
private int FindNumber(string sPar)
{
return int.Parse(sPar.Substring(sPar.Length - 1));
}
Note that this will fail if (a) the string is null, (b) the string is empty, or (c) the last character of the string isn't a digit. You should add some checking to your method if these situations are likely to be a problem.
The last line is completely wrong.
Your code takes the last char of a string(that i presume is always a number) and cast it to an int.
Do the following
try{
return Int32.Parse(s);
}
catch(Exception e)
{
// manage conversion exception here
}
I suppose you want to convert string to decimal as your code is not very clear.
you can use
Decimal d1;
if(Decimal.TryParse(sPar,out d1))
{
return d1
}
else
{
return 0;
}
I need to check if a string contains only digits. How could I achieve this in C#?
string s = "123" → valid
string s = "123.67" → valid
string s = "123F" → invalid
Is there any function like IsNumeric?
double n;
if (Double.TryParse("128337.812738", out n)) {
// ok
}
works assuming the number doesn't overflow a double
for a huge string, try the regexp:
if (Regex.Match(str, #"^[0-9]+(\.[0-9]+)?$")) {
// ok
}
add in scientific notation (e/E) or +/- signs if needed...
Taken from MSDN (How to implement Visual Basic .NET IsNumeric functionality by using Visual C#):
// IsNumeric Function
static bool IsNumeric(object Expression)
{
// Variable to collect the Return value of the TryParse method.
bool isNum;
// Define variable to collect out parameter of the TryParse method. If the conversion fails, the out parameter is zero.
double retNum;
// The TryParse method converts a string in a specified style and culture-specific format to its double-precision floating point number equivalent.
// The TryParse method does not generate an exception if the conversion fails. If the conversion passes, True is returned. If it does not, False is returned.
isNum = Double.TryParse(Convert.ToString(Expression), System.Globalization.NumberStyles.Any, System.Globalization.NumberFormatInfo.InvariantInfo, out retNum );
return isNum;
}
You can use double.TryParse
string value;
double number;
if (Double.TryParse(value, out number))
Console.WriteLine("valid");
else
Console.WriteLine("invalid");
This should work no matter how long the string is:
string s = "12345";
bool iAllNumbers = s.ToCharArray ().All (ch => Char.IsDigit (ch) || ch == '.');
Using regular expressions is the easiest way (but not the quickest):
bool isNumeric = Regex.IsMatch(s,#"^(\+|-)?\d+(\.\d+)?$");
As stated above you can use double.tryParse
If you don't like that (for some reason), you can write your own extension method:
public static class ExtensionMethods
{
public static bool isNumeric (this string str)
{
for (int i = 0; i < str.Length; i++ )
{
if ((str[i] == '.') || (str[i] == ',')) continue; //Decide what is valid, decimal point or decimal coma
if ((str[i] < '0') || (str[i] > '9')) return false;
}
return true;
}
}
Usage:
string mystring = "123456abcd123";
if (mystring.isNumeric()) MessageBox.Show("The input string is a number.");
else MessageBox.Show("The input string is not a number.");
Input :
123456abcd123
123.6
Output:
false
true
I think you can use Regular Expressions, in the Regex class
Regex.IsMatch( yourStr, "\d" )
or something like that off the top of my head.
Or you could use the Parse method int.Parse( ... )
If you are receiving the string as a parameter the more flexible way would be to use regex as described in the other posts.
If you get the input from the user, you can just hook on the KeyDown event and ignore all keys that are not numbers. This way you'll be sure that you have only digits.
This should work:
bool isNum = Integer.TryParse(Str, out Num);