Rounding up to the nearest multiple of a number
Asked Answered
T

32

214

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
Transience answered 4/8, 2010 at 15:19 Comment(8)
You have an error in your logic - let's say I want to round 4 up to the nearest multiple of 2. roundDown = (4/2) * 2 = 4; roundUp = 4 + 2; so roundCalc = 6. I'm assuming that you would want to return 4 in that case.Whiffletree
this does not work for roundUp(30,30). It gives 60 as answer, it should still give 30 as answer..Micrococcus
@bsobaid: Check out my answer at the bottom. It's slightly simpler than other solutions here, although those should work tooCoagulant
@NiklasB. it's not at the bottom anymore, +1 from me - although it's identical to plinth's answer. I've used that formula 100 times before, don't know why I didn't think of it the day I left my answer.Acidhead
@MarkRansom: Oh, I actually carefully checked the other answers to look whether it's already there but seem to have missed it. In that case I'm gonna delete it, no need to resurrect this old thread even more. Also xlq's solution is even better because it doesn't need the multiplication :)Coagulant
Is the function expected to treat 0 as a valid value of multiple? If so, what is the expected answer?Ation
Your test cases are conspicuously missing examples involving negative numbers, cases where the division is exact, cases where the division is nearly exact, and cases where the numbers are very near the limits of the range of int.Emboly
Robben_Ford_Fan_boy, The edit with the answer you went for should be removed. If it differs from answers given you can post your own answer. As it stand, that answer has problems that should be addressed in the answer section.Nichollenicholls
A
195

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;
}

Edit: Here's a version that works with negative numbers, if by "up" you mean a result that's always >= the input.

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

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

    if (numToRound < 0)
        return -(abs(numToRound) - remainder);
    else
        return numToRound + multiple - remainder;
}
Acidhead answered 4/8, 2010 at 15:44 Comment(12)
+1 In my opinion, definately the nicest and most readable solution.Transience
Add if(number<0){ multiple = multiple*(-1); } at the start to round negative numbers in the right directionBarathea
@Josh: Why using multiplication? if(number<0) multiple = -multiple is easier.Georgiegeorgina
this does not work for roundUp(30,30). It gives 60 as answer, it should still give 30 as answer.Micrococcus
@Micrococcus impossible. The if (remainder == 0) test should take care of that case. It works for me: ideone.com/Waol7BAcidhead
@bsobaid, you might get that result if you had a typo = instead of == in that if statement.Acidhead
As far as I can tell, this works for negative numbers also as is. no need to if (number < 0) multiple = -multiple. I tried RoundUp(-100087,100), it returned me -100007 instead of -100009, which is the correct answer. did I miss anything?Micrococcus
@Micrococcus Using the code in the answer as of 2014-03-14, roundUp(-100087,100) returns -99900. Neither -100007 nor -100009 could possibly be correct, since neither is a multiple of 100. On the other hand, this highly-accepted answer is also incorrect, because the correct answer is -1000000, which is the smallest multiple of 100 that's greater than or equal to -100087. (It would be correct if int arguments were replaced by unsigned int.)Czarina
The reason it's not correct is that the % operator, which called the modulo operator, is not actually a modulo operator, but rather the remainder operator. These are identical when the dividend is positive, but not otherwise. Modular arithmetic conventionally uses representatives 0 .. n-1. If the dividend is negative, however, the remainder is also negative, and that's not the conventional representative. The remainder is, however, congruent to modulo result and differs from it by exactly the dividend, which is why the example given above is off by exactly 100.Czarina
@Czarina I thought I was pretty explicit at the start that this code couldn't be trusted for negative numbers. To be honest I never tried it. I can't think of a way to fix it that wouldn't destroy the simplicity and straightforwardness that made this answer so popular. The suggestion in the comments above to invert multiple converts this from roundUp to roundAwayFromZero; some people might find that useful but it's not the original question.Acidhead
abs(INT_MIN) is undefined behavior.Nichollenicholls
I think this is what you want: n < 0 ? -m * ceil(-n / m) : m * ceil(n / m). Or to get the closestMultiple : round(n / m) * mMicrodont
F
180

Without conditions:

int roundUp(int numToRound, int multiple) 
{
    assert(multiple);
    return ((numToRound + multiple - 1) / multiple) * multiple;
}

This works like rounding away from zero for negative numbers


Version that works also for negative numbers:

int roundUp(int numToRound, int multiple) 
{
    assert(multiple);
    int isPositive = (int)(numToRound >= 0);
    return ((numToRound + isPositive * (multiple - 1)) / multiple) * multiple;
}

Tests


If multiple is a power of 2 (faster in ~3.7 times)

int roundUp(int numToRound, int multiple) 
{
    assert(multiple && ((multiple & (multiple - 1)) == 0));
    return (numToRound + multiple - 1) & -multiple;
}

Tests

Food answered 8/2, 2012 at 13:20 Comment(10)
+1 for the power of 2 version. Very useful as it totally avoids the cost of multiplications, divisions or modulo.Quevedo
Are you sure that these algorithms have no preconditions? What about negative numbers? The behaviour seems to be undefined in pre-C++11.Candlepin
> What about negative numbers? As described, this works for negative numbers like rounding away from zero.Food
I read "rounding up" as meaning rounding towards positive infinity, not rounding away from zero.Emboly
I know, but most people are only interested in positive numbersFood
+1 because it's correct and requires no special casing (and no missed branch predictions) when numToRound is already a multiple. I'm not a fan of the special case for powers of two because I don't like mixing arithmetic and bitwise operators in the same expression.Sparling
@Hurkyl I added a version for negative numbersFood
Note that & ~(x - 1) is the same as & -x for two's complement arithmetic.Comradery
Not 100% robust: fails if numToRound + multiple - 1 > MAX_INT, though, true answer may be under MAX_INT.Oxbridge
Can someone give a mathematical proof for the case of power-of-2?Unwarrantable
Q
47

This works when factor will always be positive:

int round_up(int num, int factor)
{
    return num + factor - 1 - (num + factor - 1) % factor;
}

Edit: This returns round_up(0,100)=100. Please see Paul's comment below for a solution that returns round_up(0,100)=0.

Quarters answered 1/11, 2010 at 22:41 Comment(12)
Looks to be the shortest case that handles the 'already-a-multiple' case.Demonstrative
Best solution in terms of number of costly operations. It only uses a single divison and no multiplicationCoagulant
You need to prevent a division by zero; if factor==0 you'll get an exception. I believe this one also fails when factor is negative.Cloying
Handling a factor of zero in a function like this seems like a basic layering error. It should be handled at a higher level, either an input sanitizer or exception handler. (Being positive-only is important to know though.)Hoboken
round_up(0, 100) == 100 instead of 0 as in the accepted answerMesothelium
And the compiler is smart enough to turn that division into shift if factor is a power of two (and in a few other cases). Probably a good idea to force inlining though.Vaso
Shouldn't it be num + factor - 1 - (num + factor - 1) % factor?Whimsey
num - 1 - (num - 1) % factor + factor does the same calculation without the risk of integer overflow.Emboly
@Paul's version does handle num == 0 as expectedHalvah
@Paul's version is also faster if implemented as int a = num + factor - 1; return a - a%factor;Vergeboard
{--num; return num - (num%factor) + factor; }Arthro
@Hurkyl num - 1 - (num - 1) % factor + factor overflows when num == INT_MINNichollenicholls
C
26

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
}
Chalcis answered 4/8, 2010 at 15:30 Comment(5)
This doesn't round up to the next multiple of a number.Onfre
I like this solution because if roundTo will be a power of 2, you can eliminate the / and * and end up with nothing but cheap operations (x = roundTo - 1; return (n+x)&~x;)Frippery
@Trejkaz nope. It should be (x = roundTo - 1; return (n+x)&~roundTo;) as in my answerFood
@Food that produces the wrong result for me, but if I correct it to say ~x instead of ~roundTo, I get the expected result. On Java 8 anyway.Frippery
@KindDragon: The AND mask needs to be 0xFFF...000, not 0xFFF7FFF or something, so you want either 2's complement negation (-: minus) on a power of 2, or bit-flip on one less than a power of 2 (one's complement inverse, ~: tilde not minus). So (n+x) & ~x or (n-roundTo+1) & -roundTo.Fluorine
C
16
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

Chorea answered 4/8, 2010 at 15:58 Comment(0)
A
16

This is the modern c++ approach using a template function which is working for float, double, long, int and short (but not for long long, and long double because of the used double values).

#include <cmath>
#include <iostream>

template<typename T>
T roundMultiple( T value, T multiple )
{
    if (multiple == 0) return value;
    return static_cast<T>(std::round(static_cast<double>(value)/static_cast<double>(multiple))*static_cast<double>(multiple));
}

int main()
{
    std::cout << roundMultiple(39298.0, 100.0) << std::endl;
    std::cout << roundMultiple(20930.0f, 1000.0f) << std::endl;
    std::cout << roundMultiple(287399, 10) << std::endl;
}

But you can easily add support for long long and long double with template specialisation as shown below:

template<>
long double roundMultiple<long double>( long double value, long double multiple)
{
    if (multiple == 0.0l) return value;
    return std::round(value/multiple)*multiple;
}

template<>
long long roundMultiple<long long>( long long value, long long multiple)
{
    if (multiple == 0.0l) return value;
    return static_cast<long long>(std::round(static_cast<long double>(value)/static_cast<long double>(multiple))*static_cast<long double>(multiple));
}

To create functions to round up, use std::ceil and to always round down use std::floor. My example from above is rounding using std::round.

Create the "round up" or better known as "round ceiling" template function as shown below:

template<typename T>
T roundCeilMultiple( T value, T multiple )
{
    if (multiple == 0) return value;
    return static_cast<T>(std::ceil(static_cast<double>(value)/static_cast<double>(multiple))*static_cast<double>(multiple));
}

Create the "round down" or better known as "round floor" template function as shown below:

template<typename T>
T roundFloorMultiple( T value, T multiple )
{
    if (multiple == 0) return value;
    return static_cast<T>(std::floor(static_cast<double>(value)/static_cast<double>(multiple))*static_cast<double>(multiple));
}
Addend answered 12/3, 2014 at 10:53 Comment(4)
plus 1, though some people might find it more resonable to return 0 when mulitple == 0Agitato
Beware, because converting int64_t to double can be lossy, so it's not quite as type-generic as it may appear.Sparling
@AdrianMcCarthy Yes you have to create correct template specialisations as shown above. As you can see, I implement two additional functions for long long and long double. The same has to be done for the other two functions obviously.Addend
I think this is by far the slowest of all but it wouldn't have to be. All you need to do is to std::enable_if_t and do two branches for integers and floats. You could also make a better use of the numeric_limits and see if the mantissa is big enough to actually fit the value. That would add to safety.Dinerman
I
12

For anyone looking for a short and sweet answer. This is what I used. No accounting for negatives.

n - (n % r)

That will return the previous factor.

(n + r) - (n % r)

Will return the next. Hope this helps someone. :)

Injure answered 17/7, 2013 at 11:14 Comment(2)
The % operator is implementation dependent for negative numbers -- so may get different answers in this case.Overburden
I think it's important to note that this will return the next multiple even if the number already is a multiple. To avoid that, one must check n % r for zero first.Somnus
R
9
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.

Raimundo answered 4/8, 2010 at 21:16 Comment(2)
I have tested float roundUp code with double, it works for me. Really solves my issue.Telly
What about double round(double value, double multiple) { double sign = value; multiple = std::copysign(multiple, 1.0); value = std::copysign(value, 1.0); return std::copysign(multiple * std::ceil(value / multiple), sign); } Or swap ceil for round to get rounding.Farrah
I
5

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);
}
Iraidairan answered 4/8, 2010 at 15:24 Comment(2)
@Peter Is it? I assumed that int / int would return an int, which is not what we wanted.Iraidairan
int / int does indeed return an int, but that's precisely what you want. For example, numToRound = 7, multiple = 3. 7 / 3 = 2.Fantom
A
4

Round to Power of Two:

Just in case anyone needs a solution for positive numbers rounded to the nearest multiple of a power of two (because that's how I ended up here):

// number: the number to be rounded (ex: 5, 123, 98345, etc.)
// pow2:   the power to be rounded to (ex: to round to 16, use '4')
int roundPow2 (int number, int pow2) {
    pow2--;                     // because (2 exp x) == (1 << (x -1))
    pow2 = 0x01 << pow2;

    pow2--;                     // because for any
                                //
                                // (x = 2 exp x)
                                //
                                // subtracting one will
                                // yield a field of ones
                                // which we can use in a
                                // bitwise OR

    number--;                   // yield a similar field for
                                // bitwise OR
    number = number | pow2;
    number++;                   // restore value by adding one back

    return number;
}

The input number will stay the same if it is already a multiple.

Here is the x86_64 output that GCC gives with -O2 or -Os (9Sep2013 Build - godbolt GCC online):

roundPow2(int, int):
    lea ecx, [rsi-1]
    mov eax, 1
    sub edi, 1
    sal eax, cl
    sub eax, 1
    or  eax, edi
    add eax, 1
    ret

Each C line of code corresponds perfectly with its line in the assembly: http://goo.gl/DZigfX

Each of those instructions are extremely fast, so the function is extremely fast too. Since the code is so small and quick, it might be useful to inline the function when using it.


Credit:

Abdominal answered 30/4, 2014 at 10:1 Comment(1)
int roundUpPow2(int num, int pow2) { return num + (pow2 - 1) & ~(pow2 - 1); } is about 30% faster, and easier to use (you pass 16 not 4 to round up to the next multiple of 16.Ascension
D
4

I'm using:

template <class _Ty>
inline _Ty n_Align_Up(_Ty n_x, _Ty n_alignment)
{
    assert(n_alignment > 0);
    //n_x += (n_x >= 0)? n_alignment - 1 : 1 - n_alignment; // causes to round away from zero (greatest absolute value)
    n_x += (n_x >= 0)? n_alignment - 1 : -1; // causes to round up (towards positive infinity)
    //n_x += (_Ty(-(n_x >= 0)) & n_alignment) - 1; // the same as above, avoids branch and integer multiplication
    //n_x += n_alignment - 1; // only works for positive numbers (fastest)
    return n_x - n_x % n_alignment; // rounds negative towards zero
}

and for powers of two:

template <class _Ty>
bool b_Is_POT(_Ty n_x)
{
    return !(n_x & (n_x - 1));
}

template <class _Ty>
inline _Ty n_Align_Up_POT(_Ty n_x, _Ty n_pot_alignment)
{
    assert(n_pot_alignment > 0);
    assert(b_Is_POT(n_pot_alignment)); // alignment must be power of two
    -- n_pot_alignment;
    return (n_x + n_pot_alignment) & ~n_pot_alignment; // rounds towards positive infinity (i.e. negative towards zero)
}

Note that both of those round negative values towards zero (that means round to positive infinity for all values), neither of them relies on signed overflow (which is undefined in C/C++).

This gives:

n_Align_Up(10, 100) = 100
n_Align_Up(110, 100) = 200
n_Align_Up(0, 100) = 0
n_Align_Up(-10, 100) = 0
n_Align_Up(-110, 100) = -100
n_Align_Up(-210, 100) = -200
n_Align_Up_POT(10, 128) = 128
n_Align_Up_POT(130, 128) = 256
n_Align_Up_POT(0, 128) = 0
n_Align_Up_POT(-10, 128) = 0
n_Align_Up_POT(-130, 128) = -128
n_Align_Up_POT(-260, 128) = -256
Dinerman answered 15/10, 2014 at 9:35 Comment(1)
I've been using your n_Align_Up_POT ever since I saw it inside Delphi's TList class. It has its restrictions, like the alignment (multiple) being a power of 2, but that is seldom a problem because I mostly use it to get/check the correct alignment for SMID. It is awesome and it seems not many people know about it.Permit
A
3

Round to nearest multiple that happens to be a power of 2

unsigned int round(unsigned int value, unsigned int multiple){
    return ((value-1u) & ~(multiple-1u)) + multiple;
}

This can be useful for when allocating along cachelines, where the rounding increment you want is a power of two, but the resulting value only needs to be a multiple of it. On gcc the body of this function generates 8 assembly instructions with no division or branches.

round(  0,  16) ->   0
round(  1,  16) ->  16
round( 16,  16) ->  16
round(257, 128) -> 384 (128 * 3)
round(333,   2) -> 334
Accordant answered 2/3, 2019 at 20:59 Comment(0)
L
2

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

Lever answered 4/8, 2010 at 15:23 Comment(3)
Note that double only can hold 54 bits of significand on x86-based machines. If you have 64-bit ints, it will ultimately fail.Dinerman
IEEE754 standard double can't but x64 cpus have an 80bit internal floating point so operations on a single number are reliableLever
While that is true, you have very little control over that rounding from C/C++. It depends on the control word settings and it may actually round to less than 80 bits. Also you have SSE and other SIMD instruction sets which have no such extended intermediate (vectorizing compiler could easily use them).Dinerman
T
2
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

Tarkany answered 4/8, 2010 at 15:23 Comment(0)
H
2

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;
Haruspicy answered 4/8, 2010 at 15:26 Comment(0)
B
2

may be this can help:

int RoundUpToNearestMultOfNumber(int val, int num)
{
  assert(0 != num);
  return (floor((val + num) / num) * num);
}
Butylene answered 20/9, 2013 at 14:8 Comment(1)
Why use floor and integer division? There is nothing to floor. If it were double, you could at least inherit the handling of negative values.Dinerman
B
2

To always round up

int alwaysRoundUp(int n, int multiple)
{
    if (n % multiple != 0) {
        n = ((n + multiple) / multiple) * multiple;

        // Another way
        //n = n - n % multiple + multiple;
    }

    return n;
}

alwaysRoundUp(1, 10) -> 10

alwaysRoundUp(5, 10) -> 10

alwaysRoundUp(10, 10) -> 10


To always round down

int alwaysRoundDown(int n, int multiple)
{
    n = (n / multiple) * multiple;

    return n;
}

alwaysRoundDown(1, 10) -> 0

alwaysRoundDown(5, 10) -> 0

alwaysRoundDown(10, 10) -> 10


To round the normal way

int normalRound(int n, int multiple)
{
    n = ((n + multiple/2)/multiple) * multiple;

    return n;
}

normalRound(1, 10) -> 0

normalRound(5, 10) -> 10

normalRound(10, 10) -> 10

Benefactress answered 20/1, 2014 at 15:3 Comment(0)
M
1

I found an algorithm which is somewhat similar to one posted above:

int[(|x|+n-1)/n]*[(nx)/|x|], where x is a user-input value and n is the multiple being used.

It works for all values x, where x is an integer (positive or negative, including zero). I wrote it specifically for a C++ program, but this can basically be implemented in any language.

Myrlemyrlene answered 26/1, 2011 at 1:17 Comment(0)
C
1

For negative numToRound:

It should be really easy to do this but the standard modulo % operator doesn't handle negative numbers like one might expect. For instance -14 % 12 = -2 and not 10. First thing to do is to get modulo operator that never returns negative numbers. Then roundUp is really simple.

public static int mod(int x, int n) 
{
    return ((x % n) + n) % n;
}

public static int roundUp(int numToRound, int multiple) 
{
    return numRound + mod(-numToRound, multiple);
}
Concepcionconcept answered 15/2, 2013 at 12:14 Comment(0)
J
1

This is what I would do:

#include <cmath>

int roundUp(int numToRound, int multiple)
{
    // if our number is zero, return immediately
   if (numToRound == 0)
        return multiple;

    // if multiplier is zero, return immediately
    if (multiple == 0)
        return numToRound;

    // how many times are number greater than multiple
    float rounds = static_cast<float>(numToRound) / static_cast<float>(multiple);

    // determine, whether if number is multiplier of multiple
    int floorRounds = static_cast<int>(floor(rounds));

    if (rounds - floorRounds > 0)
        // multiple is not multiplier of number -> advance to the next multiplier
        return (floorRounds+1) * multiple;
    else
        // multiple is multiplier of number -> return actual multiplier
        return (floorRounds) * multiple;
}

The code might not be optimal, but I prefer clean code than dry performance.

Jenelljenelle answered 7/3, 2014 at 21:44 Comment(1)
Casting the int to float readily loses precision and makes for incorrect answers.Nichollenicholls
S
1
int roundUp (int numToRound, int multiple)
{
  return multiple * ((numToRound + multiple - 1) / multiple);
}

although:

  • won't work for negative numbers
  • won't work if numRound + multiple overflows

would suggest using unsigned integers instead, which has defined overflow behaviour.

You'll get an exception is multiple == 0, but it isn't a well-defined problem in that case anyway.

Standing answered 12/3, 2014 at 19:52 Comment(0)
A
1

c:

int roundUp(int numToRound, int multiple)
{
  return (multiple ? (((numToRound+multiple-1) / multiple) * multiple) : numToRound);
}

and for your ~/.bashrc:

roundup()
{
  echo $(( ${2} ? ((${1}+${2}-1)/${2})*${2} : ${1} ))
}
Andrea answered 14/3, 2014 at 2:24 Comment(0)
M
1

I use a combination of modulus to nullify the addition of the remainder if x is already a multiple:

int round_up(int x, int div)
{
    return x + (div - x % div) % div;
}

We find the inverse of the remainder then modulus that with the divisor again to nullify it if it is the divisor itself then add x.

round_up(19, 3) = 21
Matriarchy answered 26/5, 2016 at 7:35 Comment(0)
A
1

Here's my solution based on the OP's suggestion, and the examples given by everyone else. Since most everyone was looking for it to handle negative numbers, this solution does just that, without the use of any special functions, i.e. abs, and the like.

By avoiding the modulus and using division instead, the negative number is a natural result, although it's rounded down. After the rounded down version is calculated, then it does the required math to round up, either in the negative or positive direction.

Also note that no special functions are used to calculate anything, so there is a small speed boost there.

int RoundUp(int n, int multiple)
{
    // prevent divide by 0 by returning n
    if (multiple == 0) return n;

    // calculate the rounded down version
    int roundedDown = n / multiple * multiple;

    // if the rounded version and original are the same, then return the original
    if (roundedDown == n) return n;

    // handle negative number and round up according to the sign
    // NOTE: if n is < 0 then subtract the multiple, otherwise add it
    return (n < 0) ? roundedDown - multiple : roundedDown + multiple;
}
Allison answered 28/7, 2018 at 18:29 Comment(1)
Fails with RoundUp(INT_MIN, -1) as n / multiple is int overflow.Nichollenicholls
I
1

I think this should help you. I have written the below program in C.

# include <stdio.h>
int main()
{
  int i, j;
  printf("\nEnter Two Integers i and j...");
  scanf("%d %d", &i, &j);
  int Round_Off=i+j-i%j;
  printf("The Rounded Off Integer Is...%d\n", Round_Off);
  return 0;
}
Imaimage answered 30/9, 2018 at 6:21 Comment(0)
S
1

Endless possibilities, for signed integers only:

n + ((r - n) % r)

Serenaserenade answered 24/7, 2020 at 14:51 Comment(1)
int n=4; int r=3; return n + ((r - n) % r); seems to return 3, instead of 6 which I'd expectSilverfish
B
1

The accepted answer doesn't work very well, I thought I'd try my hand at this problem, this should round up all integers you throw at it:

int round_up(int input, unsigned int multiple) {
    if (input < 0) { return input - input % multiple; }
    return input + multiple - (((input - 1) % multiple) + 1);
}

If the number is negative it's easy, take the remainder and add it onto the input, that'll do the trick.

If the number is not negative, you have to subtract the remainder from the multiple and add that to round up. The problem with that is that if input is exactly on a multiple, it will still get rounded up to the next multiple because multiple - 0 = multiple.

To remedy this we do a cool little hack: subtract one from input before doing the remainder, then add it back on to the resulting remainder. This doesn't affect anything at all unless input is on a multiple. In that case, subtracting one will cause the remainder to the previous multiple to be calculated. After adding one again, you'll have exactly the multiple. Obviously subtracting this from itself yields 0, so your input value doesn't change.

Boucicault answered 4/11, 2022 at 6:50 Comment(0)
C
0
/// Rounding up 'n' to the nearest multiple of number 'b'.
/// - Not tested for negative numbers.
/// \see http://stackoverflow.com/questions/3407012/
#define roundUp(n,b) ( (b)==0 ? (n) : ( ((n)+(b)-1) - (((n)-1)%(b)) ) )

/// \c test->roundUp().
void test_roundUp() {   
    // yes_roundUp(n,b) ( (b)==0 ? (n) : ( (n)%(b)==0 ? n : (n)+(b)-(n)%(b) ) )
    // yes_roundUp(n,b) ( (b)==0 ? (n) : ( ((n + b - 1) / b) * b ) )

    // no_roundUp(n,b) ( (n)%(b)==0 ? n : (b)*( (n)/(b) )+(b) )
    // no_roundUp(n,b) ( (n)+(b) - (n)%(b) )

if (true) // couldn't make it work without (?:)
{{  // test::roundUp()
    unsigned m;
                { m = roundUp(17,8); } ++m;
    assertTrue( 24 == roundUp(17,8) );
                { m = roundUp(24,8); }
    assertTrue( 24 == roundUp(24,8) );

    assertTrue( 24 == roundUp(24,4) );
    assertTrue( 24 == roundUp(23,4) );
                { m = roundUp(23,4); }
    assertTrue( 24 == roundUp(21,4) );

    assertTrue( 20 == roundUp(20,4) );
    assertTrue( 20 == roundUp(19,4) );
    assertTrue( 20 == roundUp(18,4) );
    assertTrue( 20 == roundUp(17,4) );

    assertTrue( 17 == roundUp(17,0) );
    assertTrue( 20 == roundUp(20,0) );
}}
}
Camarena answered 14/2, 2014 at 13:30 Comment(0)
C
0

This is getting the results you are seeking for positive integers:

#include <iostream>
using namespace std;

int roundUp(int numToRound, int multiple);

int main() {
    cout << "answer is: " << roundUp(7, 100) << endl;
    cout << "answer is: " << roundUp(117, 100) << endl;
    cout << "answer is: " << roundUp(477, 100) << endl;
    cout << "answer is: " << roundUp(1077, 100) << endl;
    cout << "answer is: " << roundUp(52,20) << endl;
    cout << "answer is: " << roundUp(74,30) << endl;
    return 0;
}

int roundUp(int numToRound, int multiple) {
    if (multiple == 0) {
        return 0;
    }
    int result = (int) (numToRound / multiple) * multiple;
    if (numToRound % multiple) {
        result += multiple;
    } 
    return result;
}

And here are the outputs:

answer is: 100
answer is: 200
answer is: 500
answer is: 1100
answer is: 60
answer is: 90
Cloister answered 8/3, 2014 at 0:31 Comment(0)
A
0

I think this works:

int roundUp(int numToRound, int multiple) {
    return multiple? !(numToRound%multiple)? numToRound : ((numToRound/multiple)+1)*multiple: numToRound;
}
Animism answered 18/7, 2020 at 2:31 Comment(0)
F
-1

This works for me but did not try to handle negatives

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

    int mod = numToRound % multiple;
    int diff = multiple - mod;
    return numToRound + diff;
}
Fushih answered 31/5, 2012 at 20:22 Comment(0)
P
-2

Here is a super simple solution to show the concept of elegance. It's basically for grid snaps.

(pseudo code)

nearestPos = Math.Ceil( numberToRound / multiple ) * multiple;
Protectionist answered 2/7, 2020 at 16:7 Comment(2)
did you check your idea befure submiting? it dosent give currect answerAvar
@Avar Maybe cast the values to floats?Animism

© 2022 - 2024 — McMap. All rights reserved.