找到随机BitshiftRight组合

时间:2015-01-04 17:51:48

标签: c# reverse bit-shift

我有问题。 我试图找到右移操作的组合。 一个例子。 我有一个输入:

让我们说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)而不循环遍历所有?

2 个答案:

答案 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);