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
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
including culture and number style will be better approach:
short.TryParse(myDecimal.ToString(), NumberStyles.Integer | NumberStyles.AllowDecimalPoint,
System.Globalization.CultureInfo.InvariantCulture, out newVal);
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, AllowThousandsYou 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);
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
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);
Try: Convert.ToInt16(myDecimal);