c - 哪种有符号整数除法对应于位移?
问题描述
一个熟悉的事实是,在将整数除以 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 最终解决了截断除法(商轮趋向零),而这恰好与算术右移不完全匹配(并且需要降低强度以准确保留语义)。
哪种有符号整数除法会与算术右移完全匹配?
解决方案
在执行算术右移的情况下floor
,2 的幂是匹配有符号整数右移的最合适的操作(向-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
推荐阅读
- r - R. How to create a new column, returning i based on another column in R
- java - Streams and obtaining and printing out a value from a custom class
- javascript - Why can't you swap the arrays of a 2D array by reference?
- mysql - 加密已经在 mysql 表中的数据
- cplex - Word generation in Cplex
- jquery - AngularJS ng-submit 在移动设备上不起作用
- amazon-web-services - 在 CentOS7 中 - 没有可用的软件包 aws-cfn-bootstrap
- javascript - 直接将数组作为参数传递时,数组对象属性为空
- angular - Angular : ngFor items and append a char for all items except the last item
- html - Bootstrap 4 Navbar Flex 打破品牌中心