I want to implement multiplication of two integer numbers without using multiplication operator, in .NET
我想在。net中不使用乘法运算符来实现两个整数的乘法运算。
public uint MultiplyNumbers(uint x, uint y)
{
}
Any idea!
任何想法!
7 个解决方案
#1
25
I'm assuming this is homework... otherwise there's no sane reason you'd want to do it. Therefore I'll just give hints...
我假设这是作业…否则你就没有理智的理由去做这件事。所以我会给你一些提示…
-
If performance isn't terribly important, consider that
x * 3 = x + x + x
... think about using a loop.如果性能不是非常重要,考虑x * 3 = x + x + x…考虑使用循环。
-
If performance is important but you know that one of the numbers will be small, loop on the smaller number.
如果性能很重要,但是你知道其中一个数字会很小,在较小的数字上循环。
-
If performance is important and both numbers could be large, you'll need to think about bit-twiddling. Remember that
x * 2
isx << 1
, and go from there.如果性能很重要,而且这两个数字都可能很大,那么你就需要考虑一些琐碎的事情。记住x * 2 = x << 1,然后从这里开始。
#2
12
It goes against the spirit of the assignment, but I'd do it for kicks...
这违背了任务的精神,但我愿意为之而战……
Create your own class, overload the + operator to do multiplication.
创建自己的类,重载+运算符来做乘法。
Create your homework project; add your first project as a reference. Write your code to be
创建作业项目;添加您的第一个项目作为参考。把你的代码写下来。
return new SuperInt(x) + SuperInt(y);
Everyone else is going to some variation of shifting bits or addition. Half of the kids are going to post the exact code returned by a Google search anyway. At least this way, you'll be unique.
每个人都有一些变化的比特或加法。有一半的孩子会把谷歌搜索返回的确切代码发布出来。至少这样,你是独一无二的。
The assignment itself is really just an exercise in lateral thinking. Any sane person would use the * operator when working in .Net.
作业本身只是横向思维的练习。任何神智正常的人在。net工作时都会使用*操作符。
EDIT: If you really want to be a class clown - overload the * operator and implement it with bitwise operations and addition.
编辑:如果你真的想成为一个类小丑-重载*操作符并使用位操作和加法实现它。
Additional Answer #1 (if you are willing to change your method signature...) What about this?
附加答案#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);
}
Outputs:
输出:
5 * 6 = 30
-5 * 6 = -30
-5 * -6 = 30
5 * 1 = 5
One straight-forward line of code.
一个简单的代码行。
But still, if you take this approach, be prepared to argue a bit. It does multiply integers; by implicitly converting them to doubles in the call. Your question didn't say you could use only integers, just that it had to multiply two integers without using '*'.
但是,如果你采用这种方法,就要准备好争辩。它用整数;通过隐式地将它们转换为调用中的double。你的问题并不是说你只能用整数,只需要用两个整数相乘而不用“*”。
EDIT: Since you say you can't change the signature of MultiplyNumbers - you can accomplish it without doing that:
编辑:既然你说你不能更改多号数字的签名,你可以不这样做:
static uint MultiplyNumbers(uint x, uint y)
{
return MultiplyDouble(x, y);
}
static uint MultiplyDouble(double x, double y)
{
return Convert.ToUInt32(x / (1 / y));
}
Additional Answer #2 This is my favorite approach yet.
附加答案#2这是我最喜欢的方法。
Take the values, send them to Google, parse the result.
取值,将其发送到谷歌,解析结果。
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());
}
#3
12
Look, ma, no *
operator!
听着,妈,不要操作!
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!
}
}
Even better:
更好的是:
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(); }
}
}
#4
4
You can simply loop for x
times, adding y
to a running total on each iteration.
您可以简单地循环x次,在每次迭代中增加y的运行总数。
#5
4
Repeated addition would work. Add 'x' to a running total 'y' times.
重复工作。将“x”添加到运行的总“y”时间。
var total = 0;
for(int i = 0; i < y; i++)
{
total += x;
}
#6
4
You can use bitwise operators to do multiplication.
你可以使用位运算符来做乘法运算。
x<<1
is x*2 and so on.
是x*2等等。
You will still have to do some addition.
你仍然需要做一些加法。
result=0;
while(b != 0)
{
if (b&01)
{
result=result+a;
}
a<<=1;
b>>=1;
}
From: Multiplication of two integers using bitwise operators
从:使用位运算符的两个整数相乘。
#7
1
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;
}
#1
25
I'm assuming this is homework... otherwise there's no sane reason you'd want to do it. Therefore I'll just give hints...
我假设这是作业…否则你就没有理智的理由去做这件事。所以我会给你一些提示…
-
If performance isn't terribly important, consider that
x * 3 = x + x + x
... think about using a loop.如果性能不是非常重要,考虑x * 3 = x + x + x…考虑使用循环。
-
If performance is important but you know that one of the numbers will be small, loop on the smaller number.
如果性能很重要,但是你知道其中一个数字会很小,在较小的数字上循环。
-
If performance is important and both numbers could be large, you'll need to think about bit-twiddling. Remember that
x * 2
isx << 1
, and go from there.如果性能很重要,而且这两个数字都可能很大,那么你就需要考虑一些琐碎的事情。记住x * 2 = x << 1,然后从这里开始。
#2
12
It goes against the spirit of the assignment, but I'd do it for kicks...
这违背了任务的精神,但我愿意为之而战……
Create your own class, overload the + operator to do multiplication.
创建自己的类,重载+运算符来做乘法。
Create your homework project; add your first project as a reference. Write your code to be
创建作业项目;添加您的第一个项目作为参考。把你的代码写下来。
return new SuperInt(x) + SuperInt(y);
Everyone else is going to some variation of shifting bits or addition. Half of the kids are going to post the exact code returned by a Google search anyway. At least this way, you'll be unique.
每个人都有一些变化的比特或加法。有一半的孩子会把谷歌搜索返回的确切代码发布出来。至少这样,你是独一无二的。
The assignment itself is really just an exercise in lateral thinking. Any sane person would use the * operator when working in .Net.
作业本身只是横向思维的练习。任何神智正常的人在。net工作时都会使用*操作符。
EDIT: If you really want to be a class clown - overload the * operator and implement it with bitwise operations and addition.
编辑:如果你真的想成为一个类小丑-重载*操作符并使用位操作和加法实现它。
Additional Answer #1 (if you are willing to change your method signature...) What about this?
附加答案#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);
}
Outputs:
输出:
5 * 6 = 30
-5 * 6 = -30
-5 * -6 = 30
5 * 1 = 5
One straight-forward line of code.
一个简单的代码行。
But still, if you take this approach, be prepared to argue a bit. It does multiply integers; by implicitly converting them to doubles in the call. Your question didn't say you could use only integers, just that it had to multiply two integers without using '*'.
但是,如果你采用这种方法,就要准备好争辩。它用整数;通过隐式地将它们转换为调用中的double。你的问题并不是说你只能用整数,只需要用两个整数相乘而不用“*”。
EDIT: Since you say you can't change the signature of MultiplyNumbers - you can accomplish it without doing that:
编辑:既然你说你不能更改多号数字的签名,你可以不这样做:
static uint MultiplyNumbers(uint x, uint y)
{
return MultiplyDouble(x, y);
}
static uint MultiplyDouble(double x, double y)
{
return Convert.ToUInt32(x / (1 / y));
}
Additional Answer #2 This is my favorite approach yet.
附加答案#2这是我最喜欢的方法。
Take the values, send them to Google, parse the result.
取值,将其发送到谷歌,解析结果。
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());
}
#3
12
Look, ma, no *
operator!
听着,妈,不要操作!
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!
}
}
Even better:
更好的是:
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(); }
}
}
#4
4
You can simply loop for x
times, adding y
to a running total on each iteration.
您可以简单地循环x次,在每次迭代中增加y的运行总数。
#5
4
Repeated addition would work. Add 'x' to a running total 'y' times.
重复工作。将“x”添加到运行的总“y”时间。
var total = 0;
for(int i = 0; i < y; i++)
{
total += x;
}
#6
4
You can use bitwise operators to do multiplication.
你可以使用位运算符来做乘法运算。
x<<1
is x*2 and so on.
是x*2等等。
You will still have to do some addition.
你仍然需要做一些加法。
result=0;
while(b != 0)
{
if (b&01)
{
result=result+a;
}
a<<=1;
b>>=1;
}
From: Multiplication of two integers using bitwise operators
从:使用位运算符的两个整数相乘。
#7
1
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;
}