Comment implémenter la multiplication sans utiliser d’opérateur de multiplication dans .NET

Je veux implémenter la multiplication de deux nombres entiers sans utiliser d’opérateur de multiplication, en .NET

public uint MultiplyNumbers(uint x, uint y) { } 

Une idée!

Je suppose que c’est un devoir … sinon, il n’y a aucune raison sensée de vouloir le faire. Par conséquent, je vais juste donner des conseils …

  • Si les performances ne sont pas très importantes, considérez que x * 3 = x + x + x … pensez à utiliser une boucle.

  • Si la performance est importante mais que vous savez qu’un des nombres sera petit, bouclez sur le plus petit nombre.

  • Si les performances sont importantes et que les deux chiffres peuvent être importants, vous devrez penser à des tordus. Rappelez-vous que x * 2 est x << 1 , et allez de là.

Cela va à l’esprit de la mission, mais je le ferais pour des coups de pied …

Créez votre propre classe, surchargez l’opérateur + pour effectuer la multiplication.

Créez votre projet de devoirs ajoutez votre premier projet comme référence. Ecrivez votre code pour être

 return new SuperInt(x) + SuperInt(y); 

Tout le monde va à une variation de décalage de bits ou d’addition. La moitié des enfants vont quand même publier le code exact renvoyé par une recherche Google. Au moins de cette façon, vous serez unique.

La mission elle-même n’est en réalité qu’un exercice de pensée latérale. Toute personne sensée utiliserait l’opérateur * pour travailler en .Net.

EDIT: Si vous voulez vraiment être un clown de classe – surchargez l’opérateur * et implémentez-le avec des opérations au niveau des bits et de l’addition.

Réponse supplémentaire n ° 1 (si vous êtes prêt à changer la signature de votre méthode …) Qu’en est-il?

 static void Main(ssortingng[] args) { Console.WriteLine(ssortingng.Format("{0} * {1} = {2}", 5, 6, MultiplyNumbers(5, 6))); Console.WriteLine(ssortingng.Format("{0} * {1} = {2}", -5, 6, MultiplyNumbers(-5, 6))); Console.WriteLine(ssortingng.Format("{0} * {1} = {2}", -5, -6, MultiplyNumbers(-5, -6))); Console.WriteLine(ssortingng.Format("{0} * {1} = {2}", 5, 1, MultiplyNumbers(5, 1))); Console.Read(); } static double MultiplyNumbers(double x, double y) { return x / (1 / y); } 

Les sorties:

 5 * 6 = 30 -5 * 6 = -30 -5 * -6 = 30 5 * 1 = 5 

Une ligne de code simple.

Néanmoins, si vous adoptez cette approche, soyez prêt à en discuter un peu. Il multiplie les entiers; en les convertissant implicitement en doubles dans l’appel. Votre question ne disait pas que vous ne pouviez utiliser que des entiers, mais simplement qu’elle devait multiplier deux entiers sans utiliser ‘*’.

EDIT: Puisque vous dites que vous ne pouvez pas changer la signature de MultiplyNumbers – vous pouvez le faire sans le faire:

 static uint MultiplyNumbers(uint x, uint y) { return MultiplyDouble(x, y); } static uint MultiplyDouble(double x, double y) { return Convert.ToUInt32(x / (1 / y)); } 

Réponse supplémentaire n ° 2 C’est encore mon approche préférée.

Prenez les valeurs, envoyez-les à Google, parsingz le résultat.

 static uint MultiplyNumbers(uint x, uint y) { System.Net.WebClient myClient = new System.Net.WebClient(); ssortingng sData = myClient.DownloadSsortingng(ssortingng.Format("http://www.google.com/search?q={0}*{1}&btnG=Search",x,y)); ssortingng ans = x.ToSsortingng() + " * " + y.ToSsortingng() + " = "; int iBegin = sData.IndexOf(ans,50) + ans.Length ; int iEnd = sData.IndexOf('<',iBegin); return Convert.ToUInt32(sData.Substring(iBegin, iEnd - iBegin).Trim()); } 

Regarde, mec, pas d’opérateur!

 using System; using System.Reflection.Emit; static class Program { delegate uint UintOpDelegate(uint a, uint b); static void Main() { var method = new DynamicMethod("Multiply", typeof(uint), new Type[] { typeof(uint), typeof(uint) }); var gen = method.GetILGenerator(); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Mul); gen.Emit(OpCodes.Ret); var del = (UintOpDelegate)method.CreateDelegate(typeof(UintOpDelegate)); var product = del(2, 3); //product is now 6! } } 

Encore mieux:

 using System; using System.Runtime.InteropServices; delegate uint BinaryOp(uint a, uint b); static class Program { [DllImport("kernel32.dll", SetLastError = true)] static extern bool VirtualProtect( IntPtr address, IntPtr size, uint protect, out uint oldProtect); static void Main() { var bytes = IntPtr.Size == sizeof(int) //32-bit? It's slower BTW ? Convert.FromBase64Ssortingng("i0QkBA+vRCQIww==") : Convert.FromBase64Ssortingng("D6/Ki8HD"); var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); try { uint old; VirtualProtect(handle.AddrOfPinnedObject(), (IntPtr)bytes.Length, 0x40, out old); var action = (BinaryOp)Marshal.GetDelegateForFunctionPointer( handle.AddrOfPinnedObject(), typeof(BinaryOp)); var temp = action(3, 2); //6! } finally { handle.Free(); } } } 

Vous pouvez simplement boucler x fois, en ajoutant y à un total cumulé à chaque itération.

Une addition répétée fonctionnerait. Ajoutez «x» à un total cumulé «y» fois.

 var total = 0; for(int i = 0; i < y; i++) { total += x; } 

Vous pouvez utiliser des opérateurs au niveau des bits pour effectuer la multiplication.

 x<<1 

est x * 2 et ainsi de suite.

Vous devrez toujours faire quelques ajouts.

  result=0; while(b != 0) { if (b&01) { result=result+a; } a<<=1; b>>=1; } 

De: Multiplication de deux entiers à l'aide d'opérateurs au niveau du bit

 public uint MultiplyNumbers(uint x, uint y) { if (x == 0 || y == 0) return 0; uint answer = x; for (uint i = 1; i < y; ++i) answer += x; return answer; }