【问题标题】:Different Results in Debug and Release Modes调试和发布模式的不同结果
【发布时间】:2011-09-19 19:57:58
【问题描述】:
vector<double> pvec;

double firstnode=0.0;

for(iter2=svec.begin(); iter2!=svec.end(); iter2++)
{
    double price= 0.0;
    string sFiyat = iter2->substr(13);
    stringstream(sFiyat)>>price;
    price=log(price);

    if (iter2==iter)
    {
        firstnode = price;
    }
    price -= firstnode;

    pvec.push_back(price);
}

我得到了上面的代码,调试和发布模式有一个神奇的区别。该算法旨在使向量的第一个元素等于零,然后找到第一个元素的对数与其他元素的对数之差。

在调试模式下,这给出了我想要的结果,并且向量的第一个元素始终等于零。但是当我切换到释放模式时,向量的第一个元素等于一些小的数字,例如 8.86335e-019。

这还不是全部。当我输入“cout

【问题讨论】:

  • 请注意:使用++iter2 对抗iter2++iter2++ 源代码通常看起来像这样:iterator operator++ (int i) { iterator temp = (*this); ++(*this); return temp; };
  • 通过最荒谬的修改解决了问题。我添加了“价格 -= 0;”在“price=log(price);”行之后
  • 这正是我所说的复杂和变化无常的意思。该行虽然看似无害,但可能会将price 推出更高精度的内部存储器,从而在您接下来访问它时导致值略有不同。你不能依赖它总是有效的......一组不同的优化设置,或者附近的另一个无害的变化,可以让你回到你开始的地方。如果您需要第一个元素完全为零,则将其设置为零。无论哪种方式,始终依靠浮点错误。

标签: c++ visual-studio-2010 debugging release


【解决方案1】:

调试浮点堆栈使用 FPU 中可用的完整 80 位精度。释放模式对更高效的 64 位截断结果执行。

使用 /fp http://msdn.microsoft.com/en-us/library/e7s85ffb%28VS.80%29.aspx 修改您的浮点行为以独立构建,请参阅 http://thetweaker.wordpress.com/2009/08/28/debugrelease-numerical-differences/ 以及

您观察到的一些差异仅与显示精度有关。在将 cout 与 MSVC 调试器显示的值进行比较之前,请确保将其设置为全精度。

【讨论】:

  • 两个版本的浮点模型没有区别,但是结果还是有区别的
  • 我认为您的第一段不一定正确。 x86 FPU 在内部始终使用 80 位寄存器,并且 (AFAIK) 通过启用优化,发布版本可以 将值保留在 80 位寄存器中,保持比存储时更高的精度回到内存中的 64 位双打。 (这在使用 SSE 而不是 FPU 时会发生变化,因为 SSE 会截断为 32 位或 64 位浮点。)
【解决方案2】:

当您使用浮点计算时,8e-19 量级的错误与您得到的一样接近于零。

您的误差小于计算值的十亿分之一。这很接近!

【讨论】:

  • 没错,但我需要将结果与其他内容进行比较。由于数据量很大,我自己无法比较。并且它们应该彼此相同,以便与算法进行比较
  • @halilak - 浮点计算并不精确,就像这里讨论的 how-computer-does-floating-point-arithmetic。您必须接受仍然应该被视为相等的数字之间的一些微小差异。
  • @halilak:FPU 是复杂、多变的设备。即使是相同系列的 C++ 指令也可能产生不同的结果,具体取决于您启动它们时 FPU 的状态。你必须设计你的算法来容忍这些小的浮点错误,否则你会遇到问题。
【解决方案3】:

尝试在您的发布版本中关闭优化...

【讨论】:

  • 确保IDE设置为release,然后右键项目,选择属性。在一般情况下,将整个程序优化设置为否。在 C/C++,优化下,将优化设置为禁用。这只是在黑暗中的一个镜头,但它可能会奏效。
  • 据我了解,这将关闭所有优化,以便调试和发布模式之间没有差异。如果有替代解决方案,我应该尽量避免这种情况。这是一个相当大的项目,我需要尽可能快的速度
  • 在 C# 中,您可以与 double.MinValue 进行比较,如果它们相等,则基本上为零。不确定c++中是否有类似的测试......也许试试double comp = 0; return double==price ? 0 : price;
  • @therealmitchconnors 在 C++ 中是 std::numeric_limits::min().
  • 哇。我越来越喜欢 C#。
猜你喜欢
  • 2023-04-11
  • 2015-01-24
  • 2020-01-15
  • 1970-01-01
  • 2016-05-14
  • 1970-01-01
  • 2011-06-14
  • 2015-03-25
  • 1970-01-01
相关资源
最近更新 更多