Can cout alter variables somehow?所以我有一个看起来像这样的函数:
在某个时候,此函数溢出并返回一个很大的负值。 为了尝试精确地查明发生的地方,我添加了一个cout语句,使函数如下所示:
而且有效! 当然,我通过使用double彻底解决了这个问题。 但是我很好奇为什么在我编写函数时该函数可以正常工作。 这是典型的,还是我想念的其他地方有错误? (如果有帮助,存储在浮点数中的值只是一个整数值,而不是一个特别大的值。我只是将其放在浮点数中以避免转换。) 欢迎来到浮点奇妙的世界。得到的答案可能取决于编译代码所使用的浮点模型。 发生这种情况是由于IEEE规范和运行代码的硬件之间的差异。您的CPU可能有80位浮点寄存器,可用于保存32位浮点值。这意味着,将值保留在寄存器中时,其精度要比被强制到存储器地址(也称为"归巢"寄存器)的精度高得多。 当您将值传递给cout时,编译器不得不将浮点数写入内存,这会导致精度损失和令人感兴趣的WRT溢出情况。 请参阅有关VC ++浮点开关的MSDN文档。您可以尝试使用/ fp:strict进行编译,看看会发生什么。 将值打印到cout根本不应该改变参数的值。 但是,我已经看到了类似的行为,添加调试语句会导致值更改。在这些情况下,也许我也猜到这是其他语句导致编译器的优化器行为不同,因此为您的函数生成不同的代码。 添加cout语句意味着直接使用x的值。没有它,优化器可能会删除该变量,因此更改了计算顺序,因此更改了答案。
顺便说一句,使用
除其他事项外,这将防止您无意间将变量传递给可能通过非 cout导致对该变量的引用,这通常会导致编译器迫使其将其溢出到堆栈中。 因为它是浮点型的,所以这很可能导致其值从通常具有的double或long double表示形式中被截断。 调用任何需要对x进行指针或引用的函数(非内联函数)都将导致相同的行为,但是如果编译器以后变得更聪明并学会内联它,您将同样被搞砸了:) 我认为cout对变量没有任何影响,问题可能必须在其他地方。 |