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

Posted

技术标签:

【中文标题】哪种有符号整数除法对应于位移?【英文标题】: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 最终都解决了截断除法(商轮趋向于零),而这恰好与算术右移不完全匹配(并且需要降低强度以准确保留语义)。

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

【问题讨论】:

【参考方案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

【讨论】:

换句话说,向负无穷舍入。 @NateEldredge 可能四舍五入到最接近的整数会是更好的措辞。 @AlexLop。不正确的术语是向 -inf en.wikipedia.org/wiki/IEEE_754#Directed_roundings, en.wikipedia.org/wiki/… 舍入

以上是关于哪种有符号整数除法对应于位移?的主要内容,如果未能解决你的问题,请参考以下文章

仅使用位移加法和减法的对数时间整数除法

C中的除法,商和余数的大小符号如何确定

非恢复有符号整数除法后校正

LeetCode第二十九题-整数除法

单片机 怎么用位移的方法实现乘除法

有符号 32 位元素的 AVX __m256i 整数除法