cout 可以以某种方式改变变量吗?

发布于 2024-07-04 11:52:36 字数 499 浏览 8 评论 0原文

所以我有一个看起来像这样的函数:

float function(){
    float x = SomeValue;
    return x / SomeOtherValue;
}

在某些时候,这个函数会溢出并返回一个非常大的负值。 为了尝试准确地追踪发生这种情况的位置,我添加了一个 cout 语句,使该函数看起来像这样:

float function(){
    float x = SomeValue;
    cout << x;
    return x / SomeOtherValue;
}

并且它起作用了! 当然,我通过使用 double 完全解决了这个问题。 但我很好奇为什么当我计算这个函数时它可以正常工作。 这是典型的吗?还是可能有我遗漏的其他地方的错误?

(如果有帮助的话,存储在浮点数中的值只是一个整数值,而不是一个特别大的值。我只是将它放在浮点数中以避免强制转换。)

So I have a function that looks something like this:

float function(){
    float x = SomeValue;
    return x / SomeOtherValue;
}

At some point, this function overflows and returns a really large negative value. To try and track down exactly where this was happening, I added a cout statement so that the function looked like this:

float function(){
    float x = SomeValue;
    cout << x;
    return x / SomeOtherValue;
}

and it worked! Of course, I solved the problem altogether by using a double. But I'm curious as to why the function worked properly when I couted it. Is this typical, or could there be a bug somewhere else that I'm missing?

(If it's any help, the value stored in the float is just an integer value, and not a particularly big one. I just put it in a float to avoid casting.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

落叶缤纷 2024-07-11 11:52:36

将值打印到 cout 根本不应该以任何方式更改参数的值。

但是,我看到了类似的行为,添加调试语句会导致值发生变化。 在这些情况下,也许这也是我的猜测是附加语句导致编译器的优化器表现不同,因此为您的函数生成不同的代码。

添加cout语句意味着直接使用x的值。 如果没有它,优化器可能会删除该变量,从而改变计算的顺序,从而改变答案。

Printing a value to cout should not change the value of the paramter in any way at all.

However, I have seen similar behaviour, adding debugging statements causes a change in the value. In those cases, and probably this one as well my guess was that the additional statements were causing the compiler's optimizer to behave differently, so generate different code for your function.

Adding the cout statement means that the vaue of x is used directly. Without it the optimizer could remove the variable, so changing the order of the calculation and therefore changing the answer.

孤独岁月 2024-07-11 11:52:36

我认为 cout 对变量没有任何影响,问题必须出在其他地方。

I dont think the cout has any effect on the variable, the problem would have to be somewhere else.

暗恋未遂 2024-07-11 11:52:36

欢迎来到浮点的奇妙世界。 您得到的答案可能取决于您编译代码所使用的浮点模型。

发生这种情况的原因是 IEEE 规范与代码运行的硬件之间存在差异。 您的 CPU 可能有 80 位浮点寄存器,用于保存 32 位浮点值。 这意味着当值保留在寄存器中时,其精度比强制到内存地址(也称为“归位”寄存器)时要高得多。

当您将值传递给 cout 时,编译器必须将浮点写入内存,这会导致精度丢失和有趣的 WRT 溢出情况。

请参阅有关 VC++ 浮点开关的 MSDN 文档。 您可以尝试使用 /fp:strict 进行编译,看看会发生什么。

Welcome to the wonderful world of floating point. The answer you get will likely depend on the floating point model you compiled the code with.

This happens because of the difference between the IEEE spec and the hardware the code is running on. Your CPU likely has 80 bit floating point registers that get use to hold the 32-bit float value. This means that there is far more precision while the value stays in a register than when it is forced to a memory address (also known as 'homing' the register).

When you passed the value to cout the compiler had to write the floating point to memory, and this results in a lost of precision and interesting behaviour WRT overflow cases.

See the MSDN documentation on VC++ floating point switches. You could try compiling with /fp:strict and seeing what happens.

眼眸印温柔 2024-07-11 11:52:36

cout 会导致对变量的引用,这通常会导致编译器强制将其溢出到堆栈中。

由于它是浮点型,这可能会导致其值从通常具有的 double 或 long double 表示形式中被截断。

调用任何接受 x 的指针或引用的函数(非内联)最终会导致相同的行为,但如果编译器后来变得更聪明并学会内联它,你也会同样被搞砸:)

cout causes a reference to the variable, which often will cause the compiler to force it to spill it to the stack.

Because it is a float, this likely causes its value to be truncated from the double or long double representation it would normally have.

Calling any function (non-inlined) that takes a pointer or reference to x should end up causing the same behavior, but if the compiler later gets smarter and learns to inline it, you'll be equally screwed :)

血之狂魔 2024-07-11 11:52:36

顺便说一句,使用 const 声明不可变变量总是一个好主意:

float function(){
    const float x = SomeValue;
    cout << x;
    return x / SomeOtherValue;
}

除其他外,这将防止您无意中将变量传递给可能通过非 const 修改它们的函数代码>参考文献。

As an aside, it's always a good idea to declare immutable variables using const:

float function(){
    const float x = SomeValue;
    cout << x;
    return x / SomeOtherValue;
}

Among other things this will prevent you from unintentionally passing your variables to functions that may modify them via non-const references.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文