Convert.ToInt32 behaves different when passed string vs float/double literal
var result = Convert.ToInt32(12.4);//returns 12
result = Convert.ToInt32(12.44);//returns 12
result = Convert.ToInt32(12.4444444);//returns 12
result = Convert.ToInt32("12.4"); // Input string was not in a correct format.
I understand different overloads of Convert.ToInt32 are being called for string and float/double
The question is why this inconsistent behavior shouldn't single overload for Convert.ToInt32 throw an exception for loss of precision ?
The question is why this inconsistent behavior shouldn't single
overload for Convert.ToInt32 throw an exception for loss of precision
?
You can think of the utility methods you're currently using to convert from double to int as "casting" i.e (int)12.4, (int)12.44 etc. which in essence means you for sure know that there is high chance that you'll lose data precision, thus in short is like telling the compiler "go ahead and convert it as I don't mind data loss", so, no exception will be thrown whereas the last example that converts from string to int should throw an exception because according to MSDN:
ToInt32(String) method is equivalent to passing value to the
Int32.Parse(String).
and as we all know Int32.Parse(String) throws an exception if the specified string is not in the correct format.
The way I see it, when you start with an float/double and you convert to int you expect a loss of precision. When you have a string that you convert to int you don't expect the parsing to do any losing of data, you just want it to parse and fail if the string is not valid.
You first have to convert your string into double, then cast it to int. or do another convert to int.
result = Convert.ToInt32(Convert.ToDouble("12.4"));
From msdn Convert.ToInt32(string)
Converts the specified string representation of a number to an equivalent 32-bit signed integer.
https://msdn.microsoft.com/en-us/library/sf1aw27b(v=vs.110).aspx
In given examples you can see that converting from double representation to int gives format exception.
so this is clearly by design. you should do it right.
Related
I am reading Data from an internal Database.
The code assigns value read from the database to double.
if (Convert.ToDouble(PricefromString) == Price && PriceFound == false)
PricefromString has been read from the database.
Most of the time the code works fine, but i get a FormatException, when the string value is an integer value.
In this particular case, when PricefromString = 77, i get the format exception.
I tried debugging and checked the input string to ToDouble() which is throwing the exception.
Edit: PricefromString has a whitespace tab character at the end attached.
It works perfectly fine when the string is a double value eg. 76.99, 77.01, but i get an FormatException error when price reaches an integer value.
Any leads ?
but i get a FormatException, when the string value is an integer value. In this particular case, when PricefromString = 77, i get the format exception.
No, you don't. Convert.ToDouble will work just fine with a string representing an integer, as you can see for yourself by running this code:
Console.WriteLine(Convert.ToDouble("77"));
It does in fact print out 77.
I would urge you to take a long, hard look at what precisely your input string is.
There might be something else, because if 77 is of String data type then definitely it will work.
Check to see if it does not contain any other characters like currency symbols.
Double.Parse or Convert.ToDouble will throw an exception if it cannot parse the given value.
Whereas Double.TryParse returns a bool indicating whether it succeeded.
Try this:
double value;
Double.TryParse(PricefromString, out value);
By this, you can check if it'll work or not and then do the real conversion once value is boolean true.
For more on this, please refer this answer: Parse v. TryParse
With this kind of code
double socialSecurityFee = 0;
double xsocialSecurityFee = double.Parse (socialSecurityFee);
I get this kind of error
Error CS1502: The best overloaded method match for
`double.Parse(string)' has some invalid arguments (CS1502)
(socialSecurityFee)
What's wrong with my code?
What's wrong with my code?
Exactly what the compiler is telling you - none of the overloads of double.Parse is appropriate for a single argument of type double. It's not even clear what you'd mean by that - parsing is usually about converting from one type (commonly a string) into another type (double in this case). Your initial value is already a double, so what would you expect it to do?
My guess is that you actually have a string somewhere, and you're trying to parse that - so you need to change your argument so that it uses that string instead of the socialSecurityFee variable. It's not clear that you need two variables of type double at all.
In addition, if this is meant to represent a currency amount (as it sounds like) you should consider using decimal instead of double.
double.Parse expects string as a parameter and you're trying to call it with another double value.
I'm not really sure why you're using double.Parse here, but to make it work add ToString() call:
double socialSecurityFee = 0;
double xsocialSecurityFee = double.Parse(socialSecurityFee.ToString());
or just assign the value itself (because it's already a double, isn't it?):
double socialSecurityFee = 0;
double xsocialSecurityFee = socialSecurityFee ;
There are four overloads of Double.Parse. Only one of them accepts a single parameter. The type of that parameter is a string but you are trying to pass a double. That is exactly what the compiler error message is telling you. You can not do that because doubles are not implicitly convertible to string. You can't invoke a method using parameters that don't implicitly convert to the types the method expects.
But what are you trying to do? socialSecurityFee is a double, so why are you trying to parse it? Parsing means analyzing a string to give it meaning.
The method double.Parse() expects a string argument, and you're passing it a double value.
Since your original value is already a double, you don't even need to use double.Parse()
socialSecurityFee is already a double. double.Parse expects a string, tough. You don't need to parse anything here. What are you trying to do?
Console.WriteLine("Enter a double number");
string numberInput = Console.ReadLine();
double number = Double.Parse(numberInput)
My question is what is the last line of code doing? Is it doing the same thing as ToDouble?
The very short answer is:
Converts a string value into a double. e.g.
"2.3"(String) will become 2.3(double).
You have many choices on how to do this:
Double.TryParse()
Convert.ToDouble()
Double.TryParse() is handy if you don't know 100% that the input string is going to be a number value.
It is converts a string to double, the Console.ReadLine() methods read a string data and store it on string variable named numberInput, to convert from that string to double, Double.Parse is called we passing to it the numberInput string and it will convert it to double.
"Converts the string representation of a number in a specified style to its double-precision floating-point number equivalent."
See MSDN.
It's taking String input and interpreting it as numeric input - Double in this case. String and Double are quite different types. For one, mathematical operations can be performed on Double.
Converts the string representation of a number to its double-precision floating-point number equivalent.
MSDN: http://msdn.microsoft.com/en-us/library/system.double.parse.aspx
It's calling the Double.Parse method. According to the MSDN page it
Converts the string representation of a number to its double-precision floating-point number equivalent.
As per #DoctorMick's answer: It does the same thing as the Convert.ToDouble method.
In this case it's used because the code is getting a string from the user which can be thought of as a sequence of letters. We would want to get this into the proper type that we want to work with, which in this case is Double. Double has the parse method for this.
The data read into the variable numberInput is a string. The last line parses this into the type System.Double, so that it is better typed for other operations.
There is no guarantee that numberInput contains a valid numeric value, in which case the Parse method will throw an exception that you can catch.
There have been 7 different answers yet everyone seems to have overlooked the question of is it doing the same as ToDouble. The short answer is yet, it is doing the same, in fact ToDouble calls double.Parse internally.
While Converting Decimal to String, I tried two methods.
Method 1:
string a = "100.00", b = "50.00";
string Total = (string)(Convert.ToDecimal(a) + Convert.ToDecimal(b));
It throws error, cannot convert Decimal to String.
Method 2:
string Total = (Convert.ToDecimal(a) + Convert.ToDecimal(b)).ToString();
It doesn't throw error and it is working fine.
I want to know the difference between these two methods of Conversion and Why it throws error when I used Method 1?
The first method is trying to take a decimal (the result of adding the 2 decimals) and cast it as a string. Since there's no (implicit or) explicit conversion from decimal to string, it throws because of the mismatch.
The second one takes a decimal and calls a ToString() method on it - since ToString is a valid method on the decimal type, this makes a normal instance method call and you get the return value of that call, which is a string.
Since you're using Convert calls already, you might find it more natural to do Convert.ToString to get the decimal back to a string.
It might be more clear if you separate the 'add two decimals' to a separate local var, since that's common to both here.
So, the (commented out) total1 fails because it's trying to just cast, and we have no conversion available to do so. The latter two both work fine, since they are method calls that are returning a string.
string a = "100.00", b = "50.00";
decimal result = Convert.ToDecimal(a) + Convert.ToDecimal(b);
//string total1 = (string)result;
string total2 = result.ToString();
string total3 = Convert.ToString(result);
The first code tries to "type cast" a decimal to string, where as the second one calls the ToString method on decimal to get the string representation of decimal. Type casting from decimal to string won't work, unless decimal type overloads the type conversion operator which it doesn't and hence the type casting throws exception.
Type casting in this case is like asking the CLR system to type cast a decimal to string, which CLR is unable to do because it doesn't find a way to do it.
Calling ToString is asking the decimal type to returns its string representation
Method1 is a cast , so you are trying to 'read' the data contained in a decimal variable as a string...of course you can't. You can cast, for example, a byte to an int because they are both numbers. Instead for decimal to string you need an explicit conversion procedure.
its because in first method you converted string a and b into decimal but while then you are just type casting to string, you need to convert that decimal value into string before assigning it to string variable.
in second method you are actually converting decimal value into string by using ToString() method, so its not giving error.
Here is link of table which says you can not convert decimal to string as you did in first method :
Explicit Numeric Conversions Table (C# Reference)
Second method is working because you are using the ToString() method of the object class.
In the first method are you basically doing
string a = (string)150m;
where 150 is decimal. There is no explicit or implicit cast from decimal to string. Compiler will not understand how to do the convert.
In the second method you call
string a = 150m.ToString();
In this case you are calling ToString method that Decimal class implements (along with all other classes).
What is the difference in C# between Convert.ToDecimal(string) and Decimal.Parse(string)?
In what scenarios would you use one over the other?
What impact does it have on performance?
What other factors should I be taking into consideration when choosing between the two?
There is one important difference to keep in mind:
Convert.ToDecimal will return 0 if it is given a null string.
decimal.Parse will throw an ArgumentNullException if the string you want to parse is null.
From bytes.com:
The Convert class is designed to
convert a wide range of Types, so you
can convert more types to Decimal than
you can with Decimal.Parse, which can
only deal with String. On the other
hand Decimal.Parse allows you to
specify a NumberStyle.
Decimal and decimal are aliases and
are equal.
For Convert.ToDecimal(string),
Decimal.Parse is called internally.
Morten Wennevik [C# MVP]
Since Decimal.Parse is called internally by Convert.ToDecimal, if you have extreme performance requirements you might want to stick to Decimal.Parse, it will save a stack frame.
One factor that you might not have thought of is the Decimal.TryParse method. Both Convert.ToDecimal and Parse throw exceptions if they cannot convert the string to the proper decimal format. The TryParse method gives you a nice pattern for input validation.
decimal result;
if (decimal.TryParse("5.0", out result))
; // you have a valid decimal to do as you please, no exception.
else
; // uh-oh. error message time!
This pattern is very incredibly awesome for error-checking user input.
One common suggestion related to original topic - please use TryParse() as soon as you not really sure that input string parameter WILL be correct number format representation.
Major Difference between Convert.ToDecimal(string) and Decimal.Parse(string)
is that Convert handles Null whereas the other throws an exception
Note: It won't handle empty string.
Convert.ToDecimal apparently does not always return 0. In my linq statement
var query = from c in dc.DataContext.vw_WebOrders
select new CisStoreData()
{
Discount = Convert.ToDecimal(c.Discount)
};
Discount is still null after converting from a Decimal? that is null. However, outside a Linq statement, I do get a 0 for the same conversion. Frustrating and annoying.
Knowing that Convert.ToDecimal is the way to go in most cases because it handles NULL, it, however, does not handle empty string very well. So, the following function might help:
'object should be a string or a number
Function ConvertStringToDecimal(ByVal ValueToConvertToDecimal As Object) As Decimal
If String.IsNullOrEmpty(ValueToConvertToDecimal.ToString) = False Then
Return Convert.ToDecimal(ValueToConvertToDecimal)
Else
Return Convert.ToDecimal(0)
End If
End Function