好吧——我几乎不好意思在这里张贴这个(如果有人投票关闭,我会删除),因为这似乎是一个基本的问题。

这是在c++中四舍五入到一个数字的倍数的正确方法吗?

我知道还有其他与此相关的问题,但我特别感兴趣的是,在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);
}

更新: 抱歉,我可能没把意思说清楚。下面是一些例子:

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

当前回答

这可能会有所帮助:

int RoundUpToNearestMultOfNumber(int val, int num)
{
  assert(0 != num);
  return (floor((val + num) / num) * num);
}

其他回答

我用的是:

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
}

对于2的幂:

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

请注意,这两个负值都舍入到0(这意味着所有值都舍入到正无穷),它们都不依赖于有符号溢出(这在C/ c++中未定义)。

这给:

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

c:

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

对于~/.bashrc:

roundup()
{
  echo $(( ${2} ? ((${1}+${2}-1)/${2})*${2} : ${1} ))
}

公认的答案并不是很好,我想我应该在这个问题上尝试一下,这应该是你抛出的所有整数:

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

如果这个数是负的,这很简单,取余数并把它加到输入上,这就可以了。

如果这个数不是负的,你必须从倍数中减去余数,然后加上它来四舍五入。问题是,如果输入正好在一个倍数上,它仍然会四舍五入到下一个倍数,因为倍数- 0 =倍数。

为了解决这个问题,我们做了一个很酷的小技巧:在计算余数之前从输入中减去1,然后把它加回到结果的余数上。这不会影响任何东西,除非输入是倍数。在这种情况下,减去1将计算出前一个倍数的余数。再加1,就正好是这个倍数。很明显,从自身减去这个等于0,所以输入值不变。

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

没有必要在条件上添乱

这适用于正数,不适用于负数。它只使用整数数学。

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

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

    return numToRound + multiple - remainder;
}

编辑:这里有一个适用于负数的版本,如果你所说的“上”是指一个总是>=输入的结果。

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