Я использую алгоритм базового преобразования для генерации перестановки из большого целого числа (разбитого на 32-битные слова).ускорение «базового преобразования» для больших целых чисел
Я использую относительно стандартного алгоритма для этого:
/* N = count,K is permutation index (0..N!-1) A[N] contains 0..N-1 */
i = 0;
while (N > 1) {
swap A[i] and A[i+(k%N)]
k = k/N
N = N - 1
i = i + 1
}
К сожалению, разрыв и по модулю каждой итерации складывает, особенно движущихся с большими числами - Но, кажется, я мог бы просто использовать многократно!
/* As before, N is count, K is index, A[N] contains 0..N-1 */
/* Split is arbitrarily 128 (bits), for my current choice of N */
/* "Adjust" is precalculated: (1 << Split)/(N!) */
a = k*Adjust; /* a can be treated as a fixed point fraction */
i = 0;
while (N > 1) {
a = a*N;
index = a >> Split;
a = a & ((1 << Split) - 1); /* actually, just zeroing a register */
swap A[i] and A[i+index]
N = N - 1
i = i + 1
}
Это лучше, но выполнение большого числа умножений по-прежнему вяло.
Вопрос 1:
Есть ли способ сделать это быстрее?
Например. Поскольку я знаю, что N * (N-1) меньше 2^32, можно ли вытащить эти числа из одного слова и слить в «остатки»?
Или, есть способ изменить аристочный декодер, чтобы вытаскивать указатели по одному за раз?
Вопрос 2:
Ради любопытства - если я использую умножение для преобразования числа на базу 10 без корректировки, результат умножается на (10^цифр/2^сдвиг). Есть ли сложный способ удалить этот фактор, работающий с десятичными цифрами? Даже с коэффициентом корректировки кажется, что это будет быстрее - почему бы стандартным библиотекам не использовать это против divide и mod?
Я не могу понять ваш второй алгоритм. – 2010-11-25 13:16:08
@GregS - скажите, пожалуйста, если вы считаете, что есть проблема - теория заключается в том, что она удаляет значения слева (msb) с умножением/маской по сравнению с правым (lsb) с mod/divide. – 2010-11-25 18:13:32