web-dev-qa-db-fra.com

Comment effectuer une multiplication à l'aide d'opérateurs au niveau des bits?

Je travaille sur un problème que j'ai pu résoudre, sauf pour le dernier élément - je ne sais pas comment faire pour multiplier à l'aide d'opérateurs au niveau du bit:

0*8 = 0

1*8 = 8

2*8 = 16 

3*8 = 24 

4*8 = 32

Pouvez-vous s'il vous plaît recommander une approche pour résoudre ce problème?

22
JAM

Pour multiplier par une valeur quelconque de 2 à la puissance de N (c'est-à-dire 2 ^ N), décaler les bits N fois vers la gauche. 

0000 0001 = 1 

times 4 = (2^2 => N = 2) = 2 bit shift : 0000 0100 = 4

times 8 = (2^3 -> N = 3) = 3 bit shift : 0010 0000 = 32

etc..

Pour diviser, décale les bits vers la droite.

Les bits sont entiers 1 ou 0 - vous ne pouvez pas décaler d'une partie d'un bit, donc si le nombre que vous multipliez par ne factorise pas une valeur entière de N. 

since: 17 = 16  + 1 
thus:  17 = 2^4 + 1

therefore: x * 17 = (x * 16) + x in other words 17 x's  

ainsi, pour multiplier par 17, vous devez effectuer un décalage de 4 bits vers la gauche, puis rajouter le numéro d'origine:

==> x * 17 = (x * 2^4) + x 
==> x * 17 = (x shifted to left by 4 bits) + x 

so let x = 3 = 0000 0011 

times 16 = (2^4 => N = 4) = 4 bit shift : 0011 0000 = 48

plus the x (0000 0011)

c'est à dire.

    0011 0000  (48)  
+   0000 0011   (3)
=============
    0011 0011  (51)

Modifier: mettre à jour la réponse d'origine. Charles Petzold a écrit un livre fantastique "Code" qui expliquera tout cela et plus encore de la manière la plus simple. Je le recommande vivement.

35
Preet Sangha

Pour multiplier deux nombres codés en binaire sans instruction de multiplication ..__, il serait simple d'ajouter itérativement pour atteindre le produit.

unsigned int mult(x, y)
unsigned int x, y;
{
    unsigned int reg = 0;

    while(y--)
        reg += x;
    return reg;
}

Avec les opérations sur les bits, il est possible d’exploiter la caractéristique du codage des données . Comme expliqué précédemment, un décalage de bits équivaut à une multiplication par deux . L’utilisation d’un additionneur peut être utilisée avec une puissance de deux.

// multiply two numbers with bit operations

unsigned int mult(x, y)
unsigned int x, y;
{
    unsigned int reg = 0;

    while (y != 0)
    {
        if (y & 1)
        {
            reg += x;
        }
        x <<= 1;
        y >>= 1;
    }
    return reg;
}
10
user2035522

Je crois que cela devrait être un virage à gauche. 8 est 2 ^ 3, donc décalage à gauche de 3 bits:

2 << 3 = 8

3
Jeff Ogata

Vous devez factoriser le multiplicande en puissances de 2.
3 * 17 = 3 * (16 + 1) = 3 * 16 + 3 * 1. ... = 0011b << 4 + 0011b

3
epic_fil
public static int multi(int x, int y){
        boolean neg = false;
        if(x < 0 && y >= 0){
            x = -x;
            neg = true;
        }
        else if(y < 0 && x >= 0){
            y = -y;
            neg = true;
        }else if( x < 0 && y < 0){
            x = -x;
            y = -y;
        }

        int res = 0;
        while(y!=0){
            if((y & 1) == 1) res += x;
            x <<= 1;
            y >>= 1;
        }
        return neg ? (-res) : res;
    }
3
Algorithmatic
-(int)multiplyNumber:(int)num1 withNumber:(int)num2
{
    int mulResult =0;
    int ithBit;

    BOOL isNegativeSign = (num1<0 && num2>0) || (num1>0 && num2<0)   ;
    num1 = abs(num1);
    num2 = abs(num2);


    for(int i=0;i<sizeof(num2)*8;i++)
    {
        ithBit =  num2 & (1<<i);
        if(ithBit>0){
            mulResult +=(num1<<i);
        }

    }

    if (isNegativeSign) {
        mulResult =  ((~mulResult)+1 );
    }

    return mulResult;
}
0
muzz

Je viens de me rendre compte que c'est la même réponse que la précédente. LOL désolé.

public static uint Multiply(uint a, uint b)
{
   uint c = 0;
   while(b > 0)
   {
      c += ((b & 1) > 0) ? a : 0;
      a <<= 1;
      b >>= 1;
   }
   return c;
}
0
Nicolas