在C中,是否可以将一个被除数除以一个常数并同时得到结果和余数?
我想避免执行2个除法指令,如下例所示:
val=num / 10;
mod=num % 10;
答案 0 :(得分:14)
我不担心指令计数,因为x86指令集将提供idivl
指令,用于计算一条指令中的被除数和余数。任何体面的编译器都会使用此指令。这里的文件http://programminggroundup.blogspot.com/2007/01/appendix-b-common-x86-instructions.html描述了如下指令:
执行无符号分割。划分双字的内容 包含在合并的%edx:%eax寄存器中的值 指定的寄存器或存储位置。 %eax寄存器包含 结果为商,%edx寄存器包含结果 剩余。如果商太大而不适合%eax,则触发a 0型中断。
例如,编译此示例程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int x = 39;
int divisor = 1;
int div = 0;
int rem = 0;
printf("Enter the divisor: ");
scanf("%d", &divisor);
div = x/divisor;
rem = x%divisor;
printf("div = %d, rem = %d\n", div, rem);
}
使用gcc -S -O2(-S保存创建的显示asm列表的临时文件),显示以下行中的除法和mod
div = x/divisor;
rem = x%divisor;
有效地缩减为以下指令:
idivl 28(%esp)
正如您所看到的那样,有一条指令用于执行除法和mod计算。即使删除了C程序中的mod计算,idivl
指令仍然存在。 idivl
之后有mov
的电话:
movl $.LC2, (%esp)
movl %edx, 8(%esp)
movl %eax, 4(%esp)
call printf
这些调用将商和余数复制到堆栈上以调用printf。
有趣的是,除了在函数调用中包装/和%运算符之外,函数div
没有做任何特殊操作。因此,从性能角度来看,它不会通过替换行来提高性能
val=num / 10;
mod=num % 10;
只需拨打div
。
答案 1 :(得分:5)
有div():
div_t result = div(num, 10);
// quotient is result.quot
// remainder is result.rem
答案 2 :(得分:5)
不要浪费你的时间div()
像Nemo说的那样,编译器会很容易地优化分区的使用,然后使用模数运算。编写具有最佳意义的代码,并让计算机删除残留物。
答案 3 :(得分:2)
您始终可以使用div
功能。