神秘的浮点例外

时间:2013-02-05 04:59:47

标签: c++ floating-point-exceptions

  

可能重复:
  Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)

我的朋友和我正在弄乱我们想到的最糟糕的循环(所以不要告诉我这是可怕的代码,因为它应该是!)。

我的朋友想出了这个循环:

for (int i = 0; i++ & ++i % (++i % 2) ? --i : i++; i++);

它看起来没问题,但由于浮点异常,它甚至第一次都无法进入。 所以我的第一个想法是模数除以0.但它似乎没有,因为如果你这样做,它运行良好:

for (int i = 0; i < 100; i++) {
    i++ & ++i % (++i % 2);
}

但这不会:

for (int i = 0; i < 100; i++) {
    i++ & ++i % (++i % 2) ? --i : i++;
}

但它变得陌生。第一种情况运行良好,第二种情况不会:

for (int i = 0; i < 100; i++) {
    i++ & ++i % (++i % 2) ? 0 : 1;
}

for (int i = 0; i < 100; i++) {
    i++ & ++i % (++i % 2) ? 1 : 0; // 1 and 0 switched
}

所以到现在为止我真的很困惑,但它又变得更奇怪了。如果你将? 0 : 1(运行正常)的情况放入if语句,它会再次抛出浮点异常:

for (int i = 0; i < 100; i++) {
    if (i++ & ++i % (++i % 2) ? 0 : 1);
}

我完全迷失了。有人知道这里发生了什么吗?

2 个答案:

答案 0 :(得分:3)

i++ & ++i出错了。 &运算符不对其操作数进行排序,因此在两侧都加上一个增量会导致未定义的行为。

顺便说一下,它可能是零除外,但不一定来自FPU。

答案 1 :(得分:1)

通常,在C和C ++中的单个表达式中混合使用此类多个增量操作是一个坏主意,因为它通常会导致未定义的行为。对于未定义的行为,让事物神秘地改变行为并不令人惊讶。

另一方面,Java为所有算术和逻辑运算提供了严格的规范(非fpstrict表达式中的浮点指数精度除外)。您可以将所有这些放入Java中(忽略int不再是有效的布尔表达式这一事实)并让它们给出一致的答案,尽管它可能不是您所期望的。

相关问题