【问题标题】:Which kind of signed integer division corresponds to bit shift?哪种有符号整数除法对应于位移?
【发布时间】:2020-07-21 16:01:37
【问题描述】:

众所周知的事实是,当整数除以 2 的幂时,优秀的编译器会将其强度降低为位移位。

例如:

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

Clang -O2 将其编译为:

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

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

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

【问题讨论】:

    标签: c bit-manipulation bit-shift integer-division


    【解决方案1】:

    如果执行算术右移,floor 2 的幂是匹配有符号整数右移的最合适的操作(向 -inf 舍入)。

    请注意,有符号整数的右移是实现定义的。它可能是算术右移(由大多数知名编译器实现)或逻辑右移。更多关于这两个操作之间的区别可以找到here

    算术右移示例: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
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-14
    • 1970-01-01
    相关资源
    最近更新 更多