Хорошо - мне почти неловко размещать это здесь (и я удалю, если кто-нибудь проголосует за закрытие), поскольку это кажется основным вопросом.
Это правильный способ округления числа до кратного в 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 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;
}
int noOfMultiples = int((numToRound / multiple)+0.5);
return noOfMultiples*multiple
C ++ округляет каждое число в меньшую сторону, поэтому если вы добавите 0,5 (если 1,5, то будет 2), но 1,49 будет 1,99, следовательно, 1.
РЕДАКТИРОВАТЬ - Извините, вы не заметили, что вы хотели чтобы округлить, я бы предложил использовать метод ceil () вместо +0,5
Вероятно, безопаснее привести к типу float и использовать ceil () - если вы не знаете, что деление int даст правильный результат.
Во-первых, ваше условие ошибки (несколько == 0), вероятно, должно иметь возвращаемое значение. Какие? Я не знаю. Может быть, вы хотите создать исключение, решать вам. Но возвращать ничего не опасно.
Во-вторых, вы должны проверить, что numToRound еще не является кратным. В противном случае, когда вы добавите несколько
к 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);
}
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). По сути, это преобразование в фиксированную точку, округление, а затем обратное преобразование. Она обрабатывает отрицательные значения, округляя НАПРЯМУЮ от 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 битов? (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
}
с одной стороны, так как я действительно не понимаю, что вы хотите сделать, строки
int roundUp = roundDown + multiple;
int roundCalc = roundUp;
return (roundCalc);
определенно можно сократить до
int roundUp = roundDown + multiple;
return roundUp;
int roundUp(int numToRound, int multiple)
{
if(multiple == 0)
{
return 0;
}
return ((numToRound - 1) / multiple + 1) * multiple;
}
И не нужно возиться с условиями