Rounding an integer to the nearest multiple of another integer

I need to round integers to be the nearest multiple of another integer. Examples of results in the case of multiples of 100:

  • 36-> 0
  • 99-> 100
  • 123-> 100
  • 164-> 200

etc.

I came up with the following code that works but feels "dirty":

int RoundToMultiple(int toRound, int multiple)
{
    return (toRound + (multiple / 2)) / multiple * multiple;
}

This takes into account the truncated properties of integer division to make it work. Can I find this code portable? Are there any compiler settings when this does not give me the desired result? If so, how can I achieve the same results in portable mode?

If necessary, for a better answer, it can be assumed that multiples will have a power of 10 (including multiples of 1). Numbers can also be considered positive.

+6
3

, . N4296 ( ++ 14), 5.6 [expr.mul]:

/ , . [: ]

++, C89.

, toRound , .

:

int RoundToMultiple(int toRound, int multiple)
{
    const auto ratio = static_cast<double>(toRound) / multiple;
    const auto iratio = std::lround(ratio);
    return iratio * multiple;
}

+/-, , , toRound , . (OTOH, , , multiple , .)

+4

++ :

[expr.mul]

/ quotient , .

A.k.a. . , .

+2

, , , , " " (- ).

As for the solution that converts int to double: I personally find that it is expensive only for rounding, but maybe someone can convince me that my feeling is wrong;

In any case, using only integral operators, the following solution allows us to discuss whether a doublemantissa can always hold every intextra one:

int RoundToMultiple(int toRound, int multiple) {
    toRound += multiple / 2;
    return toRound - (toRound%multiple);
}

If you also want to include negative values, the code can be slightly adapted as follows (including tests):

#include <stdio.h>

int RoundToMultiple(int toRound, int multiple) {
    toRound += toRound < 0 ? -multiple / 2 : multiple / 2;
    return toRound - (toRound%multiple);
}

int main(int argc, char const *argv[])
{
    int tests[] = { 36,99,123,164,-36,-99,-123,-164,0 };
    int expectedResults[] = { 0,100,100,200,0,-100,-100,-200,0 };

    int i=0;
    int test=0, result=0, expectedResult=0;
    do {
        test = tests[i];
        result = RoundToMultiple(test, 100);
        expectedResult = expectedResults[i];
        printf("test %d: %d==%d ? %s\n", test, result, expectedResult, (expectedResult==result ? "OK" : "NOK!"));
        i++;
    }
    while(test != 0);
}
0
source

All Articles