Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

signed integer division with rounding in C

I'd like to calculate x/y where x and y are both signed integers, and get a result rounded to the nearest integer. Specifically, I'd like a function rquotient(x, y) using integer-only arithmetic such that:

ASSERT(rquotient(59, 4) == 15);
ASSERT(rquotient(59, -4) == -15);
ASSERT(rquotient(-59, 4) == -15);
ASSERT(rquotient(-59, -4) == 15);

ASSERT(rquotient(57, 4) == 14);
ASSERT(rquotient(57, -4) == -14);
ASSERT(rquotient(-57, 4) == -14);
ASSERT(rquotient(-57, -4) == 14);

I've looked to S.O. for a solution and found the following (each with their own shortcoming):

  • Rounding integer division (instead of truncating) (round up only)
  • Integer division with rounding (positive x and y only)
  • Round with integer division (positive x and y only)
  • integer division, rounding (positive y only, but a good suggestion in the comments)
  • Integer division rounding with negatives in C++ (question about the standard, not a solution)
like image 691
fearless_fool Avatar asked Jan 31 '20 18:01

fearless_fool


People also ask

Does integer division round down in C?

Yes, the result is always truncated towards zero. It will round towards the smallest absolute value.

How do you round up the result of integer division?

You'll want to do floating point division, and then use the ceiling function, to round up the value to the next integer.

Do integers round Up in C?

In the C Programming Language, the ceil function returns the smallest integer that is greater than or equal to x (ie: rounds up the nearest integer).

What is signed integer division?

Rules for Dividing Signed NumbersTo divide two real numbers that have the same sign, divide their absolute values. The quotient is positive. (+)(+)=(+)(−)(−)=(+) To divide two real numbers that have opposite signs, divide their absolute values. The quotient is negative.


2 Answers

If you know x and y both to be positive:

int rquotient_uu(unsigned int x, unsigned int y) {
  return (x + y/2) / y;
}

If you know y to be positive:

int rquotient_su(int x, unsigned int y) {
  if (x > 0) {
    return (x + y/2) / y;
  } else {
    return (x - y/2) / y;
  }
}

If both are signed:

int rquotient_ss(int x, int y) {
  if ((x ^ y) >= 0) {            // beware of operator precedence
    return (x + y/2) / y;        // signs match, positive quotient
  } else {
    return (x - y/2) / y;        // signs differ, negative quotient
  }
}

And if you really want to baffle your future self or are addicted to code golf, please resist the urge to write it this way: ;)

int rquotient_ss(int x, int y) {
  return (x + (((x^y)>=0)?y:-y)/2)/y;
}
like image 125
fearless_fool Avatar answered Sep 30 '22 04:09

fearless_fool


A simple solution would be to use round and double:

#include <math.h>

int rquotient(int const x, int const y) {
    return (int)round((double)x / y);
}
like image 38
Ayxan Haqverdili Avatar answered Sep 30 '22 04:09

Ayxan Haqverdili