我有问题。 我试图找到右移操作的组合。 一个例子。 我有一个输入:
让我们说30。 我现在要找a和b,这样一个>> b = mynumber(30)。
这是我的尝试:
private static Random rnd = new Random();
private static int[] FindRightShift(int value)
{
int[] arr = new int[2];
for (int i = 1; i < int.MaxValue; i++)
{
int b;
if (int.TryParse((Math.Log(i / value) / Math.Log(2)).ToString(), out b))
{
arr[0] = i;
arr[1] = b;
Console.WriteLine("{0} >> {1} = {2}", arr[0], arr[1], arr[0] >> arr[1]);
// return arr;
}
}
return arr;
}
这可行,但它需要很长时间,因为它循环通过所有组合。 如何修改我的函数,以便它返回一个随机组合(a和b)而不循环遍历所有?
答案 0 :(得分:1)
我昨天发送了我的更新版本,据我测试,一切似乎都运行良好。 欢迎任何更正。
主要概念是关于正确转变的一些数学: x / 2 ^ y =数字 (其中^表示权力)
int maxPower = (int)Math.Log(int.MaxValue, 2); // 30 -> max power to not exceed int.MaxValue
maxPower = (int)Math.Log(Math.Pow(2, maxPower) / number, 2); // prevent "NOTE1" > int.MaxValue
for (int y = 0; y < maxPower; y++) // outputs all possible numbers; can be replaced with Random.Next(1, maxPower+1)
{
int sub = (int)Math.Pow(2, y);
int x = number * sub; // NOTE1
Console.WriteLine("{0} >> {1} = {2}", x, y, x >> y);
}
答案 1 :(得分:1)
当前设置的主要问题是,它不会检查移位是否导致位“关闭”。 以字节为例,数字12将是: 00001100
意味着可以向左移动的最大字节数为4.反之亦然,使用y
的示例语法,最多也可以是4(并且x
最大值为192)
对于整数和其他有符号变量,有一个额外的行为,当移动一个负值时,第一个(符号)位被区别对待(参见最后一段here)。
将正位数1073741824(1&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&amp 。所有这些意味着,最大移位的检查在正值和负值之间是不同的。
想到的方法是确定可以向左移动以确定最大值的最大位数,然后执行随机(1,y)以获得&#39; ý&#39;使用,并简单地向左移动数字y以获得x。
private static void FindRightShift(int number)
{
int maxshifts = 0, nr = number;
Func<bool> check;
if (number < 0) check = () => nr > (int.MinValue >> 1); else check = () => nr < (1 << 30);
while (check())
{
nr <<= 1;
maxshifts++; //you could also opt to do a random break here
}
if (maxshifts ==0)
throw new ArgumentException("Invalid number");
int y = R.Next(1, maxshifts), x = number << y;
//Debug.Assert((x >> y) == number);
Console.WriteLine("{0} >> {1} = {2} (maxshifts: {3})", x, y, x >> y, maxshifts);
}
另一种方法是继续尝试新的随机,直到反向移位为止。重用您当前的代码:
int x, y;
do
{
y = R.Next(1, 30); // random valid power
x = number << y;
} while (x >> y != number);
Console.WriteLine("{0} >> {1} = {2}", x, y, x >> y);