Rob*_*boy 155 c++ algorithm rounding
好的 - 我几乎不好意思在这里张贴这个(如果有人投票结束我会删除),因为这似乎是一个基本问题.
这是在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(int numToRound, int multiple)
{
 if(multiple == 0)
 {
  return numToRound;
 }
 int roundDown = ( (int) (numToRound) / multiple) * multiple;
 int roundUp = roundDown + multiple; 
 int roundCalc = roundUp;
 return (roundCalc);
}
Mar*_*som 149
这适用于正数,不确定负数.它只使用整数数学.
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;
}
Kin*_*gon 99
没有条件:
int roundUp(int numToRound, int multiple) 
{
    assert(multiple);
    return ((numToRound + multiple - 1) / multiple) * multiple;
}
对于负数,这类似于从零开始舍入
编辑:适用于负数的版本
int roundUp(int numToRound, int multiple) 
{
    assert(multiple);
    int isPositive = (int)(numToRound >= 0);
    return ((numToRound + isPositive * (multiple - 1)) / multiple) * multiple;
}
如果multiple是2的幂
int roundUp(int numToRound, int multiple) 
{
    assert(multiple && ((multiple & (multiple - 1)) == 0));
    return (numToRound + multiple - 1) & -multiple;
}
小智 36
当因子始终为正时,这种方法有效:
int round_up(int num, int factor)
{
    return num + factor - 1 - (num - 1) % factor;
}
编辑:返回round_up(0,100)=100.请参阅下面的保罗评论,以获得返回的解决方案round_up(0,100)=0.
pli*_*nth 22
这是对"如何找出n位将占用多少字节?"(A:(n位+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
}
dor*_*ron 14
int roundUp(int numToRound, int multiple)
{
 if(multiple == 0)
 {
  return 0;
 }
 return ((numToRound - 1) / multiple + 1) * multiple;  
}
而且无需乱搞条件
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;
}
这适用于任何浮点数或基数(例如,您可以将-4舍入到最接近的6.75).本质上,它转换为固定点,在那里四舍五入,然后转换回来.它通过将AWAY从0舍入来处理负数.它还通过将函数转换为roundDown来处理负值舍入值.
特定于int的版本如下所示:
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;
}
这或多或少是基座的答案,增加了负面的输入支持.
对于任何寻找短而甜蜜答案的人.这是我用的.没有负面因素.
n - (n % r)
这将返回先前的因素.
(n + r) - (n % r)
将返回下一个.希望这有助于某人.:)
这是使用模板函数的现代c ++方法,该函数适用于float,double,long,int和short(但由于使用了double值,因此不能用于long long和long 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.
创建"向上舍入"或更好地称为"圆形天花板"模板功能,如下所示:
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));
}
创建"向下舍入"或更好地称为"圆底"模板功能,如下所示:
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));
}
首先,您的错误条件(倍数== 0)应该具有返回值.什么?我不知道.也许你想抛出异常,这取决于你.但是,什么都不返回是危险的.
其次,你应该检查numToRound是否已经是一个倍数.否则,当你添加multiple时roundDown,你会得到错误的答案.
第三,你的演员是错的.你转换numToRound为一个整数,但它已经是一个整数.你需要在除法之前转换为加倍,并在乘法之后转换回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);
}