我遇到了一个问题,似乎在使用Microsoft ACE驱动程序打开Excel电子表格后,一些计算结果发生了变化。
下面的代码重现了这个问题。
前两次调用
请注意最后三位小数的差异。这似乎不是很大的差异,但在我们的生产代码中,计算非常复杂,导致的差异相当大。
如果我使用JET驱动程序而不是ACE驱动程序,没有任何区别。如果我将类型从双精度更改为十进制,则错误消失了。但这在我们的生产代码中不是一个选项。
我正在运行Windows 7 64位,程序集编译为.NET 4.5 x86。由于我们正在运行32位Office,因此不能使用64位ACE驱动程序。
有人知道为什么会发生这种情况以及如何解决吗?
以下代码重现了我的问题:
下面的代码重现了这个问题。
前两次调用
DoCalculation
产生相同的结果。然后我调用函数OpenSpreadSheet
,使用ACE驱动程序打开并关闭Excel 2003电子表格。你不会期望OpenSpreadSheet
对最后一次调用DoCalculation
产生任何影响,但结果实际上改变了。这是程序生成的输出:1,59142713593566
1,59142713593566
1,59142713593495
请注意最后三位小数的差异。这似乎不是很大的差异,但在我们的生产代码中,计算非常复杂,导致的差异相当大。
如果我使用JET驱动程序而不是ACE驱动程序,没有任何区别。如果我将类型从双精度更改为十进制,则错误消失了。但这在我们的生产代码中不是一个选项。
我正在运行Windows 7 64位,程序集编译为.NET 4.5 x86。由于我们正在运行32位Office,因此不能使用64位ACE驱动程序。
有人知道为什么会发生这种情况以及如何解决吗?
以下代码重现了我的问题:
static void Main(string[] args)
{
DoCalculation();
DoCalculation();
OpenSpreadSheet();
DoCalculation();
}
static void DoCalculation()
{
// Multiply two randomly chosen number 10.000 times.
var d1 = 1.0003123132;
var d3 = 0.999734234;
double res = 1;
for (int i = 0; i < 10000; i++)
{
res *= d1 * d3;
}
Console.WriteLine(res);
}
public static void OpenSpreadSheet()
{
var cn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;data source=c:\temp\workbook1.xls;Extended Properties=Excel 8.0");
var cmd = new OleDbCommand("SELECT [Column1] FROM [Sheet1$]", cn);
cn.Open();
using (cn)
{
using (OleDbDataReader reader = cmd.ExecuteReader())
{
// Do nothing
}
}
}