如何在.NET中不使用乘法运算符来实现乘法

Pin*_*ong 3 .net c# operators multiplication

我想在.NET中实现两个整数的乘法而不使用乘法运算符

public uint MultiplyNumbers(uint x, uint y)
{

}
Run Code Online (Sandbox Code Playgroud)

任何的想法!

Jon*_*eet 25

我假设这是家庭作业......否则你没有理所当然的想法.所以我只是给出提示......

  • 如果性能不是非常重要,请考虑x * 3 = x + x + x......考虑使用循环.

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

  • 如果性能很重要并且两个数字都很大,那么你需要考虑一下这个问题.记住那x * 2x << 1,从那里开始.


Rob*_* P. 12

这违背了任务的精神,但我会为踢球而做...

创建自己的类,重载+运算符以进行乘​​法运算.

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

return new SuperInt(x) + SuperInt(y);
Run Code Online (Sandbox Code Playgroud)

其他人都会改变位移或添加.不管怎样,有一半的孩子会发布谷歌搜索返回的确切代码.至少这样,你将是独一无二的.

任务本身实际上只是横向思维的练习.在.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);
}
Run Code Online (Sandbox Code Playgroud)

输出:

5 * 6 = 30
-5 * 6 = -30
-5 * -6 = 30
5 * 1 = 5
Run Code Online (Sandbox Code Playgroud)

一条直接的代码行.

但是,如果你采取这种方法,请准备好争论一下.它确实乘以整数; 通过隐式将它们转换为调用中的双精度数.你的问题没有说你可以使用只有整数,只是它必须乘两个整数,而无需使用"*".

编辑:因为你说你不能改变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));
}
Run Code Online (Sandbox Code Playgroud)

附加答案#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());
}
Run Code Online (Sandbox Code Playgroud)

  • 要求Google解决方案+1:D (3认同)

Meh*_*dad 12

看,妈,没有*操作员!

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!
    }
}
Run Code Online (Sandbox Code Playgroud)

更好的是:

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(); }
    }
}
Run Code Online (Sandbox Code Playgroud)