You are on page 1of 9

Algoritmos de Multiplicación de Enteros de N Dígitos

(de 1 a 2048 dígitos)

← Katiana Leguizamón Ughelli1, Martín Legal Gómez2

1 Universidad Nacional de Asunción, Facultad Politécnica.


katy.py@gmail.com
2 Universidad Nacional de Asunción, Facultad Politécnica.

martintmlg@gmail.com

Resumen. La multiplicación de enteros relativamente grandes es un problema


en el que generalmente los números superan la cantidad máxima de dígitos
representable. Aquí se presenta un análisis comparativo de tres algoritmos que
resuelven el problema, basados en los métodos, KARATSUBA,
TRANSFORMADA RAPIDA DE FOURIER y la MULTIPLICACIÓN
DIRECTA.

Palabras claves: Karatsuba, Transformación Rapida de Fourier, Multiplicación


Directa.

1 Introducción

Este trabajo presenta un análisis comparativo entre tres algoritmos que resuelven el
problema de la Multiplicación de Enteros de N Dígitos (de 1 a 2048 dígitos). Este es
un problema que requiere de soluciones eficientes, especialmente para cálculos
matemáticos de gran complejidad.
El trabajo hace una descripción del problema y de los métodos a ser analizados, así
como de los resultados experimentales obtenidos de la comparación de dichos
métodos.

2 Descripción del problema

La multiplicación de dos enteros de N dígitos, donde N es un número relativamente


grande, representan un problema cuando estos superan la cantidad máxima de dígitos
representable por una computadora, cuyas arquitecturas limitan el número de enteros
que pueden representar.
3 Métodos que resuelven el problema

Se proponen los siguientes métodos que resuelven el problema:


• Karatsuba
• Transformación Rápida de Fourier (FFT)
• Multiplicación Directa

4 Análisis teórico

A continuación se realiza el análisis teórico de los métodos mencionados.

4.1 Karatsuba

El paso básico del algoritmo de Karatsuba es una fórmula que permite calcular el
producto de dos números relativamente grandes x e y, usando tres multiplicaciones de
números más pequeños, cada uno con más o menos de la mitad de los dígitos de x e y,
más algunas sumas y desplazamientos de dígitos.
Supongamos que x e y están representados como cadenas de n dígitos de alguna
base b uno puede dividir los dos números dados de la siguiente manera, donde n/2 es
un número redondeado por exceso:
x = x1bn/2 + x0 (1)

y = y1bn/2 + y0 (2)
n/2
Donde x0 e y0 son menores que b . El producto de xy es entonces:
n/2 n/2
xy = (x1b + x0) (y1b + y0)
n n/2
xy = x1y1b + (x1y0 + x0y1)b + x0y0 (3)

Por tanto podemos decir que para calcular xy hay que efectuar 4 productos entre
enteros de tamaño n/2. La recurrencia que se obtiene para este caso es:
T(n) = 4T(n/2 + O (n) (4)
2
y su coste asociado es O(n ) [1].
En el algoritmo propuesto por Karatsuba se aplica exactamente la misma
fragmentación que se acaba de utilizar, pero se reduce el número de nuevos productos
a calcular. Entonces, la fórmula (3) se puede reducir a 3 multiplicaciones haciendo
que el segundo término (x1y0 + x0y1) quede en relación con el primero (x 1y1) y con el
tercero (x0y0), por lo que:
(x1y0 + x0y1) = (x1 + x0) (y1 + y0) – x1y1 – x0y0 (5)
Por lo tanto tenemos que para obtener el segundo término bastará con hacer una
multiplicación y cuatro sumas (mucho menos costosas que las multiplicaciones).
Finalmente tenemos que para calcular las 3 multiplicaciones de números de n/2 cifras
necesarias para Karatsuba podemos modificar la fórmula (3) de la siguiente manera:
n n/2
xy = x1y1b + [(x1 + x0) (y1 + y0) – x1y1 – x0y0]b + x0y0 (6)
De este modo se calculan tres nuevos productos entre enteros de tamaño n/2 y
tenemos que la nueva recurrencia que se obtiene es:
T(n) = 3T(n/2) + O(n) (7)
1.57
y su coste asociado es O(n ).
Se tiene que, para un n suficientemente grande, el algoritmo de Karatsuba
realizará menos desplazamientos y sumas de un solo dígito que la multiplicación
clásica, incluso cuando su paso básico use más sumas y desplazamientos que la
fórmula sencilla. Para valores pequeños de n, sin embargo, los desplazamientos y
operaciones de suma pueden hacerlo ir más lentamente que el método a mano. Todo
depende de la plataforma del ordenador y del contexto. Por norma general, Karatsuba
normalmente más rápido cuando los multiplicandos son del orden 2320 ≈ 2×109 o
mayor [2].

4.2 Transformación Rápida de Fourier

Sean x0, x1 ...., xn-1 números complejos. La transformada discreta de Fourier (DFT),
por sus siglas en inglés) se define como:

(8)

2
La evaluación directa de esta fórmula requiere O(n ) operaciones aritméticas.
Mediante un algoritmo FFT se puede obtener el mismo resultado con sólo O(n log n)
operaciones. En general, dichos algoritmos dependen de la factorización de n pero, al
contrario de lo que frecuentemente se cree, existen FFT’s para cualquier n, incluso
con n primo.
La idea que permite esta optimización es la descomposición de la transformada a
tratar en otras más simples y éstas a su vez hasta llegar a transformadas de 2
elementos donde k puede tomar los valores 0 y 1. Una vez resueltas las transformadas
más simples hay que agruparlas en otras de nivel superior que deben resolverse de
nuevo y así sucesivamente hasta llegar al nivel más alto. Al final de este proceso, los
resultados obtenidos deben reordenarse [3].
4.3 Multiplicación Directa

La multiplicación directa presentada en este trabajo es una pequeña modificación del


algoritmo que nos enseñan en la escuela para calcular el producto de dos números. A
continuación describiremos brevemente este algoritmo y seguido, nuestro método de
multiplicación directa.
El método utilizado habitualmente para multiplicar dos números enteros se inicia
desde la derecha, teniendo cuidado con la ley de los signos y con colocar las unidades
de un orden bajo las unidades del mismo orden (unidades bajo unidades, decenas bajo
decenas, centenas bajo centenas, etc.). Luego se suman los productos de cada cifra del
segundo factor por todas las del primero.
En nuestro método se comienza de izquierda a derecha, teniendo en cuenta los
signos, realizando el producto de cada digito del multiplicando por todos los dígitos
del multiplicador, almacenándose el resultado en un array en la posición [i + j] donde
i es el contador del primer for y j el índice del segundo for. Si se debe almacenar
luego otro valor en la misma posición del array se suma al valor existente en ese
momento en dicha posición y así sucesivamente hasta que el contador del primer for
termine. Entonces tenemos guardados los dígitos en el array, nada más nos falta hacer
el acarreo, para lo cual tenemos un método específico encargado de esto. El coste de
2
este algoritmo es O (n ).

Algoritmo 1. Fragmento del código de Multiplicación Directa.


for (i = 0; i < multiplicando.ncifras; i++){
for (j = 0; j < multiplicador.ncifras; j++){
array.cifras[i + j] += multiplicando.cifras[i] *
multiplicador.cifras[j];
}
}

5 Resultados Experimentales

Dos de los algoritmos aquí analizados, Karatsuba y Transformación Rápida de


Fourier utilizan la técnica de divide y vencerás, por tanto estos algoritmos son
recursivos, mientras que el algoritmo de Multiplicación Directa es iterativo.
El algoritmo de Karatsuba aplica directamente el esquema de Divide y Vencerás.
Sin pérdida de generalidad, podemos suponer que el tamaño de los enteros a
multiplicar es n, es decir, cada entero ocupa n posiciones que pueden ser bits o
dígitos, y que n es potencia de dos. El tamaño de los enteros a multiplicar se puede
reducir dividiendo entre dos su longitud. De esta forma los dos enteros iniciales de
tamaño n se convierten en cuatro enteros de tamaño n/2. Una vez obtenidos los
fragmentos, se calculan recursivamente los nuevos productos entre ellos y luego se
combinan adecuadamente sus resultados para obtener el producto de los dos enteros
iniciales.
Para calcular el producto de 1234 y 5678, elija b = 10 y n/2 = 2. Entonces:

12 34 = 12 × 10 2+ 34
56 78 = 56 × 10 2 + 78
z 2= 12 × 56 = 672
z 0= 34 × 78 = 2652
z 1= (12 + 34) (56 + 78) - z 2- z 0= 46 × 134 - 672 - 2.652 = 2.840
resultado = z 2× 102 × 2 + z 1× 102+ z 0 = 672 × 2840 × 10000 + 100 + 2652 = 7006652
Fig. 1. Ejemplo de una multiplicación con el método de Karatsuba

La transformada rápida de Fourier es un algoritmo optimizado para calcular la


transformada discreta de Fourier (DFT) y su inversa. La FFT es de gran importancia
en una gran variedad de aplicaciones, desde el procesamiento de señales digitales a la
solución de ecuaciones diferenciales, a las derivadas parciales, a los algoritmos para
multiplicar números enteros de grandes dimensiones.

numero mult_FFT(numero x, numero y)


k = Calcular k tal que 2^k >= (cifras
de x)+(cifras de y)-1
/* Para trabajar con FFT hay que pasar
los números a un array de complejos */
xc = CifrasAComplejo(x, k)
yc = CifrasAComplejo(y, k)
/* Trasformamos los números */
xt = FFT (xc, k)
yt = FFT (yc, k)
/* Multiplicamos en el espacio transformado */
de i=0 a (2^k)-1
xytc = complejo_conjugado(xt[i]*yt[i])
/* Volvemos al espacio original */
xyc = complejo_conjugado(FFT(xytc,k))/2^k
/* Pasamos a cifras los complejos con el redondeo
FFT trabaja con double y numero con int */
xy = ComplejoACifras(xyc, k)
Acarreo(xy)
return xy
Fig. 2. Pseudocódigo para multiplicar con el método de FFT.

En la Fig. 3 se muestra un ejemplo de la multiplicación de dos números utilizando


el pseudocódigo mostrado en la Fig. 2 para hallar el producto con la técnica de FFT.

mult_FFT ( 197, 95 )
k = 2 ya que 2^2 >= 2+3-1
Hay que rellenar con 0 la parte imaginaria y hasta 2^k
xc = { {7,0}{9,0}{1,0}{0,0} }
yc={ {5,0}{9,0}{0,0}{0,0} }
Transformación
xt ={ {17,0}{6,-9}{-1,0}{6,9} }
yt ={ {14,0}{5,-9}{-4,0}{5,9} }
Multiplicación
xytc ={{238, -0}{-51, 99}{4, 0}{-51, -99}}
xyc = { {35,0}{108,0}{86,0}{9,0} }
xy = {35}{108}{86}{9}
haciendo el acarreo...
xy={5}{1}{7}{8}{1}

return xy

Fig. 3. Ejemplo de multiplicación de dos números mediante FFT.

La multiplicación directa, es un método muy simple que se enseña en las escuelas.


En la Fig.4 se muestra un ejemplo de dicho método.

2 3 9 5 8 2 3 3 Multiplicando
x 5 2 8 0 Multiplicador
0 0 0 0 0 0 0 0
1 9 1 6 6 5 8 6 4
4 7 9 1 6 4 6 6
1 1 9 7 9 1 1 6 5

1 2 6 4 9 9 4 7 0 2 4 0 Producto
Fig. 4. Ejemplo de multiplicación de dos números mediante FFT.

5.1 Comparaciones realizadas

Las siguientes comparaciones y resultados fueron obtenidos utilizando un computador


con procesador Intel Core2 Duo de 3.0 GHz. Y RAM de 1 GB.

Tabla1. Resultados de la comparación empírica para distintos tamaños de N para los


métodos analizados.
Métodos
Cantidad de
Karatsuba FFT Directa
Dígitos
Tiempo en ns
50 5737320 716012 8825004
150 7330954 786690 9613442
250 12584760 3890925 7209156
350 13697479 3066450 14283025
450 18017510 5546655 13162350
550 23773201 7288840 31133770
650 31530125 10385390 32356205
750 39823280 13649148 30231775
850 39038970 17212804 31279465
1050 26487440 12176615 87666030
1150 41748460 21394406 68018840
1250 33423801 14206620 66624668
1350 36880312 16884339 84959751
1450 41003250 19154875 90481400
1550 59662330 35643354 68077570
1650 52377601 25008972 68651180
1750 57810973 28173341 68179895
1850 72081151 31396030 69692726
1950 81745720 35201259 66867299
2048 84206441 38165603 81291407
Fig. 5. Gráfica que representa el tiempo en función a la cantidad de dígitos de los operandos.

Finalmente, podemos decir que si hay que multiplicar enteros de longitud superior a
500 bits ó dígitos conviene utilizar el algoritmo de Karatsuba, pero si los enteros son
más pequeños es más eficiente utilizar el algoritmo de Multiplicación Directa.
Además en todo caso es más eficiente el algoritmo de multiplicación Transformación
Rápida de Fourier (FFT).
En la Tabla2 se observa la complejidad de los algoritmos utilizados para este
trabajo.

Tabla2. Complejidad de los algoritmos estudiados.

Método Complejidad
Karatsuba O (n1.57)
FFT O (n log n)
Directa O (n2)

6 Conclusión

En conclusión, podemos decir que de los 3 algoritmos presentados, el FFT es el que


mejor comportamiento presenta en forma empírica y teórica, mientras que el
algoritmo de Karatsuba presenta un coste espacial para resolverlo y cuando el número
de dígitos no es muy grande no obtiene buenos resultados, en cambio cuando la N es
muy grande el coste espacial si consigue un gran ahorro temporal.
7 Referencias

[1] Aho, A. V. (1983). Data Structures and Algorithms . pp. 226

[2] A. Karatsuba and Yu. Ofman (1962). Multiplication of Many-Digital Numbers


by Automatic Computers. Proceedings of the USSR Academy of Sciences 145:
pp. 293-294

[3] Ramirez, R. W. The FFT: Fundamentals and Concepts. Englewood Cliffs, NJ:
Prentice-Hall, 1985.

You might also like