Método de multiplicación que desconozco

Iniciado por kutcher, 15 Octubre 2014, 01:41 AM

0 Miembros y 1 Visitante están viendo este tema.

kutcher

Buenas noches, estoy estudiando un algoritmo que realiza una multiplicación de dos enteros almacenados en respectivos arrays, el problema es que no consigo entender el método utilizado en tal caso, ya que existen varios :

void longmulti(const char *a, const char *b, char *c)
{
    int i = 0, j = 0, k = 0, n, carry;
    int la, lb;

    la = strlen(a);
    lb = strlen(b);

    memset(c, '0', la + lb);
    c[la + lb] = '\0';

    for (i = la - 1; i >= 0; i--)
    {
        for (j = lb - 1, k = i + j + 1, carry = 0; j >= 0; j--, k--)
        {
            n = T(a[i]) * T(b[j]) + T(c[k]) + carry;
            carry = n / 10;
            c[k] = (n % 10) + '0';
        }
        c[k] += carry;
    }
    if (c[0] == '0')
       memmove(c, c + 1, la + lb);

    return;
}


Saludos

leosansan

#1
Cita de: kutcher en 15 Octubre 2014, 01:41 AM
Buenas noches, estoy estudiando un algoritmo que realiza una multiplicación de dos enteros almacenados en respectivos arrays, el problema es que no consigo entender el método utilizado en tal caso, ya que existen varios :
.....................................
Saludos

Este algoritmo es la clásica multiplicación:

Código (cpp) [Seleccionar]

 
   1 2 3      <== indice: j = 2 1 0
   x 2 3      <== indice: i =   1 0
  -------
   3 6 9      <== i = 3 * j = 3 2 1
 2 4 6    <== i = 2 * j = 3 2 1
 ----------
 2 7 12 9
-----------
0 2 8  2 9   <== indice: k = 0 1 2 3 4

De izquierda derecha:

"FALTA": carry = 0 ;

c[0] =  '0'
c[4] =  9 % 10 +  + acarreo + '0' = '9' ===>  carry = acarreo =  9 / 10 = 0
c[3] = 12 % 10 +  + acarreo + '0' = '2' ===>  carry = acarreo = 12 / 10 = 1
c[2] =  7 % 10 +  + acarreo + '0' = '8' ===>  carry = acarreo =  8 / 10 = 0
c[1] =  2 % 10 +  + acarreo + '0' = '2' ===>  carry = acarreo =  2 / 10 = 0

c[0] +=   acarreo + (  Esto falta  ) '0' = '0'

c[5] = c[ la + lb ] = '\0' <==  Esto esta al principio

c  = 02829

if ( acarreo == 0 o lo que es lo mismo, si c[0] == '0' )

 desplazo todos los caracteres del array "c" una posicion a la izquierda" :

  memmove ( c , c + 1 , la + lb ) ; ==> c = 2829

Observacion; lo siguiente es para trabajar con enteros

n = T(a[i]) * T(b[j]) + T(c[k]) + carry = a[i] - '0' + b[j] - '0' + c[k] - '0'  + carry


Más o menos así es el esquema que sigue un código simple de multiplicación.  ;)

¡¡¡¡ Saluditos! ..... !!!!



EDITADO con la observación de kutcher, no sé en que estaría pensando.  ;)

kutcher

#2
Cita de: leosansan en 15 Octubre 2014, 07:21 AM
Este algoritmo es la clásica multiplicación:

Efectivamente al parecer se trata del método mencionado, pero en el esquema que has hecho, el resultado que obtienes creo es incorrecto debería ser 2829 en ves de 3936 todo esto debido a la alineación del segundo producto parcial a la derecha, he hecho un seguimiento minucioso al algoritmo y trabaja mas o menos asi :

Código (cpp) [Seleccionar]
 1 2 3
 x
   2 3
----------
  1// carry
 +
2 4 6 9   //(4 = c[k]) (9 = 3 * 3) (6 = 2 * 3) (2 = 2 * 1)
  --
  5 6     //(5 = c[k]) (6 = 3 * 2)
 +
  3       // (3 = 3 * 1)
----------
2 8 2 9


Saludos leosansan un gusto volverte a ver escribir

leosansan

Cita de: kutcher en 15 Octubre 2014, 18:24 PM
....................................................
Saludos leosansan un gusto volverte a ver escribir

Igualmente amigo kutcher.

Me permito hacerte una pequeña observación respecto a ese código para multiplicar y es que debido a los dos for recurrentes si los dos números son cada uno de 1000 cifras habría que realizar un millón (¡¡¡1.000.000¡¡¡ ni más ni menos) de operaciones "/" y "%".

Si lo analizas verás que con un array temporal ese número se reduce a la suma de cifras, es decir ¡¡¡¡2.000 tan sólo ¡¡¡¡¡.

No cuelgo código por razones que entenderás, pero si estas interesado me envías un mp.

Un fuerte saludo de León.