45 votes

Comment puis-je effectuer une multiplication sans l'opérateur '*' ?

J'étais juste en train de passer en revue quelques trucs de base comme j'apprends le C. Je suis tombé sur une question pour multiplier un nombre par 7 sans utiliser l'opérateur *. En gros, c'est comme ça

      (x << 3) - x;

Maintenant, je connais les opérations de base de manipulation des bits, mais je n'arrive pas à comprendre comment multiplier un nombre par tout autre nombre impair sans utiliser l'opérateur * ? Existe-t-il un algorithme général pour cela ?

8 votes

C'est (8*x)-x ou 7x.

2 votes

Notez que la plupart des compilateurs optimisent déjà ce genre de choses. Par exemple, transformer 15*x en ((x<<4)-x))

2 votes

Algèbre :) - (x << 3) - x = 8 * x - x = (8 - 1) * x = 7 * x L'astuce est que x << 3 == x * 2^3 == 8

59voto

Wayne Conrad Points 31052

Pensez à la façon dont vous multipliez en décimal en utilisant un crayon et du papier :

  12
x 26
----
  72
 24
----
 312

A quoi ressemble une multiplication en binaire ?

   0111
x  0101
-------
   0111
  0000
 0111
-------
 100011

Vous avez remarqué quelque chose ? Contrairement à la multiplication en décimal, où vous devez mémoriser la "table des temps", lorsque vous multipliez en binaire, vous multipliez toujours l'un des termes par 0 ou 1 avant de l'écrire dans la liste des additifs. Il n'y a pas besoin de table de multiplication. Si le chiffre du deuxième terme est 1, vous ajoutez le premier terme. S'il est égal à 0, vous ne le faites pas. Notez également comment les additions sont progressivement déplacées vers la gauche.

Si vous n'en êtes pas sûr, faites quelques multiplications binaires sur papier. Lorsque vous avez terminé, convertissez le résultat en décimal et voyez s'il est correct. Après en avoir fait quelques-unes, je pense que vous aurez une idée de la façon dont la multiplication binaire peut être mise en œuvre en utilisant des décalages et des additions.

25voto

Jim C Points 4736

Tout le monde oublie l'évidence. Il n'y a pas de multiplication :

10^(log10(A) + log10(B))

2 votes

Ce qui, en C, serait exp(log(A) + log(B)) .

3 votes

Je suppose que vous êtes sarcastique, mais si vous ne l'êtes pas, avez-vous déjà regardé le code source de logn ?

7 votes

Je l'ai vu comme une leçon d'histoire plutôt que comme un sarcasme. Les gens d'aujourd'hui ont tendance à oublier que nous faisions des choses avant d'avoir des ordinateurs ou même des calculatrices électroniques. J'ai vu trop d'ingénieurs et de programmes qui acceptent le résultat de la "boîte magique" sans comprendre comment elle fonctionne. Personne ne peut tout savoir, mais nous devrions comprendre autant que possible. Je connais l'algorithme général de calcul des logs, mais j'admets ne pas les avoir étudiés en profondeur. Ils impliquent souvent un décalage, ce qui revient à multiplier en binaire, comme l'ont souligné de nombreuses personnes. Ce n'est pas inattendu, les premiers CPUS ne peuvent qu'additionner et décaler.

23voto

Carlos Gutiérrez Points 5790

La question dit :

Multiplier un nombre par 7 sans utiliser l'opérateur *.

Cela n'utilise pas * :

 number / (1 / 7) 

Edit :
Cela compile et fonctionne bien en C :

 int number,result;
 number = 8;
 result = number / (1. / 7);
 printf("result is %d\n",result);

0 votes

+1 pour l'idée, mais cela ne fonctionnera pas en Java : java.lang.ArithmeticException: / by zero puisque (1 / 7) est fait par division entière (la solution de contournement est facile)

0 votes

En fait, ça ne marchera pas non plus en C ! Je suis presque sûr que vous obtiendriez un core dump si vous exécutez cette ligne :).

0 votes

Échouera probablement pour certaines valeurs en raison des arrondis. Échouera si votre int est de 64 bits et number est supérieure à 2^51 ou plus...

19voto

Un décalage vers la gauche d'un nombre entier est une multiplication par 2, à condition qu'il ne déborde pas. Il suffit d'ajouter ou de soustraire comme il convient une fois que l'on est proche.

17voto

int multiply(int multiplicand, int factor)
{
    if (factor == 0) return 0;

    int product = multiplicand;
    for (int ii = 1; ii < abs(factor); ++ii) {
        product += multiplicand;
    }

    return factor >= 0 ? product : -product;
}

Vous vouliez une multiplication sans * tu l'as, mon pote !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X