Я заинтересован в получении остатка от евклидова деления , то есть для пары целых чисел (i, n) найдите r, например:
i = k * n + r, 0 <= r < |k|
простое решение:
int euc(int i, int n)
{
int r;
r = i % n;
if ( r < 0) {
r += n;
}
return r;
}
Но так как мне нужно выполнить это десятки миллионов раз (это используется внутри итератора для многомерных массивов), я бы хотел избежать ветвления, если это возможно. Требования:
- Разветвление, но также желательно быстрее.
- Приемлемо решение, которое работает только для положительного n (но оно должно работать для отрицательного i).
- n заранее неизвестен и может принимать любое значение> 0 и
Редактировать
На самом деле довольно легко ошибиться в результате, поэтому вот пример ожидаемых результатов:
- euc (0, 3) = 0
- euc (1, 3) = 1
- euc (2, 3) = 2
- euc (3, 3) = 0
- euc (-1, 3) = 2
- euc (-2, 3) = 1
- euc (-3,3) = 0
Некоторые люди также беспокоятся, что не имеет смысла оптимизировать это. Мне это нужно для многомерного итератора, в котором элементы за пределами границ заменяются элементами в «виртуальном массиве», который повторяет исходный массив. Поэтому, если мой массив x равен [1, 2, 3, 4], виртуальный массив равен [...., 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4] и, например, x [-2] равен x 1 и т. Д. *
Для второго массива измерения d мне нужно евклидово деление d для каждой точки. Если мне нужно сделать корреляцию между массивом n ^ d и ядром m ^ d, мне нужно евклидово деление n ^ d * m ^ d * d. Для трехмерного изображения 100x100x100 точек и ядра 5 * 5 * 5 точек это уже ~ 400 миллионов евклидовых делений.