Дробная часть числа вопроса - PullRequest
2 голосов
/ 17 мая 2009

Каков хороший алгоритм для определения необходимой дроби, необходимой для добавления / к числу числа, чтобы округлить его до ближайшего целого числа без использования встроенных функций потолка или пола?

Редактировать: Ищем математический трюк с числом, чтобы вычислить часть, необходимую для округления числа до ближайшего целого числа. Чем более примитивны математические операции, тем лучше. Пожалуйста, избегайте использования других процедур. 0.5 можно взять в любом случае, в зависимости от вашего метода. Это НЕ мой домашний вопрос, и я не собираюсь его нигде использовать.

Ответы [ 3 ]

4 голосов
/ 17 мая 2009

Измените число на единицу, чтобы получить десятичную часть, если ее> 0,5, округлить вверх, иначе округлить вниз

OR

Разделите число на 0,5, если оно нечетное, округлите вверх, еще округлите вниз

3 голосов
/ 18 мая 2009

Как только вы получите дробную часть числа, проблема в значительной степени решена. Один из способов получить дробную часть состоит в том, чтобы многократно вычитать степени числа 2 из вашего числа (при условии, что оно было положительным, если оно изначально было отрицательным).

Функция ниже, getWholeMaker, возвращает то, что вы хотите («вещь», которая должна быть добавлена ​​для округления числа). Время выполнения O(log(n)) и использует только элементарные операции.

/* Returns the factional part of x */
double getFrac(double x) {
    if(x < 0) x = -x;
    if(x < 1) return x;
    else if(x < 2) return x-1;

    /* x >= 0 */
    double t = 2;
    while(t+t <= x) t += t;
    /* t is now the largest power of 2 less than or equal to x */
    while(t >= 1) {
        if(t <= x) x -= t;
        t /= 2;
    }

    return x;
}

double getWholeMaker(double x) {
    double frac = getFrac(x);
    double sign = x >= 0 ? +1 : -1;
    return sign * (frac <= 0.5 ? -frac : 1-frac);
}
3 голосов
/ 17 мая 2009

Если вы не можете использовать мод (поскольку он может быть определен только для целых чисел в вашем языке, вы можете сделать что-то вроде этого (в псевдокоде C-ish):

// make the input positive:
boolean inputPositive = true;
if (input < 0) {
  input = 0 - input;
  inputPositive = false;
}

// subtract 1 until you just have the decimal portion:
int integerPart = 0;
while (input > 1) {
  input = input - 1;
  integerPart++;
}

int ret;
if (input >= 0.5) { // round up
  ret = integerPart + 1;
} else {
  ret = integerPart;
}

if (inputPositive) {
  return ret;
} else {
  return 0 - ret;
}

Это решение не использует мод или какие-либо внешние функции. Конечно, я не могу представить, почему вы хотели бы этого в реальной жизни. Интересно подумать, хотя.

...