Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Excel 2010与Excel 2003中整数的表示法(C+;+;插件)_C++_Visual Studio_Excel_Visual Studio 2008_Xls - Fatal编程技术网

C++ Excel 2010与Excel 2003中整数的表示法(C+;+;插件)

C++ Excel 2010与Excel 2003中整数的表示法(C+;+;插件),c++,visual-studio,excel,visual-studio-2008,xls,C++,Visual Studio,Excel,Visual Studio 2008,Xls,导言 我继承了一个用VS2008、XLW2.0和Excel2003开发的遗留插件项目(用C++) 我已经设法将它移植到XLW4.0头文件中(在添加对Excel2007的支持时,一些方法更改了名称,诸如此类)。我还没有生成任何东西,因为旧代码是手工编写的,我不打算更改正在工作的东西,并且只有为了它才有一个合理的结构和代码逻辑 该代码在Excel2003下正常工作。我今天尝试了excel 2010,发现了一个最令人困惑(和恐惧)的bug 令人困惑的行为 我(从一个VBA宏)接收到一列(n行,1列)数

导言

我继承了一个用VS2008、XLW2.0和Excel2003开发的遗留插件项目(用C++)

我已经设法将它移植到XLW4.0头文件中(在添加对Excel2007的支持时,一些方法更改了名称,诸如此类)。我还没有生成任何东西,因为旧代码是手工编写的,我不打算更改正在工作的东西,并且只有为了它才有一个合理的结构和代码逻辑

该代码在Excel2003下正常工作。我今天尝试了excel 2010,发现了一个最令人困惑(和恐惧)的bug

令人困惑的行为

我(从一个VBA宏)接收到一列(n行,1列)数字(构造为小正整数),作为XlfOper&我想将其转换为一个(旧式)数组。代码基本上是遍历每一行,然后在与给定行对应的XlfOper上调用AsInt()方法。比如:

for (long iy = 0; iy < numcols; ++iy)
{
for (long ix = 0; ix < numrows; ++ix)
    convertXflOper( x(ix, iy), a1D[iy*numrows + ix] ); 
}
在给定的一行,excel工作簿中有数字10

在Excel 2003下,该值转换为10。在Excel 2010下,这将转换为9。

我已经调试过了,问题是它的读数不是10,而是它的一个双重近似值。(即时窗口的)输出是

在Excel 2010中,以及

x.lpxloper4_->val.num
10.000000000000000 // right: an integer is an integer
在Excel 2003中。因此,C++代码,如它漂亮(或不),似乎不存在错误。AsInt()方法的行为类似于强制转换,
static_cast(9.9999999982)
是9,而不是10

问题

这件事会让我非常难受,主要是因为它很容易被忽略:对于许多其他整数值,它在Excel2003和2010中都能正常工作


我在excel界面中犯了什么错误,因为它认为必须将整数视为双精度?我怎么能确定这不会发生谁知道在哪里和什么时候?解决此问题的最佳方法是什么?

Excel内部不保存整数-所有数字(整数、日期、时间、货币等)都保存为双精度。因此,Oper val.num始终是双精度的,而xltypeNum的Oper始终是双精度的。
(Oper可以在val.w中保存整数,但只能作为XLM宏流控制等东西的一部分,这些东西已经过时几十年了,在实践中不太可能实现)。

我不知道为什么在Excel 2007中会得到9.9999999-如何将值传递给运算符?

我认为Excel内部使用浮点数是有意义的。在新版excel中,舍入的内部行为可能发生了变化。如果您可以访问像
x.AsDouble()这样的方法
您应该自己进行四舍五入。@Fermat2357很好,但整数应该精确表示,这似乎是一个基本要求。我可以使用这种方法,问题是要确保我在所有可能需要的情况下都应用它……这是一种动态输入,不容易预测何时会出现需要,也不容易确保手动转换适用于所有地方。是的,你是对的。足够小的整数可以精确地表示为double。如果我们假设期望的整数是非常接近浮点格式的近似值,那么将舍入方法应用于强制转换为整数应该可以。如果我们不能假设你有麻烦。你至少应该测试一下。这个单元格的公式是什么?似乎在这条线的某个地方,它涉及到一些不返回整数的数学。@MarkRansom很好的猜测:但它是一个静态值。它基本上是计算行中大于零的单元格数,但不是一个公式:它是由一个(先前的,独立的)宏作为值写入的。谢谢@charleswillams。这也是我(尽管有限)的理解。XlfOper的传递方式如下:Run(“my_dll_函数”,Application.Run(a_工作表_名称&a_VBA_函数_返回a_范围));所讨论的函数只是设置了一个_函数….=ThisWorkbook.Sheets(....).Range(“my_Range_name”)由于数字来自单元格,因此最初将是一个双精度数字。从命名范围中获取值似乎是一条非常迂回的路线,在这条路线上可能会进行多次转换,但我认为这是有原因的。您是否尝试过在XL 2007中使用Oper12来查看是否发生了相同的情况?
x.lpxloper4_->val.num
9.9999999999999982 // wrong: I am not asking for 10.0, I am asking for 10
x.lpxloper4_->val.num
10.000000000000000 // right: an integer is an integer