为什么 (a % 256) 与 (a & 0xFF) 不同?

新手上路,请多包涵

我一直认为在执行 (a % 256) 时,优化器自然会使用有效的按位运算,就好像我写了 (a & 0xFF)

在编译器资源管理器 gcc-6.2 (-O3) 上进行测试时:

 // Type your code here, or load an example.
int mod(int num) {
    return num % 256;
}

mod(int):
    mov     edx, edi
    sar     edx, 31
    shr     edx, 24
    lea     eax, [rdi+rdx]
    movzx   eax, al
    sub     eax, edx
    ret

在尝试其他代码时:

 // Type your code here, or load an example.
int mod(int num) {
    return num & 0xFF;
}

mod(int):
    movzx   eax, dil
    ret

好像我完全错过了一些东西。有任何想法吗?

原文由 Elad Weiss 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 777
2 个回答

这是不一样的。试试 num = -79 ,你会从这两个操作中得到不同的结果。 (-79) % 256 = -79 ,而 (-79) & 0xff 是一些正数。

使用 unsigned int ,操作相同,代码可能相同。

PS- 有人评论

它们不应该相同, a % b 被定义为 a - b * floor (a / b)

这不是它在 C、C++、Objective-C 中的定义方式(即问题中的代码将编译的所有语言)。

原文由 gnasher729 发布,翻译遵循 CC BY-SA 3.0 许可协议

由于 C++11,如果 num 为负数,则 num % 256 必须为非正数。

因此位模式将取决于系统上带符号类型的实现:对于负的第一个参数,结果不是提取最低有效 8 位。

如果 num 在您的情况下是 unsigned ,那将是另一回事:这些天我几乎 希望 编译器能够进行您引用的优化。

原文由 Bathsheba 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题