210

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
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Robben_Ford_Fan_boy
  • 8,494
  • 11
  • 64
  • 85
  • 3
    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. – Niki Yoshiuchi Aug 04 '10 at 15:24
  • this does not work for roundUp(30,30). It gives 60 as answer, it should still give 30 as answer.. – bsobaid Mar 07 '14 at 20:30
  • @bsobaid: Check out my answer at the bottom. It's slightly simpler than other solutions here, although those should work too – Niklas B. Mar 07 '14 at 22:04
  • @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. – Mark Ransom Mar 07 '14 at 22:30
  • @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 :) – Niklas B. Mar 07 '14 at 22:34
  • Is the function expected to treat `0` as a valid value of `multiple`? If so, what is the expected answer? – R Sahu Mar 09 '14 at 04:01
  • 3
    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`. –  Nov 25 '15 at 22:14
  • 1
    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. – chux - Reinstate Monica Jan 05 '19 at 18:33

32 Answers32

192

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;
}
bdesham
  • 15,430
  • 13
  • 79
  • 123
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • +1 In my opinion, definately the nicest and most readable solution. – Robben_Ford_Fan_boy Aug 04 '10 at 17:28
  • 1
    Add `if(number<0){ multiple = multiple*(-1); }` at the start to round negative numbers in the right direction – Josh Feb 03 '13 at 13:54
  • 6
    @Josh: Why using multiplication? `if(number<0) multiple = -multiple` is easier. – md5 Jun 27 '13 at 17:53
  • this does not work for roundUp(30,30). It gives 60 as answer, it should still give 30 as answer. – bsobaid Mar 07 '14 at 20:52
  • @bsobaid impossible. The `if (remainder == 0)` test should take care of that case. It works for me: http://ideone.com/Waol7B – Mark Ransom Mar 07 '14 at 21:04
  • @bsobaid, you might get that result if you had a typo `=` instead of `==` in that `if` statement. – Mark Ransom Mar 07 '14 at 21:09
  • 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? – bsobaid Mar 10 '14 at 18:18
  • @bsobaid 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`.) – eh9 Mar 14 '14 at 09:36
  • 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. – eh9 Mar 14 '14 at 09:56
  • @eh9 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. – Mark Ransom Mar 14 '14 at 17:45
  • `abs(INT_MIN)` is undefined behavior. – chux - Reinstate Monica Jan 05 '19 at 18:17
  • 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) * m` – Rivenfall Jun 27 '19 at 08:37
174

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

Neuron
  • 5,141
  • 5
  • 38
  • 59
KindDragon
  • 6,558
  • 4
  • 47
  • 75
  • 35
    +1 for the power of 2 version. Very useful as it totally avoids the cost of multiplications, divisions or modulo. – Nikos C. Nov 12 '13 at 13:46
  • Are you sure that these algorithms have no preconditions? What about negative numbers? [The behaviour seems to be undefined in pre-C++11](http://stackoverflow.com/questions/319880/integer-division-rounding-with-negatives-in-c). – cubuspl42 Aug 18 '15 at 16:28
  • > What about negative numbers? As described, this works for negative numbers like rounding away from zero. – KindDragon Sep 03 '15 at 18:13
  • I read "rounding up" as meaning rounding towards positive infinity, not rounding away from zero. –  Nov 25 '15 at 22:15
  • I know, but most people are only interested in positive numbers – KindDragon Nov 25 '15 at 22:21
  • +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. – Adrian McCarthy Nov 25 '15 at 23:00
  • @Hurkyl I added a version for negative numbers – KindDragon Nov 26 '15 at 11:29
  • 13
    Note that `& ~(x - 1)` is the same as `& -x` for two's complement arithmetic. – Todd Lehman Aug 10 '16 at 02:04
  • Not 100% robust: fails if `numToRound + multiple - 1 > MAX_INT`, though, true answer may be under `MAX_INT`. – user2052436 Jun 14 '19 at 16:04
  • Can someone give a mathematical proof for the case of power-of-2? – Ziqi Fan Dec 15 '21 at 23:41
48

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.

Paul
  • 6,061
  • 6
  • 39
  • 70
xlq
  • 489
  • 4
  • 2
  • 2
    Looks to be the shortest case that handles the 'already-a-multiple' case. – harningt Aug 20 '12 at 12:56
  • 1
    Best solution in terms of number of costly operations. It only uses a single divison and no multiplication – Niklas B. Mar 09 '14 at 06:41
  • 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. – kingtorus Mar 10 '14 at 23:58
  • 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.) – SilverbackNet Jun 14 '14 at 21:05
  • 3
    round_up(0, 100) == 100 instead of 0 as in the accepted answer – Gregory Sep 12 '14 at 00:11
  • 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. – Thomas Kejser Jan 14 '15 at 13:34
  • 7
    Shouldn't it be `num + factor - 1 - (num + factor - 1) % factor`? – Paul Mar 03 '15 at 16:34
  • 7
    `num - 1 - (num - 1) % factor + factor` does the same calculation without the risk of integer overflow. –  Nov 25 '15 at 22:18
  • 1
    @Paul's version does handle num == 0 as expected – Cimbali Jan 13 '16 at 17:41
  • @Paul's version is also faster if implemented as `int a = num + factor - 1; return a - a%factor;` – Serge Rogatch Jul 03 '17 at 06:12
  • ```{--num; return num - (num%factor) + factor; }``` – Robert Andrzejuk Feb 28 '18 at 15:54
  • @Hurkyl [`num - 1 - (num - 1) % factor + factor`](https://stackoverflow.com/questions/3407012/c-rounding-up-to-the-nearest-multiple-of-a-number/3407254?noredirect=1#comment55615791_4073700) overflows when `num == INT_MIN` – chux - Reinstate Monica Jan 05 '19 at 18:36
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
}
plinth
  • 48,267
  • 11
  • 78
  • 120
  • 1
    This doesn't round up to the next multiple of a number. – aaaa bbbb Aug 04 '10 at 16:07
  • 7
    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;) – Hakanai Feb 06 '13 at 03:55
  • @Trejkaz nope. It should be `(x = roundTo - 1; return (n+x)&~roundTo;)` as in my answer – KindDragon Oct 19 '17 at 13:45
  • @KindDragon 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. – Hakanai Oct 20 '17 at 03:14
  • @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`. – Peter Cordes Mar 15 '18 at 07:09
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

doron
  • 27,972
  • 12
  • 65
  • 103
14

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));
}
Flovdis
  • 2,945
  • 26
  • 49
  • 1
    plus 1, though some people might find it more resonable to return 0 when mulitple == 0 – stijn Aug 14 '15 at 11:30
  • 4
    Beware, because converting int64_t to double can be lossy, so it's not quite as type-generic as it may appear. – Adrian McCarthy Nov 25 '15 at 23:06
  • @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. – Flovdis Nov 26 '15 at 09:55
  • 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. – the swine Apr 03 '17 at 14:47
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. :)

aaron-bond
  • 3,101
  • 3
  • 24
  • 41
  • The % operator is implementation dependent for negative numbers -- so may get different answers in this case. – wcochran Jul 28 '20 at 23:41
  • 3
    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. – Tara Dec 17 '20 at 20:16
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.

Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
Dolphin
  • 4,655
  • 1
  • 30
  • 25
  • I have tested float roundUp code with double, it works for me. Really solves my issue. – Ashif Aug 25 '14 at 11:15
  • 1
    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. – Troyseph Feb 13 '19 at 14:24
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);
}
Mike Caron
  • 14,351
  • 4
  • 49
  • 77
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:

Community
  • 1
  • 1
haneefmubarak
  • 1,911
  • 1
  • 21
  • 32
  • 2
    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. – Axel Rietschin Sep 03 '16 at 00:28
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
the swine
  • 10,713
  • 7
  • 58
  • 100
  • 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. – user1593842 Sep 12 '17 at 18:17
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
Anne Quinn
  • 12,609
  • 8
  • 54
  • 101
2

may be this can help:

int RoundUpToNearestMultOfNumber(int val, int num)
{
  assert(0 != num);
  return (floor((val + num) / num) * num);
}
pb2q
  • 58,613
  • 19
  • 146
  • 147
Arsen
  • 654
  • 8
  • 20
  • 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. – the swine Apr 03 '17 at 14:50
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

onmyway133
  • 45,645
  • 31
  • 257
  • 263
2

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
  • 94,801
  • 28
  • 188
  • 263
  • 1
    Note that double only can hold 54 bits of significand on x86-based machines. If you have 64-bit ints, it will ultimately fail. – the swine Apr 03 '17 at 14:52
  • IEEE754 standard double can't but x64 cpus have an 80bit internal floating point so operations on a single number are reliable – Martin Beckett Apr 03 '17 at 16:09
  • 1
    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). – the swine Apr 04 '17 at 12:57
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

Michal Ciechan
  • 13,492
  • 11
  • 76
  • 118
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;
Jesse Naugher
  • 9,780
  • 1
  • 41
  • 56
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);
}
user990343
  • 11
  • 1
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.

Gotcha
  • 392
  • 2
  • 10
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.

user3392484
  • 1,929
  • 9
  • 9
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} ))
}
nhed
  • 5,774
  • 3
  • 30
  • 44
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
Mira Weller
  • 2,406
  • 22
  • 27
Nick Bedford
  • 4,365
  • 30
  • 36
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.

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;
}
weatx
  • 71
  • 2
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;
}
Neel
  • 131
  • 3
  • 9
1

Endless possibilities, for signed integers only:

n + ((r - n) % r)

  • `int n=4; int r=3; return n + ((r - n) % r);` seems to return 3, instead of 6 which I'd expect – qbolec Nov 29 '22 at 18:12
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.

Nik Tedig
  • 453
  • 2
  • 6
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) );
}}
}
Adolfo
  • 281
  • 2
  • 5
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
Dave
  • 144
  • 4
0

I think this works:

int roundUp(int numToRound, int multiple) {
    return multiple? !(numToRound%multiple)? numToRound : ((numToRound/multiple)+1)*multiple: numToRound;
}
-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;
}
-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;