Reputation: 4718
I have a decimal value
decimal myDecimal = 19.0000M;
I'm trying to convert this to a short value.
short newVal;
short.TryParse(myDecimal.ToString(), out newVal); // False
but this fails. If I use a double it is fine.
Why does this fail?
Thanks
Upvotes: 4
Views: 3249
Reputation: 37281
The Problem
The problem is that this overload of TryParse
takes that number as
an NumberStyles.Integer
- meaning it is looking for a format that
does not contain any .
. seeing in Reference Source it is
actually doing this:
public static bool TryParse(String s, out Int16 result) {
return TryParse(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result);
}
To show that the .
is the problem change as following and it will
work:
decimal myDecimal = 19M;
var succeeded = short.TryParse(myDecimal.ToString(), out newVal);
How Does Double work but decimal fails
The reason why with double it works is because of how it is returned in the ToString
:
decimal val1 = 19.00M;
double val2 = 19.00;
val1.ToString() // "19.00"
val2.ToString() // "19"
The Fix
To be able to parse your original input use instead the overload where you provide the NumberStyle
and Format
:
var succeeded = short.TryParse(myDecimal.ToString(), NumberStyles.Number, NumberFormatInfo.CurrentInfo, out newVal);
The NumberStyle.Number
allows:
AllowLeadingWhite
, AllowTrailingWhite
, AllowLeadingSign
,
AllowTrailingSign
, AllowDecimalPoint
, AllowThousands
Upvotes: 2
Reputation:
It doesn't work because myDecimal.ToString() returns a decimal number string: 19.000 and short.Tryparse() accepts only integer strings.
The solution is not to convert to string but directly between decimal and short (as luki shows):
short shortVal = Convert.ToInt16(myDecimal);
Upvotes: 0
Reputation: 18137
You should AllowDecimalPoint
with parsing of short in other case the parsing will fail: DonNetFiddle
decimal myDecimal = 19.0000M;
short newVal;
short.TryParse(myDecimal.ToString(), NumberStyles.AllowDecimalPoint , CultureInfo.InvariantCulture, out newVal);
Upvotes: 1
Reputation: 7546
Remember, decimal saves digits after floating point as well. So, mathematicaly equal numbers will give different effect when printed:
decimal myDecimal = 19.0000M;
decimal myDecimal2 = 19.000000M;
Console.WriteLine(myDecimal.ToString());
Console.WriteLine(myDecimal2.ToString());
//OUTPUT
19,0000
19,000000
Upvotes: 0
Reputation: 557
including culture and number style will be better approach:
short.TryParse(myDecimal.ToString(), NumberStyles.Integer | NumberStyles.AllowDecimalPoint,
System.Globalization.CultureInfo.InvariantCulture, out newVal);
Upvotes: 4