4

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

Gilad Green
  • 36,708
  • 7
  • 61
  • 95
Sun
  • 4,458
  • 14
  • 66
  • 108

6 Answers6

4

including culture and number style will be better approach:

short.TryParse(myDecimal.ToString(), NumberStyles.Integer | NumberStyles.AllowDecimalPoint, 
           System.Globalization.CultureInfo.InvariantCulture, out newVal);
kashi_rock
  • 539
  • 1
  • 5
  • 19
2

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
Gilad Green
  • 36,708
  • 7
  • 61
  • 95
  • 1
    From decimal to string to int? Maybe there is an even more complicated way available? – Uwe Keim Oct 26 '16 at 11:12
  • 1
    @UweKeim - That is how he is doing in the question. This is just providing a way of how to use what he is doing but that will work – Gilad Green Oct 26 '16 at 11:13
  • 1
    Yeah, sorry, will post my comment at the appropriate location . – Uwe Keim Oct 26 '16 at 11:13
  • @Jim - In your computer the culture is different and probably uses `,` as the symbol for a decimal point. Change the `.` to `,` and try. The `InvariantCulture` is based on English. See [this](http://stackoverflow.com/questions/2423377/what-is-the-invariant-culture) – Gilad Green Oct 26 '16 at 11:38
1

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);
mybirthname
  • 17,949
  • 3
  • 31
  • 55
0

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
eocron
  • 6,885
  • 1
  • 21
  • 50
0

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);

-2

Try: Convert.ToInt16(myDecimal);

luki
  • 72
  • 2
  • 1
    I can try a lot, but I would prefer an answer and an explanation why it works and why the original approach does not work – Thomas Weller Oct 26 '16 at 11:02
  • In default version of TryParse method input parameter s(string) is interpretted using NumberStyles.Integer style , so you will be able to input only string with digits and optional white spaces and sign character. In your example your input string contains decimal delimeter character so TryParse method returns false. If you want to use this method to parse your input you have to use this method: – luki Oct 26 '16 at 11:14
  • public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out short result) – luki Oct 26 '16 at 11:14