如何将带小数点的字符串解析为double?

217 c# string double parsing

我想解析"3.5"一个双字符串的字符串.然而,

double.Parse("3.5") 
Run Code Online (Sandbox Code Playgroud)

收益35和

double.Parse("3.5", System.Globalization.NumberStyles.AllowDecimalPoint) 
Run Code Online (Sandbox Code Playgroud)

抛出一个FormatException.

现在我的计算机的语言环境设置为德语,其中逗号用作小数分隔符.它可能需要做些什么并double.Parse()期待"3,5"作为输入,但我不确定.

如何解析包含十进制数的字符串,该十进制数可能是也可能不是我当前语言环境中指定的格式?

Meh*_*ari 390

double.Parse("3.5", CultureInfo.InvariantCulture)
Run Code Online (Sandbox Code Playgroud)

  • 这意味着doulble.Parse使用默认文化,可能不包含点作为小数点? (4认同)
  • 对我不起作用:跳过逗号并返回和int为double (4认同)
  • 它使用当前运行的线程的文化. (3认同)
  • 如果转换12345678.12345678,它也转换为12345678.123457 (3认同)

Pie*_*ant 70

我通常使用多文化函数来解析用户输入,主要是因为如果有人习惯于小键盘并使用使用逗号作为小数分隔符的文化,那么该人将使用小键盘的点而不是逗号.

public static double GetDouble(string value, double defaultValue)
{
    double result;

    //Try parsing in the current culture
    if (!double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.CurrentCulture, out result) &&
        //Then try in US english
        !double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out result) &&
        //Then in neutral language
        !double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture, out result))
    {
        result = defaultValue;
    }

    return result;
}
Run Code Online (Sandbox Code Playgroud)

请注意,@ nicie评论是真的.为了我的辩护,我在受控环境中使用此功能,我知道文化可以是en-US,en-CA或fr-CA.我使用这个函数是因为在法语中,我们使用逗号作为小数分隔符,但是任何曾在金融界工作过的人都会在小键盘上使用小数分隔符,但这是一个点,而不是逗号.因此,即使在fr-CA文化中,我也需要解析具有小数分隔符的数字.

  • 我不确定这是个好主意.如果您不了解文化,则无法可靠地解析双精度:在德国,双值可能包含'.',但它们被认为是千位分隔符.所以在Legate的情况下,GetDouble("3.5")将在德国语言环境中返回35,在en-us环境中返回3.5. (18认同)

Mal*_*Jan 21

我不能写评论,所以我写在这里:

double.Parse("3.5",CultureInfo.InvariantCulture)不是一个好主意,因为在加拿大我们写3,5而不是3.5,这个函数给我们35作为结果.

我在电脑上测试了两个:

double.Parse("3.5", CultureInfo.InvariantCulture) --> 3.5 OK
double.Parse("3,5", CultureInfo.InvariantCulture) --> 35 not OK
Run Code Online (Sandbox Code Playgroud)

这是Pierre-Alain Vigeant提到的正确方法

public static double GetDouble(string value, double defaultValue)
{
    double result;

    // Try parsing in the current culture
    if (!double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.CurrentCulture, out result) &&
        // Then try in US english
        !double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out result) &&
        // Then in neutral language
        !double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture, out result))
    {
        result = defaultValue;
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)


小智 17

Double.Parse("3,5".Replace(',', '.'), CultureInfo.InvariantCulture)
Run Code Online (Sandbox Code Playgroud)

在解析之前用逗号替换逗号.在逗号为小数分隔符的国家/地区中很有用.考虑将用户输入(如有必要)限制为一个逗号或点.

  • 这不是一个好答案,因为在某些文化信息中,千位分隔符并且可以使用。如果将其替换为点,则最终将具有多个点,并且解析将失败:Double.Parse((12345.67).ToString(“ N”,new CultureInfo(“ en”))。Replace(',','。 '),CultureInfo.InvariantCulture),因为(12345.67).ToString(“ N”,new CultureInfo(“ en”))。Replace(',','。')的格式将为“ 12.345.67” (3认同)

Yak*_*een 15

诀窍是使用不变的文化,在所有文化中解析点.

double.Parse("3.5", System.Globalization.NumberStyles.AllowDecimalPoint, System.Globalization.NumberFormatInfo.InvariantInfo);
Run Code Online (Sandbox Code Playgroud)

  • 不适用于所有情况.1.234.567,89 (8认同)
  • 不起作用,失败并显示“3,5” (2认同)

小智 10

看,上面的每个答案建议用常量字符串写一个字符串替换只能是错误的.为什么?因为您不尊重Windows的区域设置!Windows确保用户可以自由设置他/她想要的任何分隔符.他/她可以打开控制面板,进入区域面板,点击高级并随时更改角色.即使在你的程序运行期间.想一想.一个好的解决方案必须要注意这一点.

所以,首先你必须问自己,这个数字来自哪里,你要解析.如果它来自.NET Framework中的输入没问题,因为它将采用相同的格式.但也许它来自外部,可能来自外部服务器,也许来自只支持字符串属性的旧数据库.在那里,数据库管理员应该给出一个规则,以这种格式存储数字.如果你知道它将是一个美国格式的美国数据库,你可以使用这段代码:

CultureInfo usCulture = new CultureInfo("en-US");
NumberFormatInfo dbNumberFormat = usCulture.NumberFormat;
decimal number = decimal.Parse(db.numberString, dbNumberFormat);
Run Code Online (Sandbox Code Playgroud)

这将在世界任何地方都能正常工作.请不要使用'Convert.ToXxxx'."转换"类仅被视为任何方向转换的基础.此外:您也可以使用DateTimes的类似机制.

  • 一个大问题是,当用户使用的小数点分隔符不被视为其文化设置的小数点分隔符时 (2认同)