Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Divide without losing remainder

Tags:

c

In C, is it possible to divide a dividend by a constant and get the result and the remainder at the same time?

I want to avoid execution of 2 division instructions, as in this example:

val=num / 10;
mod=num % 10;
like image 407
Nulik Avatar asked Oct 30 '11 03:10

Nulik


People also ask

What is the rule for remainder?

Properties of Remainder:The remainder is always less than the divisor. If the remainder is greater than the divisor, it means that the division is incomplete. It can be greater than or lesser than the quotient. For example; when 41 is divided by 7, the quotient is 5 and the remainder is 6.

How do you know if a division has a remainder?

When a math problem has a remainder, it just means that there is a number left over after the division is done. To check your answer, just multiply your quotient and divisor and add your remainder.

What is remainder in divisible?

The Remainder is the value left after the division. If a number (dividend) is not completely divisible by another number (divisor) then we are left with a value once the division is done. This value is called the remainder. For example, 10 is not exactly divided by 3.


1 Answers

I wouldn't worry about the instruction count because the x86 instruction set will provide a idivl instruction that computes the dividend and remainder in one instruction. Any decent compiler will make use of this instruction. The documenation here http://programminggroundup.blogspot.com/2007/01/appendix-b-common-x86-instructions.html describes the instruction as follows:

Performs unsigned division. Divides the contents of the double-word contained in the combined %edx:%eax registers by the value in the register or memory location specified. The %eax register contains the resulting quotient, and the %edx register contains the resulting remainder. If the quotient is too large to fit in %eax, it triggers a type 0 interrupt.

For example, compiling this sample program:

#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);
}

With gcc -S -O2 (-S saves the tempory file created that shows the asm listing), shows that the division and mod in the following lines

div = x/divisor;
rem = x%divisor;

is effectively reduced to the following instruction:

idivl   28(%esp)

As you can see theres one instruction to perform the division and mod calculation. The idivl instruction remains even if the mod calculation in the C program is removed. After the idivl there are calls to mov:

movl    $.LC2, (%esp)
movl    %edx, 8(%esp)
movl    %eax, 4(%esp)
call    printf

These calls copy the quotient and the remainder onto the stack for the call to printf.

Update

Interestingly the function div doesn't do anything special other than wrap the / and % operators in a function call. Therefore, from a performance perspective, it will not improve the performance by replacing the lines

 val=num / 10;       
 mod=num % 10;

with a single call to div.

like image 112
sashang Avatar answered Sep 19 '22 12:09

sashang