【问题标题】:When arithmetic operations overflow do they result in a deterministic figure?当算术运算溢出时,它们会产生确定性的数字吗?
【发布时间】:2015-10-15 17:38:42
【问题描述】:

给定相同的两个输入和一个会导致溢出的算术运算,溢出的结果是否总是相同的?

仅作为背景,我正在一个 Visual Studio C++ 项目中工作,其中一些时髦的小浮点数字来自一些高斯,通过 calllib 从 Matlab 传递过来,这给了我看起来像溢出的东西,其中指数跳转到巨大的数字这个矩阵的某些地方。问题是当我重新运行我的代码时,我仍然会在不同的地方出现溢出,这让我想知道溢出行为有多稳定和确定性。

【问题讨论】:

  • 从语言的角度来看,有符号整数溢出会导致未定义的行为。因此,特定实现可以提供确定性行为。但是,一个不同的实现可能会把兔子从帽子里拉出来。
  • 从语言的角度来看非常好,我会在一天结束时做一些实验,看看 Visual c++ 2010 对 floatmax*floatmax 和 intmax+intmax 的表现如何。
  • 你可以责怪你的编译器或机器,但这永远不会让你到任何地方。显然,真正的问题是数学模型完全被破坏并产生了荒谬的结果。
  • 您询问“算术溢出”并将您的问题标记为“浮点”和“整数溢出”?下定决心,然后问。
  • @PascalCuoq 抱歉,您可能没有意识到这里使用的标签有限。没有“算术溢出”标签,也没有“浮点溢出”标签,并且“溢出”仅与某些 CSS 内容相关。我正在使用浮点值,因此使用了浮点标记。如果您有代表随意制作一些标签,如果您觉得我的标签弄乱了使用过的标签,我会很容易地使用它们。

标签: c++ floating-point integer-overflow arithmetic-expressions


【解决方案1】:

无法详尽地回答这个问题,但我想我会演示我制作的小例子。 下面是 Visual Studio 2010 中制作的玩具示例

#include <climits>
#include <cfloat>

int _tmain( int argc , _TCHAR* argv[] )
{
    // IS OVERFLOW DETERMINISTIC
    int a = INT_MAX;
    int b = a + 10;

    std::cout <<"a="    << a << std::endl;
    std::cout <<"b=a+1="<< b << std::endl;

    double d1 = DBL_MAX ;
    double d2 = 2*d1;
    std::cout <<"d1="     << d1 << std::endl;
    std::cout <<"d2=2*d2="<< d2 << std::endl;

    return 0;
}

下面是对应用程序的一些调用...

C:\Users\me>cd/d C:\Users\me\Documents\Visual Studio 2010\Projects\TestSolution\Debug

C:\Users\me\Documents\Visual Studio 2010\Projects\TestSolution\Debug>TestSolution.exe
a=2147483647
b=a+10=-2147483639
d1=1.79769e+308
d2=2*d2=1.#INF

C:\Users\me\Documents\Visual Studio 2010\Projects\TestSolution\Debug>TestSolution.exe
a=2147483647
b=a+10=-2147483639
d1=1.79769e+308
d2=2*d2=1.#INF

C:\Users\me\Documents\Visual Studio 2010\Projects\TestSolution\Debug>TestSolution.exe
a=2147483647
b=a+10=-2147483639
d1=1.79769e+308
d2=2*d2=1.#INF

C:\Users\me\Documents\Visual Studio 2010\Projects\TestSolution\Debug>TestSolution.exe
a=2147483647
b=a+10=-2147483639
d1=1.79769e+308
d2=2*d2=1.#INF

【讨论】:

    【解决方案2】:

    有符号整数的溢出是未定义的行为;任何事情都可能发生,甚至是您的程序崩溃之类的事情。

    实际上,当编译器构建你的程序时,它可能决定了一些确定性的行为......

    ...但是,您真正需要担心的是,如果您编辑程序并再次编译它,或者您更改构建选项,编译器将决定某些 other 确定性行为并再次编译它,或者如果您升级到较新的版本并再次编译它,或者如果您尝试使用不同的编译器,或者您在两个不同的地方使用相同的函数并且它决定为每个选择不同的行为,并且以此类推。

    【讨论】:

    • 这确实是一个敏锐的微妙之处!以前从未考虑过这种可变性。感谢分享!事实证明,我的不确定性与模型或溢出无关,但似乎与 Matlab 和 C++ 之间的联系有关。使用一个新的 Matlab 实例,结果是正确的,我再次运行 matlab 脚本并得到时髦的结果,然后又得到更多不同的结果。关闭matlab重新打开重复,同样的故事。我对这里的调试感到非常困惑,但考虑行为,或者更确切地说,当我在问题空间中徘徊时,溢出的未定义行为很有趣。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-23
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多