Подтвердить что ты не робот

Модулю отрицательных чисел

Возможный дубликат:
Мод отрицательного числа тает мой мозг!

Мне было интересно, был ли более хороший алгоритм для того, что я пытаюсь сделать:

wrapIndex(-6, 3) = 0
wrapIndex(-5, 3) = 1
wrapIndex(-4, 3) = 2
wrapIndex(-3, 3) = 0
wrapIndex(-2, 3) = 1
wrapIndex(-1, 3) = 2
wrapIndex(0, 3) = 0
wrapIndex(1, 3) = 1
wrapIndex(2, 3) = 2
wrapIndex(3, 3) = 0
wrapIndex(4, 3) = 1
wrapIndex(5, 3) = 2

Я придумал

function wrapIndex(i, i_max) {
        if(i > -1)
            return i%i_max;

        var x = i_max + i%i_max;
        if(x == i_max)
            return 0;

        return x;
    }

Есть ли лучший способ сделать это?

4b9b3361

Ответ 1

Это решение является ветвящимся, но выполняет % дважды:

function wrapIndex(i, i_max) {
   return ((i % i_max) + i_max) % i_max;
}

Следует сказать, что предполагается поведение С#/Java %, т.е. результат имеет тот же знак, что и дивиденд. Некоторые языки определяют вычисление остатка, чтобы вместо этого принять знак делителя (например, mod в Clojure). Некоторые языки имеют оба варианта (пара mod/rem в Common Lisp, Haskell и т.д.). Алгол-68 имеет %x, который всегда возвращает неотрицательное число. С++ оставил его до реализации до тех пор, пока С++ 11, теперь знак остатка (почти) полностью определен в соответствии с знаком дивиденда.

См. также

Ответ 2

Решение с двумя операциями % работает, но это немного быстрее в большинстве языков на большинстве аппаратных средств (есть исключения, однако):

int wrapIndex(int i, int i_max) {
    i = i%i_max;
    return i<0 ? i+i_max : i;
}

Ответ 3

Никер - это вопрос вкуса, но как насчет

var x = (i_max + i % i_max) % i_max;

Ответ 4

Вы можете сделать это:

function wrapIndex(i, i_max) {
    if (i < 0) i = (i % i_max) + i_max;
    return i % i_max;
}

Ответ 5

Многие пользователи дали хорошие ответы, просто остерегайтесь отрицательных чисел, поскольку разные языки могут вести себя по-разному. Например, этот фрагмент C пишет "-1"

int main ()
{
    printf("%d\n", (-4) % 3);
}

В python у нас есть другое выходное значение

Python 2.6.4 (r264:75706, Dec  7 2009, 18:43:55) 
[GCC 4.4.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> (-4) % 3
2

EDIT: На самом деле я не думаю, что у вас будут отрицательные индексы! Однако это хорошо знать.