В C, можно ли делить дивиденд на константу и получать результат и остаток в одно и то же время?
Я хочу избежать выполнения инструкций с двумя разделами, как в этом примере:
val=num / 10;
mod=num % 10;
В C, можно ли делить дивиденд на константу и получать результат и остаток в одно и то же время?
Я хочу избежать выполнения инструкций с двумя разделами, как в этом примере:
val=num / 10;
mod=num % 10;
Вы всегда можете использовать функцию div
.
Я бы не беспокоился о подсчете команд, потому что набор команд x86 предоставит команду idivl
, которая вычисляет дивиденды и остаток в одной инструкции. Любой достойный компилятор будет использовать эту инструкцию. Представление здесь http://programminggroundup.blogspot.com/2007/01/appendix-b-common-x86-instructions.html описывает инструкцию следующим образом:
Выполняет беззнаковое деление. Разделяет содержимое двойного слова содержащихся в объединенных регистрах% edx:% eax по значению в регистр или ячейку памяти. Регистр% eax содержит результирующий фактор, а регистр% edx содержит результирующий остаток. Если частное слишком велико, чтобы соответствовать в% eax, оно вызывает прерывания типа 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 сохраняет созданный файл tempory, который показывает листинг asm), показывает, что деление и мода в следующих строках
div = x/divisor;
rem = x%divisor;
эффективно сводится к следующей инструкции:
idivl 28(%esp)
Как вы можете видеть, одна инструкция для выполнения вычисления деления и мод. Инструкция idivl
сохраняется, даже если вычисление мод в программе C будет удалено. После idivl
появляются вызовы mov
:
movl $.LC2, (%esp)
movl %edx, 8(%esp)
movl %eax, 4(%esp)
call printf
Эти вызовы копируют фактор и остаток в стек для вызова printf.
Интересно, что функция div
не делает ничего особенного, кроме обертывания операторов/и% в вызове функции. Поэтому с точки зрения производительности он не улучшит производительность, заменив строки
val=num / 10;
mod=num % 10;
с одним вызовом div
.
Там div():
div_t result = div(num, 10);
// quotient is result.quot
// remainder is result.rem
Не тратьте время на div()
Как и Nemo, компилятор легко оптимизирует использование деления, за которым следует использование модуля в одном. Напиши код, который имеет оптимальный смысл, и пусть компьютер удалит треск.