社区,
假设我们有一个随机整数,它在Int32.MinValue - Int32.MaxValue范围内。 我想找到两个数字,这些数字在使用右移运算符一起计算时会得到这个整数。
一个例子:
如果输入值为123456
,则两个可能的输出值可能是2022703104
和14
,因为2022703104 >> 14 == 123456
这是我的尝试:
private static int[] DetermineShr(int input)
{
int[] arr = new int[2];
if (input == 0)
{
arr[0] = 0;
arr[1] = 0;
return arr;
}
int a = (int)Math.Log(int.MaxValue / Math.Abs(input), 2);
int b = (int)(input * Math.Pow(2, a));
arr[0] = a;
arr[1] = b;
return arr;
}
然而,对于某些否定值,它不起作用,输出不会导致正确的计算。
对于非常小的输入值,例如-2147483648
,它会抛出异常:
如何修改我的功能,以便为Int32.MinValue
和Int32.MaxValue
之间的所有输入值生成有效输出?
答案 0 :(得分:2)
好吧,让我们进行比较
123456 == 11110001001000000
2022703104 == 1111000100100000000000000000000
你能看到这种模式吗?如果您已获得shift
(在您的情况下为14
)答案是
(123456 << shift) + any number in [0..2 ** (shift-1)] range
但是,对于大值左移,可能会导致整数溢出;如果shift
很小(小于32
)我建议使用long
:
private static long Factor(int source, int shift) {
unchecked {
// (uint): we want bits, not two complement
long value = (uint) source;
return value << shift;
}
}
测试:
int a = -1;
long b = Factor(-1, 3);
Console.WriteLine(a);
Console.WriteLine(Convert.ToString(a, 2));
Console.WriteLine(b);
Console.WriteLine(Convert.ToString(b, 2))
将返回
-1
11111111111111111111111111111111
34359738360
11111111111111111111111111111111000
请注意,否定整数是两个补充
https://en.wikipedia.org/wiki/Two%27s_complement
事实上,在被视为 unsigned 整数
时非常大