我想保证无符号值小于9而没有分支且没有模运算符(要求): 模数为
的算法x = x % 9
带循环/分支的算法:
while(x >= 9)
{
x -= 9;
}
在特殊情况下(如阈值== 8),可以通过以下方式实现:
x = x & 0x07u;
阈值是否有可能等于9?
答案 0 :(得分:3)
我不明白为什么要替换模运算符。 如果是效率,请考虑以下两个示例:
int main(int argc, char* argv[]) {
int x = argc % 9;
return x;
}
和
int main(int argc, char* argv[]) {
int x = argc - (argc / 9) * 9;
return x;
}
对于这两个实现,gcc -g -O3
正在生成相同的程序集(我在x86上使用gcc 4.8.1):
main:
movl %edi, %eax # argc, tmp71
movl $954437177, %edx #, tmp65
imull %edx # tmp65
movl %edi, %eax # argc, tmp67
sarl $31, %eax #, tmp67
sarl %edx # x
subl %eax, %edx # tmp67, x
leal (%rdx,%rdx,8), %eax #, tmp70
subl %eax, %edi # tmp70, x
movl %edi, %eax # x,
ret
结论:不关心效率(在这种情况下和大多数情况下),让编译器这样做。
顺便说一句:954437177
是(2^33 + 1) / 9
答案 1 :(得分:3)
这就是编译器的用途。输入生成所需输出的代码,编译器生成最有效的程序集以生成该输出。
实际上,C语言是根据抽象机器定义的,其中只定义了其可观察行为。
对于该计划:
int main(int x, char **z)
{
x = x % 9;
return x;
}
gcc 5.2 -O3生成:
main:
movl %edi, %eax
movl $954437177, %edx
imull %edx
movl %edx, %eax
movl %edi, %edx
sarl %eax
sarl $31, %edx
subl %edx, %eax
leal (%rax,%rax,8), %eax
subl %eax, %edi
movl %edi, %eax
ret
我不确定这是什么,但954437177是0b00111000111000111000111000111001
。如果你有兴趣,或许你可以将这个程序集与你手工提出的任何其他东西进行对比。
答案 2 :(得分:1)
你可以使用这个方法,没有循环,分支或模数:
#include <stdio.h>
#include <stdint.h>
int main(void)
{
uint8_t x = 15;
printf("%u", x - (x/9)*9);
return 0;
}
节目输出:
6