Estoy usando un algoritmo de conversión de base para generar una permutación a partir de un entero grande (dividido en palabras de 32 bits).acelerar la "conversión base" para enteros grandes
utilizo un algoritmo relativamente estándar para esto:
/* 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
}
Por desgracia, la brecha y Modulo cada iteración se suma, en especial de trasladarse a grandes números enteros - Pero, al parecer tan sólo pudiera utilizar multiplican!
/* 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
}
Esto es mejor, pero hacer multiplicaciones de números enteros grandes es todavía lento.
Pregunta 1:
¿Hay alguna manera de hacerlo más rápido?
Por ejemplo. Como sé que N * (N-1) es menor que 2^32, ¿podría sacar esos números de una palabra y unirme a los "restos"?
O, ¿hay alguna manera de modificar un decodificador aritético para extraer las indicaciones de a una por vez?
Pregunta 2:
En aras de la curiosidad - si uso la multiplicación para convertir un número de base 10 sin el ajuste, entonces el resultado se multiplica por (10^dígitos/2^turno). ¿Hay alguna manera complicada de eliminar este factor trabajando con los dígitos decimales? Incluso con el factor de ajuste, parece que sería más rápido: ¿por qué las bibliotecas estándar no usarían esto frente a dividir y modificar?
No puedo entender tu segundo algoritmo. –
@GregS - por favor dígame si cree que hay un problema - la teoría es que elimina los valores de la izquierda (msb) con multiplicar/máscara frente a la derecha (lsb) con mod/divide. –