哪种有符号整数除法对应位移位?

Which kind of signed integer division corresponds to bit shift?

众所周知,将整数除以 2 的幂时,好的编译器会将其强度归约为位移。

例如:

int main(int argc, char **argv) {
    return argc/2;
}

Clang -O2 将其编译为:

movl    %ecx, %eax
shrl    , %eax
addl    %ecx, %eax
sarl    %eax
retq

值得注意的是,虽然这个指令序列比实际的除法指令快得多,但并非人们希望的只是一个位移位。大概是因为典型的 CPU 和 C 最终选择了截断除法(商向零舍入),而这恰好与算术右移不完全匹配(并且需要强度降低以准确保留语义)。

哪种有符号整数除法与算术右移完全匹配?

如果执行算术右移,floor乘以2的幂是最合适的运算,它匹配有符号整数右移(向[=23=舍入) ]-inf).

请注意,有符号整数的右移是实现定义的。它可能是算术右移(由大多数知名编译器实现)或逻辑右移。有关这两种操作之间差异的更多信息,请参见 .

算术右移示例:https://godbolt.org/z/zhhfbc

#include <stdio.h>
#include <math.h>

int main(void)
{
    int val1 = 7;
    int val2 = -7;
    
    printf("Value1 = %.1lf\n", floor(val1/2.0));
    printf("Value2 = %.1lf\n", floor(val2/2.0));

    printf("Value1 = %d\n", val1 >> 1);
    printf("Value2 = %d\n", val2 >> 1);  

    return 0;
}

输出为:

Value1 = 3.0

Value2 = -4.0

Value1 = 3

Value2 = -4