I was curious to know how I can round a number to the nearest whole number. For instance, if I had:
int a = 59 / 4;
which would be 14.75 if calculated in floating point; how can I store the result as 15 in "a"?
As written, you're performing integer arithmetic, which automatically just truncates any decimal results.
You'll want to do floating point division, and then use the ceiling function, to round up the value to the next integer.
Truncating division is division where a fractional result is converted to an integer by rounding towards zero. If both operands are ints, then other must not be zero.
The standard idiom for integer rounding up is:
int a = (59 + (4 - 1)) / 4;
You add the divisor minus one to the dividend.
A code that works for any sign in dividend and divisor:
int divRoundClosest(const int n, const int d) { return ((n < 0) ^ (d < 0)) ? ((n - d/2)/d) : ((n + d/2)/d); }
In response to a comment "Why is this actually working?", we can break this apart. First, observe that n/d
would be the quotient, but it is truncated towards zero, not rounded. You get a rounded result if you add half of the denominator to the numerator before dividing, but only if numerator and denominator have the same sign. If the signs differ, you must subtract half of the denominator before dividing. Putting all that together:
(n < 0) is false (zero) if n is non-negative (d < 0) is false (zero) if d is non-negative ((n < 0) ^ (d < 0)) is true if n and d have opposite signs (n + d/2)/d is the rounded quotient when n and d have the same sign (n - d/2)/d is the rounded quotient when n and d have opposite signs
If you prefer a macro:
#define DIV_ROUND_CLOSEST(n, d) ((((n) < 0) ^ ((d) < 0)) ? (((n) - (d)/2)/(d)) : (((n) + (d)/2)/(d)))
The linux kernel macro DIV_ROUND_CLOSEST doesn't work for negative divisors!
EDIT: This will work without overflow:
int divRoundClosest( int A, int B ) { if(A<0) if(B<0) return (A + (-B+1)/2) / B + 1; else return (A + ( B+1)/2) / B - 1; else if(B<0) return (A - (-B+1)/2) / B - 1; else return (A - ( B+1)/2) / B + 1; }
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