Excel 2010 vs Excel 2003中整数的表示(C ++插件)

介绍

我inheritance了VS2008,xlw 2.0和excel 2003开发的传统插件项目(用C ++编写)。

我已经设法将其移植到xlw 4.0头(当添加对Excel 2007的支持时,某些方法更改了名称,类似的东西)。 我还没有产生任何东西,因为旧的代码是手工编写的,我不会改变一些正在工作的东西,而只是为了它而具有合理的结构和代码逻辑。

代码在excel 2003下按照预期工作。我今天用excel 2010试了一下,发现了一个最令人困惑的(和可怕的)错误。

令人费解的行为

我收到(从VBAmacros)一列(n行1列)的数字(通过build设小正整数)作为XlfOper&,我想将其转换为(旧式)arrays。 代码基本上遍历每一行,然后调用对应于给定行的XlfOper上的AsInt()方法。 就像是:

for (long iy = 0; iy < numcols; ++iy) { for (long ix = 0; ix < numrows; ++ix) convertXflOper( x(ix, iy), a1D[iy*numrows + ix] ); } 

其中a1D是此特定项目中使用的1维数组types,convertXflOper是一个模板函数,适用于以下types:

 void convertXflOper (const XlfOper &x, long & y) { y = x.AsInt(); } 

在一个给定的行,我在Excel的工作簿数10。

在Excel 2003下,这将转换为10.在Excel 2010中,这将转换为9。

我已经debugging过了,问题是它实际上读数不是10,而是一个近似值。 输出(即时窗口)是

 x.lpxloper4_->val.num 9.9999999999999982 // wrong: I am not asking for 10.0, I am asking for 10 

在Excel 2010中,和

 x.lpxloper4_->val.num 10.000000000000000 // right: an integer is an integer 

在Excel 2003中。因此,C ++代码看起来不错,看起来不错。 AsInt()方法的行为类似于cast,而static_cast<long>(9.9999999999999982)是9,而不是10。

这件事情会让我非常沮丧,主要是因为很容易忽视它:对于其他许多整数值,它在Excel 2003和2010中都能正常工作。

我在做什么错误的Excel界面,它认为一个整数必须被视为一个双? 我怎么能确定,这不会发生谁知道在哪里,什么时候? 解决这个问题的最好方法是什么?

Excel不在内部保存整数 – 所有的数字(整数,date,时间,货币等)保持为双打。 所以Oper val.num总是双重的,而xltypeNum的一个操作总是双重的。
(操作人员可以在val.w中保存整数,但只能作为XLM Macrostream量控制的一部分,这些操作已经过时了几十年,不太可能在实践中得到满足)。
我不知道为什么你会在Excel 2007中获得9.9999999 – 你如何将价值传递给Oper?