5

I am dividing 2 integers and looking to get an integer as a result. I want the right Math.Round() method so when I divide, it always round to the next integer regardless of how. Here are a bunch of examples with expectations below.

int result = (6/4); // = 2
int result = (3/4);  // = 1
int result = (1/4);  // = 1
int result = (8/4);  // = 2
int result = (9/4);  // = 3

What is the correct way of doing this?

leora
  • 188,729
  • 360
  • 878
  • 1,366
  • 2
    Question: Do you care about negative values? For example, using `Math.Ceiling` on `-9d/4d` will give you `-2` and not `-3`. – Chris Sinclair Feb 26 '13 at 22:44
  • [Rounding integer division (instead of truncating)](https://stackoverflow.com/q/2422712/995714) – phuclv Feb 16 '19 at 03:40

5 Answers5

7

Since all the integers in your example are positive, I'll assume that you are not interested in the case where one or both operands are negative or zero.

Math.Round works on floating-point numbers. That is not necessary here.

Dividing two integers gives an integer result. It always rounds down. You want something like this:

int Divide(int numerator, int denominator) {
    return (numerator + denominator - 1) / denominator;
}

For example,for 1/4, we get (1 + 4 - 1) / 4 = 4 / 4 = 1, and for 8/4 we get (8 + 4 - 1) / 4 = 11 / 4 = 2.

There's a very slight possibility of overflow here, so if the numerator is always greater than zero, it's better to use:

int Divide(int numerator, int denominator) {
    return 1 + (numerator - 1) / denominator;
}
Jeffrey Sax
  • 10,253
  • 3
  • 29
  • 40
  • 1
    leora hasn't specified, but this can produce incorrect results for negative integers: `Divide(-9, 4)` results in `-1` (which I believe is incorrect) (also, I think you may have mixed up `denominator` and `numerator`) – Chris Sinclair Feb 26 '13 at 22:49
  • It seems to work. But the names `denominator` and `numerator` ought to be swapped, I believe. – Jeppe Stig Nielsen Feb 26 '13 at 22:50
  • Fixed. Thanks to both of you for pointing it out. I am remarkably good at making that mistake. In my native language, the word for denominator sounds like "numer." – Jeffrey Sax Feb 26 '13 at 22:58
  • This is superior to converting to `float` because it will work in cases where `float` can underflow and through the loss of precision return the wrong answer. I use this technique regularly. – ErikE Feb 26 '13 at 22:59
4

You need to perform division as float/double and use Math.Ceiling:

Math.Ceiling... Returns the smallest integral value that is greater than or equal to the specified double-precision floating-point number.

Sample:

 int result = (int)Math.Ceiling(6/4.0);
 result = (int)Math.Ceiling((double)3/4);
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
1

This is definitely not the method you are looking for...

int mod = 9 % 4;
int result = (9 - mod) / 4) + (mod > 0 ? 1 : 0);

Does not require any casting or usage of the Math class.

Brad M
  • 7,857
  • 1
  • 23
  • 40
  • Jeffrey Sax's method achieves the same effect and to me is more natural. – ErikE Feb 26 '13 at 23:00
  • True, but his method uses internal casting, as well as requires a check to make sure the numerator is not zero. I'm really splitting hairs here... – Brad M Feb 26 '13 at 23:11
  • Why do you have to check whether the numerator is zero? If the division is `0 / 5` for example, you get 0 through `(0 + 4) / 5`. And what internal casting? You're using `int` just the same... – ErikE Feb 27 '13 at 01:04
  • My method doesn't have to check, Jeffrey Sax's method does. I'm not sure how to respond about the casting...I interpret cases such as "int Divide() { return .875; } as casting. – Brad M Feb 27 '13 at 01:19
  • Brad, I think maybe you're confusing the methods... there's no floating point math in [Jeffrey Sax's answer](http://stackoverflow.com/a/15100770/57611). – ErikE Feb 27 '13 at 01:24
0

One of those integers should be a double:

double result = (6d/4); // 1.5  
int rounded = (int)Math.Round(result, MidpointRounding.AwayFromZero);
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
0

The question is posed in a confusing manner, it asks for a ceil while talking about round. For the record, here is an integer round function for positive integers

private static int RoundDivide(int numerator, int denominator) {
    return (numerator + (denominator / 2)) / denominator;
}
WARdd
  • 76
  • 5