2010-12-16 4 views
25

Comment multipiper deux entiers en utilisant des opérateurs au niveau du bit?Multiplication de deux entiers à l'aide d'opérateurs au niveau du bit

J'ai trouvé une implémentation here. Y a-t-il une meilleure façon de mettre en œuvre la multiplication?

Par exemple: 2 * 6 = 12 doit être effectué à l'aide d'opérateurs au niveau du bit.

REMARQUE: Les chiffres sont arbitraires et non puissance de 2

+0

Faut-il prendre des entiers arbitraires? Il existe un moyen facile d'implémenter la multiplication si l'un des opérandes doit être une puissance de deux. En outre, est-ce une tâche de devoir ou essayez-vous d'implémenter la multiplication dans l'assemblée sur un processeur avec un jeu d'instruction qui n'inclut pas la multiplication (ou les deux)? –

+0

puissance de deux mise en œuvre est facile, mais dans ce cas, les entiers ne sont pas la puissance de deux, ils sont arbitraires. Et ce n'est pas une question de devoirs, c'est une question d'entrevue. S'il vous plaît vérifier la mise en œuvre que j'ai attaché. – SuperMan

+0

Le lien dans la question n'existe pas –

Répondre

41
#include<stdio.h> 

main() 
{ 
    int a, b, result; 
    printf("\nEnter the numbers to be multiplied:"); 
    scanf("%d%d", &a, &b);  // a > b 
    result = 0; 
    while (b != 0)    // Iterate the loop till b == 0 
    { 
     if (b & 01)    // Bitwise & of the value of b with 01 
     { 
      result = result + a; // Add a to result if b is odd . 
     } 
     a<<=1;     // Left shifting the value contained in 'a' by 1 
            // Multiplies a by 2 for each loop 
     b>>=1;     // Right shifting the value contained in 'b' by 1. 
    } 
    printf("nResult:%d",result); 
} 

Source

+0

Pouvez-vous expliquer votre code ur? –

+1

@ Vector9 Avez-vous une chose spécifique à comprendre? Le cœur de la logique multiplie une valeur par 2 et l'additionne au résultat lorsque l'autre valeur est impaire.Il a utilisé le bit shift pour multiplier (à gauche)/diviser (à droite) les 2 entrées. Penser en termes d'opérateurs arithmétiques: 'while (b! = 0): if (b est impair) {résultat = résultat + a;} a = a * 2; b = b/2; Une astuce mathématique simple. @ L'astuce de Shiv est encore plus nette là où il a évité 'résultat = résultat + a' – zengr

+0

Oui, j'ai compris ce que nous faisions: a * b * (2/2) -> (a * 2) * (b/2). Ce que je n'ai pas compris, c'est pourquoi result = result + a est utilisé quand impair. –

2

algorithme de montage: Cela résulte directement du fait que ax * 7 = (ax * 8) ax.

mov  bx, ax   ;Save AX*1 
shl  ax, 1   ;AX := AX*2 
shl  ax, 1   ;AX := AX*4 
shl  ax, 1   ;AX := AX*8 
sub  ax, bx   ;AX := AX*7 

Chaque étape de changement est une multiplication par 2

1

En C# est ici la mise en œuvre de la fonction.

public static int Mul(int a, int b) 
    { 
     int r = 0; 
     while (b != 0) 
     { 
      var temp = b & 1; 

      if (temp!= 0) 
      { 
       r = r + a; 
      } 
      a= a << 1; 
      b= b >> 1; 
      if (temp == 0) 
      { 
       r = a; 
       break; 
      } 
     } 

     return r; 
    } 
+1

Cette réponse contient une erreur. J'ai soumis un edit, en demandant à un modérateur de supprimer l'erreur, et ce fut sa réponse: _Edits qui changent le code dans les réponses sont presque toujours rejetés. Vous devez laisser un commentaire sous la réponse, ou une nouvelle réponse de votre choix. L'erreur dans le code ci-dessus est 'if (temp == 0)'. L'instruction if complète, y compris la rupture, doit être supprimée. Pour voir cela, appelez la fonction avec les entrées de 1 et 4: Mul (1, 4), et la valeur de retour sera 2. Clairement 1 x 4 n'est pas 2. – Barzee

+0

ce code dirige à des erreurs. Et pourquoi n'avez-vous pas examiné les codes affichés (réponse acceptée)? –

5

Celui-ci est purement avec des opérations au niveau des bits.

public int bitwiseMultiply(int a, int b) { 
    if (a ==0 || b == 0) { 
     return 0; 
    } 

    if (a == 1) { 
     return b; 
    } 
    else 
     if (b == 1) { 
      return a; 
     } 


    int result = 0; // Not needed, just for test 
    int initA = a; 
    boolean isORNeeded = false; 
    while (b != 0) { 

     if (b == 1) { 
      break; 
     } 

     if ((b & 1) == 1) { // Carry needed, odd number 
      result += initA; // Test, not needed 
      isORNeeded = true; 
     } 

     a <<= 1; // Double the a 
     b >>= 1; // Half the b 
     System.out.println("a=["+a+"], b=["+b+"], result=["+result+"]"); 
    } 

    return (isORNeeded ? (a | initA) : a); // a + result; 
} 
0
#include<stdio.h> 
    void main() 
    { 
     int n, m, i, j, x, large, small, t1, m2, result, a1, a2, a3, c, c1, c2, r, r1, la, re; 

     printf("Enter two numbers\n"); 
     scanf("%d%d", &n, &m); 
     result = 0; 

     if (n > m) 
     { 
      large = n; 
      small = m; 
     } 
     else 
     { 
      large = m; 
      small = n; 
     } 

     c = 0; 

     while (small) 
     { 
      t1 = small; 
      t1 &= 1; 

      if (t1 == 1) 
      { 
       printf("\n %d", large); 
       la = large; 
       re = result; 
       m2 = 0; 
       r1 = 1; 
       while (re || la || c) 
       { 
        a2 = la; 
        a2 &= 1; 
        a3 = re; 
        a3 &= 1; 

        c1 = a2 & a3; 
        r = a3^a2; 

        c2 =r & c; 
        r ^= c; 
        if (c1 || c2) 
         c = 1; 
        else 
         c = 0; 

        result &= ~r1; 
        x = r; 
        m2 >>= 1; 
        while (m2) 
        { 
         r <<= 1; 
         m2 >>= 1; 
        } 

        result |= r; 
        la >>= 1; 
        re >>= 1; 
        r1 <<= 1; 
        m2 = r1; 
       } 

      } 
      large <<= 1; 
      small >>= 1; 

     } 
     printf("\n%dX%d= %d\n", n, m, result); 
    } 
11

Je suis venu ici à la recherche de cette question et je trouve la réponse de Zengr correcte. Merci Zengr! Mais il y a une modification que je voudrais voir qui se débarrasse de l'opérateur '+' dans son code. Ceci devrait faire la multiplication de deux nombres arbitraires en utilisant AUCUN OPÉRATEUR ARITHMÉTIQUE mais tous les bits.

solution de Zengr première:

#include<stdio.h> 
main() 
{ 
    int a,b,result;  
    printf("nEnter the numbers to be multiplied :"); 
    scanf("%d%d",&a,&b);   // a>b 
    result=0; 
    while(b != 0)    // Iterate the loop till b==0 
    { 
     if (b&01)    // Bitwise & of the value of b with 01 
     { 
      result=result+a;  // Add a to result if b is odd . 
     } 
     a<<=1;     // Left shifting the value contained in 'a' by 1 
          // multiplies a by 2 for each loop 
     b>>=1;     // Right shifting the value contained in 'b' by 1. 
    } 
    printf("nResult:%d",result); 
} 

Ma réponse est:

#include<stdio.h> 
main() 
{ 
    int a,b,result;  
    printf("nEnter the numbers to be multiplied :"); 
    scanf("%d%d",&a,&b);   // a>b 
    result=0; 
    while(b != 0)    // Iterate the loop till b==0 
    { 
     if (b&01)    // Bitwise & of the value of b with 01 
     { 
      result=add(result,a);  // Add a to result if b is odd . 
     } 
     a<<=1;     // Left shifting the value contained in 'a' by 1 
           // multiplies a by 2 for each loop 
     b>>=1;     // Right shifting the value contained in 'b' by 1. 
    } 
    printf("nResult:%d",result); 
} 

où je voudrais écrire ajouter() comme:

int Add(int x, int y) 
{ 
    // Iterate till there is no carry 
    while (y != 0) 
    { 
     // carry now contains common set bits of x and y 
     int carry = x & y; 

     // Sum of bits of x and y where at least one of the bits is not set 
     x = x^y; 

     // Carry is shifted by one so that adding it to x gives the required sum 
     y = carry << 1; 
    } 
    return x; 
} 

ou en ajoutant récursive comme:

int Add(int x, int y) 
{ 
    if (y == 0) 
     return x; 
    else 
     return Add(x^y, (x & y) << 1); 
} 

source pour le code additionnel: http://www.geeksforgeeks.org/add-two-numbers-without-using-arithmetic-operators/

Questions connexes