I'm trying to parse user entered text into a float so that I can perform some wicked awesome math on the result. The result being the numberA variable at the end there. This is how I'm parsing the string into a float:
numberAString = GUI.TextField(new Rect(25, 100, 100, 25), numberAString.ToString());
bool ParsableCheckA = float.TryParse(numberAString, out numberA);
I eventually multiply numberA by another float later. I'm handling text that won't parse with a simple error message later. Couple things that bug me:
1) Why do I need to use numberAString in the TryParse parameters instead of its value? Why can't I just drop GUI.Textfield etc. into that slot? Why do I need to break this up over two lines of code?
2) I get a warning that I never use ParsableCheckA (which is true). But without it, I can't seem to use that Tryparse helper, no? Is there a way to eliminate the need for that bool? Thanks.
TryParse() Metod and its usage is rather straighforward, as shown in the following example:
double _dblOriginal;
_dblOriginal=3.141592;
string _str;
_str = _dblOriginal.ToString();
double _dblParsed;
bool _parseOK= TryParse(_str, out dblParsed);
More details in: http://msdn.microsoft.com/en-us/library/system.double.tryparse%28v=vs.110%29.aspx
Note: make sure that in your example the string numberAString you pass to the TryParse() method contains a valid number.
Also, FYI: TryParse() method has some performance benefits compare to just Parse() method because it does not throw an exception if parsing fail (instead you just check the bool result value).
Hope this will help. Regards,
(1) numberAString (see GUI.TextField) is a string, so you can use it directly in the TryParse() call.
(2) TryParse() is designed to return a boolean value so you can check for errors and take action. However, you aren't required to assign the return value. You can us it like this and simply accept the default value (0.0) assigned to the out parameter:
float.TryParse(numberAString, out numberA);
In this case you would not be able to distinguish between an invalid entry and a value that parsed correctly as zero.
I personally create an extension method to make my number parsing easier. If performance is critical, then this may not be a good idea (because for valid floats, you'll be essentially converting them twice). But I don't the effect on performance is much more than negligible.
public static class NumberExtensions
{
//Test if the text represents a valid float.
public static bool IsFloat(this string text)
{
float dummy = 0;
return Float.TryParse(text, out dummy);
}
//Convert the text to a float. Will throw exception if it's not a valid float.
public static float ToFloat(this string text)
{
float number = Float.Parse(text);
return number;
}
}
Usage...
string text = "123";
if(text.IsFloat())
{
//text must be a valid float
float myfloat = text.ToFloat();
}
else
{
//text isn't a valid float
}
You have to remember to test if it's a float by calling the IsFloat() extension method, but it's much easier for me to think of it conceptually like this rather than using out variables, which some think is a bad idea.
Related
I've been struggling to get my head around a natural way of using TryParse because I keep expecting it to work the other way around (i.e. to return the parsed value and emit the boolean for whether the input parsed).
For example, if we take a basic implementation of Parse, the return value is the parsed input:
int parsedValue = int.Parse(input);
This works fine until it gets a value that it can't parse, at which point it entirely reasonably throws an exception. To me, the option then is either to wrap the parse in something like a try-catch block to handle the exception and a condition to set a default, or just to use TryParse to let C# do all that for me. Except that's not how TryParse works. The above example now looks like this:
bool parseSucceeded = int.TryParse(input, out int parsedValue);
To get it to assign in the same way as Parse, I wrap it in a ternary conditional with parsedValue and a default value (in this case, 0) as the true and false results respectively:
int parsedValue = int.TryParse(input, out parsedValue) ? parsedValue : 0;
But I still feel like I'm missing the point with TryParse if I'm just working around its default behaviour like this. I've read Tim Schmelter's excellent answer in which he shows its internal workings, from which I can suppose that it returns the boolean because it's easier internally than passing it out at all the various places that it currently returns. But I'm not sure about this, and I'm not satisfied that I understand its intent correctly. I also tried reading the documentation for it, but the remarks don't clear up my confusion (I don't think they even make its differences with Parse clear enough, like the change in return type).
Am I understanding it correctly, or am I missing something?
Sure, it could have been implemented as
int TryParse(string input, out bool succeeded)
{
}
But as mentioned in a comment, the common use case for the function is:
string input;
int parsedValue;
if(int.TryParse(input, out parsedValue))
{
// use parsedValue here
}
With the signature you propose, that code would now be:
string input;
bool succeeded;
int parsedValue = int.TryParse(input, out succeeded)
if(succeeded)
{
// use parsedValue here
}
So there's more code for no functional benefit. Also, with your ternary operator, if the parse fails you just set a value of zero, which is unnecessary since the default value of it is 0. You could just do:
int parsedValue;
int.TryParse(input, out parsedValue);
If the parse fails, parsedValue will have a value of 0; (I also question if/how you distinguish between an actual result of 0 and a failed parse, but I'm sure you have a reason).
So there's no technical reason why the signature is the way it is; it's a design decision that is appropriate for the most common use cases.
Of course, now with tuples in C# 7 you could have:
(int parsedValue, bool succeeded) = int.TryParse(input);
but again there's little functional benefit and prevents you from inlining the TryParse in an if statement.
Because logically you would want to check that the TryParse succeeded before trying to use the out value.
So this is more concise:
if (int.TryParse(input, out int parsedValue)}
{
// Do something with parsedValue
}
Than this:
int parsedValue = int.TryParse(input, out bool succeded);
if (succeeded)
{
// Do something with parsedValue
}
I think, a large part of your confusion stems from the method name isn't named exactly right:
int parsedValue = int.Parse("42");
This makes perfect sense, give me the integeger representation of a string.
int parsedValue = int.TryParse(input);
This makes sense as an extension of the concept: Input might be '42' or 'Oswald', but if it's a number I want that number.
In 2020, I think a better name would be CanParse(string input, out int result).
It better matches style guides and naming conventions, where returning a bool should be named with Is, Has, or Can.
It better matches how we use TryParse 99% of the time:
if (int.CanParse(input, out int result))
{
return result * 10;
}
But where I feel the current name makes sense, is the problem I assume it was trying to solve: To get rid of the following boilerplate code:
int result;
bool hasValidNumber = false;
try
{
result = int.Parse(input);
hasValidNumber = true;
}
catch
{
// swallow this exception
}
if (hasValidNumber)
{
// do things with result
}
else
{
// use a default or other logic
}
How can I convert a textbox into a float only when the textbox has value?
I currently have this float test = (float)Convert.ToDouble(textbox.Text);
It works fine, But gives an error if the textbox is empty.
I think that better solution will be:
float test = float.NaN;
if(float.TryParse(textbox.Text, out test ))
{
// your code here
}
There are many ways to do this, but generally you test with an if. For example:
float test;
if (!string.IsNullOrWhiteSpace(textbox.text))
test = (float)Convert.ToDouble(textbox.Text);
It really is as simple as including this in an If statement.
float test;
if(textbox.Text.Length > 0) //Or (textbox.Text != "")
test = (float)Convert.ToDouble(textbox.Text);
As an additional suggestion, multiple layers of validation is always a good thing. If you have something like a submit button, you should test against required fields being empty on the UI BEFORE it gets to the point where it is converted.
A very common way is to use double.TryParse to do the conversion. This way you can handle empty and invalid values with a single statement.
bool success = double.TryParse(textbox.Text, out value);
Don't forget to check success and handle a possible failure.
I'm trying to convert the string "127.0" to an integer.
I tried this function:
int getInt(string numStr)
{
int result;
int.TryParse(numStr, out result);
return result;
}
But when I call it as int x = getInt("127.0"); then int.TryParse() sets result to 0.
When I rewrite the function like this:
int getInt(string numStr)
{
result=Convert.ToInt32(numStr);
return result;
}
the same getInt() call throws this exception:
Input string was not in a correct format.
The issue here is that "127.0" is not an integer, it's a floating point number. You will need to parse it using one of the other floating point types (i.e. double, float, Decimal, etc.).
You may want to consider either stripping off any values after the decimal point and attempting to parse it, or parsing it as another type and casting it as an integer :
int result = (int)Convert.ToDouble("1.270");
You could also take advantage of the Math.Truncate() function which would give you the integer portion of your value :
int result = (int)Math.Truncate(Convert.ToDouble("127.0"));
First off, you need to check the return value of int.TryParse(). If it returns false, then the string could not be converted.
Had you done that, you would see it returned false because 127.0 does not describe an integer value (it describes a floating point value).
Note that decimal.TryParse() would succeed here. You need to figure out if you need an integer or floating point value, and reject data that is incorrect.
An int cannot contain a decimal point; that makes it either a double, a float, or a decimal. Try to pull the number minus anything from the decimal point over to the right, like this:
int getInt(string numStr)
{
int result;
string[] splitup;
string number;
if (numstr.Contains('.'))
{
splitup = numstr.Split('.');
number = splitup[0];
int.TryParse(number, out result);
}
else
{
int.TryParse(numstr, out result);
}
return result;
}
Rion Williams is absolutely correct, IMHO.
Along with the fact that what you are parsing is not an integer, I'd personally use the TryParse method. Many of the .NET types have it, and it's quite a bit "safer" (it won't throw exceptions) than just parsing a string.
Example:
string stringValue = "127.0";
int intValue;
if(Int32.TryParse(stringValue, out intValue))
{
// return value
}
// handle the failure
If you don't like that, I'd wrap it in a try-catch...
So I am new to C# and I am having difficulty understanding out. As opposed to just returning something from a function
using System;
class ReturnTest
{
static double CalculateArea()
{
double r=5;
double area = r * r * Math.PI;
return area;
}
static void Main()
{
double output = CalculateArea();
Console.WriteLine("The area is {0:0.00}", output);
}
}
compare to this
using System;
class ReturnTest
{
static void CalculateArea(out double r)
{
r=5;
r= r * r * Math.PI;
}
static void Main()
{
double radius;
CalculateArea(out radius);
Console.WriteLine("The area is {0:0.00}",radius );
Console.ReadLine();
}
}
The first one is how I would generally do it. Is there a reason why I may want to use out instead of just a return statement? I understand that ref allows for 2 way communication, and that I generally shouldn't use ref unless the function is doing something with the variable I am sending it.
However is there a difference between out and return statements, like shown above? Syntax-wise is there a reason to favor one or the other?
A good use of out instead of return for the result is the Try pattern that you can see in certain APIs, for example Int32.TryParse(...). In this pattern, the return value is used to signal success or failure of the operation (as opposed to an exception), and the out parameter is used to return the actual result.
One of the advantages with respect to Int32.Parse is speed, since exceptions are avoided. Some benchmarks have been presented in this other question: Parsing Performance (If, TryParse, Try-Catch)
The out keyword is mostly used when you want to return more than one value from a method, without having to wrap the values in an object.
An example is the Int32.TryParse method, which has both a return value (a boolean representing the success of the attempt), and an out parameter that gets the value if the parsing was successful.
The method could return an object that contained both the boolean and the integer, but that would need for the object to be created on the heap, reducing the performance of the method.
Only time I tend to use out is when I need multiple things returned from a single method. Out lets you avoid wrapping multiple objects into a class for return. Check out the example at the Microsoft Out page.
You can have multiple out parameters, so if you need to return multiple values, it's a bit easier than creating a special class for your return values.
When one variable is concerned out and return are OK. But what if you wanted to return more than 1 values? Out helps in that.
static void CalculateArea(out double r, out double Foo)
{
//Can return 2 values in terms of out variables.
}
static double CalculateArea(double r)
{
// Will return only one value.
}
I have a Double which could have a value from around 0.000001 to 1,000,000,000.000
I wish to format this number as a string but conditionally depending on its size. So if it's very small I want to format it with something like:
String.Format("{0:.000000000}", number);
if it's not that small, say 0.001 then I want to use something like
String.Format("{0:.00000}", number);
and if it's over, say 1,000 then format it as:
String.Format("{0:.0}", number);
Is there a clever way to construct this format string based on the size of the value I'm going to format?
Use Math.Log10 of the absolute value of the double to figure out how many 0's you need either left (if positive) or right (if negative) of the decimal place. Choose the format string based on this value. You'll need handle zero values separately.
string s;
double epislon = 0.0000001; // or however near zero you want to consider as zero
if (Math.Abs(value) < epislon) {
int digits = Math.Log10( Math.Abs( value ));
// if (digits >= 0) ++digits; // if you care about the exact number
if (digits < -5) {
s = string.Format( "{0:0.000000000}", value );
}
else if (digits < 0) {
s = string.Format( "{0:0.00000})", value );
}
else {
s = string.Format( "{0:#,###,###,##0.000}", value );
}
}
else {
s = "0";
}
Or construct it dynamically based on the number of digits.
Use the # character for optional positions in the string:
string.Format("{0:#,###,##0.000}", number);
I don't think you can control the number of decimal places like that as the precision of the double will likely mess things up.
To encapsulate the logic of deciding how many decimal places to output you could look at creating a custom formatter.
The first two String.Format in your question can be solved by automatically removing trailing zeros:
String.Format("{0:#,##0.########}", number);
And the last one you could solve by calling Math.Round(number,1) for values over 1000 and then use the same String.Format.
Something like:
String.Format("{0:#,##0.########}", number<1000 ? number : Math.Round(number,1));
Following up on OwenP's (and by "extension" tvanfosson):
If it's common enough, and you're on C# 3.0, I'd turn it into an extension method on the double:
class MyExtensions
{
public static string ToFormmatedString(this double d)
{
// Take d and implement tvanfosson's code
}
}
Now anywhere you have a double you can do:
double d = 1.005343;
string d_formatted = d.ToFormattedString();
If it were me, I'd write a custom wrapper class and put tvanfosson's code into its ToString method. That way you could still work with the double value, but you'd get the right string representation in just about all cases. It'd look something like this:
class FormattedDouble
{
public double Value { get; set; }
protected overrides void ToString()
{
// tvanfosson's code to produce the right string
}
}
Maybe it might be better to make it a struct, but I doubt it would make a big difference. You could use the class like this:
var myDouble = new FormattedDouble();
myDouble.Value = Math.Pi;
Console.WriteLine(myDouble);