Short.Parse 小数失败

Short.Parse with decimal fails

我有一个十进制值

decimal myDecimal = 19.0000M;

我正在尝试将其转换为短值。

short newVal;
short.TryParse(myDecimal.ToString(), out newVal); // False

但这失败了。如果我用双倍的就好了。

为什么会失败?

谢谢

尝试: Convert.ToInt16(myDecimal);

请记住,十进制也在浮点数之后保存数字。因此,数学上相等的数字在打印时会产生不同的效果:

decimal myDecimal = 19.0000M;
decimal myDecimal2 = 19.000000M;
Console.WriteLine(myDecimal.ToString());
Console.WriteLine(myDecimal2.ToString());

//OUTPUT
19,0000
19,000000

包括文化和数字样式会更好:

short.TryParse(myDecimal.ToString(), NumberStyles.Integer | NumberStyles.AllowDecimalPoint, 
           System.Globalization.CultureInfo.InvariantCulture, out newVal);

你应该 AllowDecimalPoint 解析 short 否则解析会失败:DonNetFiddle

decimal myDecimal = 19.0000M;
short newVal;

short.TryParse(myDecimal.ToString(), NumberStyles.AllowDecimalPoint , CultureInfo.InvariantCulture, out newVal);

它不起作用,因为 myDecimal.ToString() returns 十进制数字字符串:19.000 并且 short.Tryparse() 只接受整数字符串。

解决办法不是转成字符串而是直接在decimal和short之间转换(如luki所示):

short shortVal = Convert.ToInt16(myDecimal);

The Problem

  • 问题是 TryParse 的重载将该数字作为 一个 NumberStyles.Integer - 意味着它正在寻找一种格式 不包含任何 .。在 Reference Source 中看到它是 实际这样做:

    public static bool TryParse(String s, out Int16 result) {
       return TryParse(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result);
    }
    
  • 为了说明.是问题的变化如下 工作:

    decimal myDecimal = 19M;
    var succeeded = short.TryParse(myDecimal.ToString(), out newVal);
    

How Does Double work but decimal fails

double 起作用的原因是它在 ToString:

中的返回方式
decimal val1 = 19.00M;
double val2 = 19.00;

val1.ToString() // "19.00"
val2.ToString() // "19"

The Fix

为了能够解析您的原始输入,请使用您提供 NumberStyleFormat:

的重载
var succeeded = short.TryParse(myDecimal.ToString(), NumberStyles.Number, NumberFormatInfo.CurrentInfo,  out newVal);

NumberStyle.Number允许:

  • AllowLeadingWhite, AllowTrailingWhite, AllowLeadingSign, AllowTrailingSignAllowDecimalPointAllowThousands