整数回绕的正确方法?

A correct way for the integer wrap around?

什么是相对更好/更正确的方法来确保整数值总是在 for 循环中从 从 0 到最大 8 环绕? (我正在使用 32 次迭代,就像这里的例子)我找到了三个选项(A、B 和 C)

示例:

int x = 0;
const int max = 8; // EDIT: Always in the power of two.

for (int i = 0; i < 32; ++i)
{
    // EDIT: "x++;" usage was incorrect here.
    x = i;

//  x = x % max;  // A
//  x &= max - 1; // B
//  x &= ~max;    // C (EDIT: Incorrect, dont use...)

    std::cout << "x: " << x << std::endl;
}

还有其他建议吗?

编辑: 性能至关重要,需要最快的解决方案。 我看到在某些第三方性能关键代码中使用了“x &= ~max”。看起来他们用这个技巧绕了一圈。它是否有效或比其他解决方案更快?

谢谢。

B 和 C 在这种特殊情况下都有效,但仅在 max 恰好是 2 的幂时有效。如果不是,%= 将和其他任何东西一样快。

如果 [0,8) 有效并且 max 保证是 2 的幂,x &= (max-1) 工作并且比第一个更快。不能说C.

对于 int,位掩码 (x &= (max-1);) 和取模 (x %= max;) 解决方案产生不同的程序集,因为它们对负值产生不同的结果。虽然模块解决方案可能更易于阅读,但它可能 运行 比模块解决方案慢。通常你会使用 x %= max; 因为它准确表达了你想做什么,但如果性能很关键,位掩码解决方案值得考虑。

请注意,对于 unsigned int,gcc 将两个解决方案编译为使用单个 and 指令。

神马:https://godbolt.org/z/WAckr7