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

这是在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 roundUp = roundDown + multiple;
int roundCalc = roundUp;
return (roundCalc); 

肯定可以缩写为

int roundUp = roundDown + multiple;
return roundUp;

其他回答

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

这是使用模板函数的现代c++方法,该模板函数适用于float, double, long, int和short(但不适用于long long和long double,因为使用了double值)。

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

但是你可以很容易地通过模板专门化添加long long和long double的支持,如下所示:

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

要创建向上舍入的函数,请使用std::ceil,而总是向下舍入的函数请使用std::floor。上面的例子是使用std::round进行舍入。

创建“round up”或更广为人知的“round ceiling”模板函数,如下所示:

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

创建“round down”或更广为人知的“round floor”模板函数,如下所示:

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

首先,因为我不太明白你想要做什么,这些台词

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

肯定可以缩写为

int roundUp = roundDown + multiple;
return roundUp;

首先,错误条件(multiple == 0)应该有一个返回值。什么?我不知道。也许您想要抛出一个异常,这取决于您。但是,什么都不返回是危险的。

其次,您应该检查numToRound是否已经是一个倍数。否则,当您在roundDown中添加倍数时,您将得到错误的答案。

第三,你的角色选择是错误的。您将numToRound转换为一个整数,但它已经是一个整数。需要在除法之前强制转换为to double,在乘法之后强制转换回int。

最后,负数需要什么?舍入“向上”可以表示舍入到零(与正数方向相同),或远离零(一个“更大”的负数)。或者,也许你不在乎。

以下是前三个修复的版本,但我不处理负面问题:

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

无限的可能性,仅适用于有符号整数:

N + ((r - N) % r