为啥 Convert.ToDecimal(3.1922) 显示为 31922?
Posted
技术标签:
【中文标题】为啥 Convert.ToDecimal(3.1922) 显示为 31922?【英文标题】:Why is Convert.ToDecimal(3.1922) showing as 31922?为什么 Convert.ToDecimal(3.1922) 显示为 31922? 【发布时间】:2012-10-28 14:49:02 【问题描述】:我正在读取一个包含值的 XML 文件。当我读到它们时,它们是字符串。
因此,当我尝试将它们转换为 Double
或 Decimal
时,这一点就消失了。
decimal dec = Convert.ToDecimal("3.1922");
MessageBox.Show(dec.ToString()); // 31922
我做错了什么?
【问题讨论】:
【参考方案1】:这和你现在的文化有关
decimal dec = Convert.ToDecimal("3.1922",CultureInfo.CreateSpecificCulture("de-DE"));
MessageBox.Show(dec.ToString()); //31922
dec = Convert.ToDecimal("3.1922", CultureInfo.CreateSpecificCulture("en-US"));
MessageBox.Show(dec.ToString()); //3.1922
dec = Convert.ToDecimal("3,1922", CultureInfo.CreateSpecificCulture("de-DE"));
MessageBox.Show(dec.ToString()); //3.1922
【讨论】:
您也应该添加推荐的解决方案,即明确指定CultureInfo.InvariantCulture
。
那么最好的方法是什么?使用 CultureInfo.InvariantCulture 或创建一个“有效”的文化。 IE。 CreateSpecificCulture("en-US") 像我想要的那样工作。
@Niels 这取决于你的具体情况,但如果你想让你的代码适用于许多语言环境,请使用CultureInfo.InvariantCulture
@L.B.感谢您的回答。 XML 中的值将始终采用这种格式,并且我的应用程序的 GUI 将始终使用英文。那么,最好的解决方案是什么?
@Niels 我会使用InvariantCulture
【参考方案2】:
在您当前的文化中,.
用作千位分隔符。你可以这样验证:
var culture = Thread.CurrentThread.CurrentCulture;
var numberFormat = culture.NumberFormat;
string groupSeparator = numberFormat.NumberGroupSeparator; // will be .
string decimalSeparator = numberFormat.NumberDecimalSeparator; // will be ,
您可以指定所需的解析文化:
decimal dec = Decimal.Parse("3.1922", new CultureInfo("en-US"));
或者您可以将您的文化设置为当前:
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
decimal dec = Decimal.Parse("3.1922");
【讨论】:
@Ons 你怎么知道尼尔斯的文化?例如,德国文化使用.
作为千位分隔符。
我说的是一般的美国文化。此处未指定文化。当我运行代码时。它显示正常。
这里没有指定文化那么,你为什么确定当前的OP环境文化?
@Ons 如果没有指定文化,则使用本地文化。你不能假设这种文化就是美国文化。必须明确使用必须InvariantCulture
才能使此代码可靠地工作。
这实际上是正确的。所以在这种情况下,我们可以使用文化不变量,它会正常工作吗?【参考方案3】:
检查您的 NumberFormat.NumberDecimalSeparator。
【讨论】:
【参考方案4】:首先在public form1()
after InitializeComponent();
中添加这些代码:
public Form1()
InitializeComponent();
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
然后在任何你想要的地方使用你的代码:
decimal dec = Convert.ToDecimal("3.1922");
MessageBox.Show(dec.ToString());
更新:
如果您不希望全局更改,则应在显示小数之前添加代码。
private void ShowDecimal_Click(object sender, EventArgs e)
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
decimal dec = Convert.ToDecimal("3.1922");
MessageBox.Show(dec.ToString());
更新 2:
decimal dec = Decimal.Parse("3.1922", new CultureInfo("en-US"));
MessageBox.Show(dec.ToString());
【讨论】:
局部问题的全局更改 => 糟糕的设计 @CodesInChaos 他可以在他的代码之前更改它。我只是给他指路;) 这让事情变得更糟。由于现在单击按钮会全局更改状态而不恢复它。以上是关于为啥 Convert.ToDecimal(3.1922) 显示为 31922?的主要内容,如果未能解决你的问题,请参考以下文章
Decimal.Parse() 与 Convert.ToDecimal() [重复]
使用 Convert.ToDecimal() 会导致 C# 中的值四舍五入。如何克服这个问题?