views:

276

answers:

9

OK - I'm almost embarrassed posting this here (and I will delete if anyone votes to close) as it seems like a basic question.

Is this the correct way to round up to a multiple of a number in C++?

I know there are other questions related to this but I am specficially interested to know what is the best way to do this in C++:

int roundUp(int numToRound, int multiple)
{
 if(multiple == 0)
 {
  return numToRound;
 }

 int roundDown = ( (int) (numToRound) / multiple) * multiple;
 int roundUp = roundDown + multiple; 
 int roundCalc = roundUp;
 return (roundCalc);
}

Update: Sorry I probably didn't make intention clear. Here are some examples:

roundUp(7, 100)
//return 100

roundUp(117, 100)
//return 200

roundUp(477, 100)
//return 500

roundUp(1077, 100)
//return 1100

roundUp(52, 20)
//return 60

roundUp(74, 30)
//return 90

EDIT: Thanks for all the replies. Here is what I went for:

int roundUp(int numToRound, int multiple)  
{  
 if(multiple == 0)  
 {  
  return numToRound;  
 }  

 int remainder = numToRound % multiple; 
 if (remainder == 0)
  {
    return numToRound; 
  }

 return numToRound + multiple - remainder; 
}  
+1  A: 

Probably safer to cast to floats and use ceil() - unless you know that the int division is going to produce the correct result.

Martin Beckett
+1  A: 
int noOfMultiples = int((numToRound / multiple)+0.5);
return noOfMultiples*multiple

C++ rounds each number down,so if you add 0.5 (if its 1.5 it will be 2) but 1.49 will be 1.99 therefore 1.

EDIT - Sorry didn't see you wanted to round up, i would suggest using a ceil() method instead of the +0.5

LnDCobra
+2  A: 

First off, your error condition (multiple == 0) should probably have a return value. What? I don't know. Maybe you want to throw an exception, that's up to you. But, returning nothing is dangerous.

Second, you should check that numToRound isn't already a multiple. Otherwise, when you add multiple to roundDown, you'll get the wrong answer.

Thirdly, your casts are wrong. You cast numToRound to an integer, but it's already an integer. You need to cast to to double before the division, and back to int after the multiplication.

Lastly, what do you want for negative numbers? Rounding "up" can mean rounding to zero (rounding in the same direction as positive numbers), or away from zero (a "larger" negative number). Or, maybe you don't care.

Here's a version with the first three fixes, but I don't deal with the negative issue:

int roundUp(int numToRound, int multiple)
{
 if(multiple == 0)
 {
  return 0;
 }
 else if(numToRound % multiple == 0)
 {
  return numToRound
 }

 int roundDown = (int) (( (double) numToRound / multiple ) * multiple);
 int roundUp = roundDown + multiple; 
 int roundCalc = roundUp;
 return (roundCalc);
}
Mike Caron
-1: Conversion to double is bizarre and unnecessary.
Peter Ruderman
+1 For numToRound % multiple == 0. Good catch
David Relihan
@Peter Is it? I assumed that `int / int` would return an int, which is not what we wanted.
Mike Caron
int / int does indeed return an int, but that's precisely what you want. For example, numToRound = 7, multiple = 3. 7 / 3 = 2.
Peter Ruderman
+1  A: 

well for one thing, since i dont really understand what you want to do, the lines

int roundUp = roundDown + multiple;
int roundCalc = roundUp;
return (roundCalc); 

could definitely be shortened to

int roundUp = roundDown + multiple;
return roundUp;
Jesse Naugher
+6  A: 

This is a generalization of the problem of "how do I find out how many bytes n bits will take? (A: (n bits + 7) / 8).

int RoundUp(int n, int roundTo)
{
    // fails on negative?  What does that mean?
    if (roundTo == 0) return 0;
    return ((n + roundTo - 1) / roundTo) * roundTo; // edit - fixed error
}
plinth
This doesn't round up to the next multiple of a number.
aaaa bbbb
Fixed that - thanks.
plinth
+5  A: 

This works for positive numbers, not sure about negative. It only uses integer math.

int roundUp(int numToRound, int multiple) 
{ 
 if(multiple == 0) 
 { 
  return numToRound; 
 } 

 int remainder = numToRound % multiple;
 if (remainder == 0)
  return numToRound;
 return numToRound + multiple - remainder;
} 
Mark Ransom
+1 In my opinion, definately the nicest and most readable solution.
David Relihan
+2  A: 
int roundUp(int numToRound, int multiple)
{
 if(multiple == 0)
 {
  return 0;
 }
 return ((numToRound - 1) / multiple + 1) * multiple;  
}

And no need to mess around with conditions

doron
A: 
  float roundUp( float number, float fixedBase ) {
     if (fixedBase != 0 && number != 0) {
        float sign = number>0?1:-1;
        number*=sign;
        number/=fixedBase;
        int fixedPoint = (int)ceil(number);
        number = fixedPoint*fixedBase;
        number*=sign;
     }
     return number;
  }

This works for any float number or base (e.g. you can round -4 to the nearest 6.75). In essence it is converting to fixed point, rounding there, then converting back. It handles negatives by rounding AWAY from 0. It also handles a negative round to value by essentially turning the function into roundDown.

An int specific version looks like:

  int roundUp( int number, int fixedBase ) {
     if (fixedBase != 0 && number != 0) {
        int sign = number>0?1:-1;
        int baseSign=fixedBase>0?1:0;
        number*=sign;
        int fixedPoint = (number+baseSign*(fixedBase-1))/fixedBase;
        number = fixedPoint*fixedBase;
        number*=sign;
     }
     return number;
  }

Which is more or less plinth's answer, with the added negative input support.

Dolphin