如何在.net中实现不使用乘法运算符的乘法

本文关键字:运算符 net 实现 | 更新日期: 2023-09-27 17:54:43

我想实现两个整数的乘法而不使用乘法运算符,在。net

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

任何想法!

如何在.net中实现不使用乘法运算符的乘法

我假设这是家庭作业…否则你就没有理由这么做了。因此,我将给出提示…

  • 如果性能不是非常重要,考虑x * 3 = x + x + x

  • 如果性能很重要,但您知道其中一个将很小,则循环较小的数字。

  • 如果性能很重要,并且两个数字都可能很大,那么您需要考虑位旋转。记住x * 2x << 1,从这里开始。

这违背了任务的精神,但我愿意这样做。

创建自己的类,重载+操作符进行乘法运算。

创建作业项目;添加您的第一个项目作为参考。把你的代码写成

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

其他所有人都要做一些移位或加法的变化。不管怎样,有一半的孩子会发布由Google搜索返回的精确的代码。至少这样,你是独一无二的。

作业本身就是横向思维的练习。任何理智的人在。net中工作时都会使用*操作符。

编辑:如果你真的想成为一个类小丑-重载*操作符并通过位操作和加法来实现它。

附加答案#1(如果你愿意改变你的方法签名…)这个呢?

static void Main(string[] args)
{
    Console.WriteLine(string.Format("{0} * {1} = {2}", 5, 6, MultiplyNumbers(5, 6)));
    Console.WriteLine(string.Format("{0} * {1} = {2}", -5, 6, MultiplyNumbers(-5, 6)));
    Console.WriteLine(string.Format("{0} * {1} = {2}", -5, -6, MultiplyNumbers(-5, -6)));
    Console.WriteLine(string.Format("{0} * {1} = {2}", 5, 1, MultiplyNumbers(5, 1)));
    Console.Read();
}

static double MultiplyNumbers(double x, double y)
{
    return x / (1 / y);
}

输出:

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

一行直接的代码。

但是,如果你采用这种方法,准备好争论一下。它可以做整数乘法;通过在调用中将它们隐式地转换为双精度。你的问题并没有说你只能使用整数,只是说它必须在不使用'*'的情况下将两个整数相乘。

编辑:既然你说你不能改变MultiplyNumbers的签名-你可以不这样做来完成它:

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

补充答案#2这是我最喜欢的方法。

获取这些值,将它们发送给Google,解析结果。

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

看,妈,没有*操作符!

<罢工>

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!
    }
}

更好:

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.FromBase64String("i0QkBA+vRCQIww==")
            : Convert.FromBase64String("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(); }
    }
}

您可以简单地循环x次,将y添加到每次迭代的运行总数中。

重复相加即可。将'x'加到总运行次数'y'上。

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

可以使用位运算符进行乘法运算。

x<<1

= x*2,依此类推

你仍然需要做一些加法。

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

From:使用位运算符

进行两个整数的乘法运算
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;
}