2010-07-07 14 views
7

Estoy tratando de implementar la división larga para bignums. No puedo usar una biblioteca como GMP desafortunadamente debido a las limitaciones de la programación integrada. Además, quiero el ejercicio intelectual de aprender cómo implementarlo. Hasta ahora, he agregado y multiplicado utilizando matrices de bytes de cualquier longitud (por lo que cada byte es como un dígito base-256).Cómo implementar división larga para números enormes (bignums)

Estoy tratando de comenzar a implementar la división/módulo y quiero saber por dónde empezar? He encontrado muchos códigos altamente optimizados (también ilegibles) en la red, lo que no me ayuda, y he encontrado muchos libros técnicos matemáticos altamente técnicos de los que no puedo cerrar la brecha entre la teoría y la implementación. .

Si alguien pudiera recomendar un algoritmo popular, y apuntarme a una explicación fácil de entender que se incline hacia la implmenentación, sería fantástico.

-edit: Necesito algoritmos que funcionan cuando el dividendo es ~ 4000bits, y el divisor es de ~ 2000bits

-Editar: ¿Funcionará este algoritmo con la base-256? http://courses.cs.vt.edu/~cs1104/BuildingBlocks/divide.030.html

-edit: ¿Este es el algoritmo (división newton) que realmente debería estar usando? http://en.wikipedia.org/wiki/Division_(digital)#Newton.E2.80.93Raphson_division

+0

Encontré esto, pero no estoy seguro de que sea un buen algoritmo para números> 2048 bits? http://stackoverflow.com/questions/2525172/custom-very-long-int-division-issue – Chris

+1

También encontré este documento, ¿sería un buen algoritmo para empezar? http://www.brinch-hansen.net/papers/1994b.pdf – Chris

Respuesta

4

Si quieres aprender, comienza con el método de lápiz y papel que usaste en la escuela primaria. Lo creas o no, ese es esencialmente el mismo algoritmo O (n^2) que se usa en la mayoría de las bibliotecas bignum para los números que están en el rango que estás buscando. El primer paso difícil se llama "estimación del cociente", y probablemente sea el más difícil de entender. Una vez que entiendas eso, el resto debería ser fácil.

Una buena referencia es Knuth's "Seminumerical Algorithms". Él tiene muchas discusiones sobre diferentes maneras de hacer la estimación del cociente tanto en el texto como en los ejercicios. Ese libro tiene capítulos dedicados a las implementaciones de bignum.

+0

+1 para Knuth reference. –

+0

El método de lápiz y papel solo parece funcionar si el divisor tiene uno o dos dígitos, de lo que puedo encontrar en la red – Chris

+0

Espera, ¿es esto lo mismo que el método de cambio/resta aquí? http://courses.cs.vt.edu/~cs1104/BuildingBlocks/divide.030.html – Chris

0

Esta pregunta tiene más de 2 años, pero para estos números de tamaño, puede consultar el código fuente de OpenSSL. Tiene RSA con números de este tamaño, por lo que tiene muchas rutinas matemáticas optimizadas para números de 1000 a 4000 bits.

1

¿Está utilizando el vacío Four1 (double double [], int, int) en su código y luego convolviendo y luego haciendo una transformación inversa? Tengo multiplicación para trabajar pero cuando traté de hacer la división de la misma manera que escupió sale un resultado y luego abandono, así que no puedo evitarlo, pero si tiene el tomo llamado "Recetas numéricas en C++", vaya al final y encontrará lo que busca en realidad comienza en la página 916 a 926.

Cuestiones relacionadas