正确地将字符串转换为double

时间:2014-12-03 18:55:50

标签: c# type-conversion

我正在用c#编写一个程序,遇到了一个烦人的小问题。我需要将字段从dataGridView控件转换为double,以便将它们存储在数据库中。但是,它无法正确转换。

dataGridView中的原始值使用逗号(,)进行小数点分隔。

这是原始代码:

double number = Convert.ToDouble(dataGridView1.Rows[row].Cells[1].Value)

单元格是文本框类型。通过使用该方法,12,3变为12,3E + 14

由于某些未知原因,转换器将数字乘以10乘以功率14。

在阅读了一些问题之后,我偶然发现了另一种可能的解决方案

double number = Convert.ToDouble(dataGridView1.Rows[row].Cells[1].Value, CultureInfo.CurrentCulture);

结果仍然相同。 12,3 - > 12,3E + 14

double number = Convert.ToDouble(dataGridView1.Rows[row].Cells[1].Value.ToString(), CultureInfo.CurrentCulture);

这变得更有趣。而不是12,3我得到了123

我错过了什么吗?对所有这些都有一个简单的解决方案吗?

编辑:以防万一 - 数据库字段类型设置为real,dataGridView单元格是TextBox类型,因此输入是字符串类型。

EDIT2:我要做的是将值(实际)从数据库加载到DGV,将其保存到不同的数据库表中,然后从新写入的数据库表(实际)加载值并显示它在另一个DGV。将值从DGV1写入数据库后,其类型为Single。然而,在第二次将它们写入数据库之后,该值变为String类型,即使我没有对它进行任何更改。这可能是扭曲转换价值的原因吗?我的意思是他们第一次出现在12,3E + 14而不是12,3。我可以用Math.Pow(10,14)来划分它们以获得原始值,但这是肮脏的做法:/

最终编辑:谢谢大家的帮助,但在这种情况下真正的问题是我的疏忽。 由于这个程序正在开发很长一段时间,当我还习惯了c#语法时,我已经包含了一些变量类型的混淆,这使我不得不检查代码中的所有类型。再次,谢谢大家的帮助。

  

TL; DR - 保持变量类型一致。

6 个答案:

答案 0 :(得分:2)

如果你的CurrentCulture是在美国,它会将“1,23”解析为123.

正如Tigran所说,创建一个FormatProvider,或者创建一个NumberFormatInfo。如果您不想/需要更改CurrentCulture默认值,这是一个替代解决方案。

NumberFormatInfo provider = new NumberFormatInfo();
provider.NumberDecimalSeparator = ",";
double num = Convert.ToDouble("1,23", provider);

如果这行代码为您提供123:

double number = Convert.ToDouble(dataGridView1.Rows[row].Cells[1].Value.ToString(), CultureInfo.CurrentCulture);

那么这应该给你1.23:

NumberFormatInfo provider = new NumberFormatInfo();
provider.NumberDecimalSeparator = ",";
double number = Convert.ToDouble(dataGridView1.Rows[row]
.Cells[1].Value.ToString(),provider);

答案 1 :(得分:0)

您可以尝试使用a来调用要替换的字符串上的replace函数。然后进行转换。试试这个:

double number = Convert.ToDouble(dataGridView1.Rows[row].Cells[1].Value.ToString().Replace(",", "."));

答案 2 :(得分:0)

你试试吗

double da = double.Parse(a,CultureInfo.InvariantCulture);

这里有类似的问题

他们用它

C# convert string to double in locale

答案 3 :(得分:0)

第一个和第二个案例是相同的,因为在两种情况下,函数都使用CurrentCulture,就像第二个参数一样。

第三个更有趣,因为您使用:Convert.ToDouble(String)重载,它使用

  

当前线程文化的格式约定。

哪个可能推迟你的那台机器。

所以首先要做的事情就是imo,你可以检查一下当前的调试(我想象一下)线程文化是否等于你的那台机器,如果不是会产生影响。

考虑在“fr-FR”中,小数分隔符为“,”,其中“en-US”为“。”。 为了正确威胁已知的数据格式,您需要提供自定义FormatProvider并使用它进行解析。

因此,在您的情况下,代码可能如下所示:

 //assign expected separator
 NumberFormatInfo nf = new NumberFormatInfo();
 nf.NumberDecimalSeparator = ",";

 var val = dataGridView1.Rows[row].Cells[1].Value;
 double number = Convert.ToDouble(val, nf);

应该适合你。

答案 4 :(得分:0)

由于Value属性的类型为object,因此它可能包含一个盒装双值。在这种情况下,演员就足够了:

double number = (double)dataGridView1.Rows[row].Cells[1].Value;

或者,如果列可以为空,可能

double? number = (double?)dataGridView1.Rows[row].Cells[1].Value;

请注意,这不涉及转换,只是将值转换为正确的类型。

尝试输出此信息以了解值的类型:

System.Diagnostics.Debug.WriteLine(
    dataGridView1.Rows[row].Cells[1].Value.GetType().Name);

然后打开输出窗口。

答案 5 :(得分:0)

我终于解决了我的问题。看来,即使C#具有本地化选项,SQL也没有。

数字转换得很好,但SQL解析查询错误:

"INSERT INTO myTable VALUES ('2,5' , '3,1'); 

没有用,但是这样做了:

"INSERT INTO myTable VALUES ('2.5' , '3.1');