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):
Yes, the result is always truncated towards zero. It will round towards the smallest absolute value.
You'll want to do floating point division, and then use the ceiling function, to round up the value to the next integer.
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).
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.
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;
}
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With