lan*_*der 43 .net c# operators bit-shift bitwise-operators
基本上是标题中的问题.我正在看MVC 2源代码:
[Flags]
public enum HttpVerbs {
Get = 1 << 0,
Post = 1 << 1,
Put = 1 << 2,
Delete = 1 << 3,
Head = 1 << 4
}
Run Code Online (Sandbox Code Playgroud)
而我只是好奇双左眼角饼干的<<作用.
pid*_*pid 131
当你写作
1 << n
Run Code Online (Sandbox Code Playgroud)
你却将位组合000000001的n离开,因此把时间n成2的指数:
2^n
Run Code Online (Sandbox Code Playgroud)
所以
1 << 10
Run Code Online (Sandbox Code Playgroud)
真的是
1024
Run Code Online (Sandbox Code Playgroud)
对于5个项目的列表,您for将循环32次.
Sel*_*enç 82
它被称为left-shift运营商.看一下文档
左移运算符使第一个操作数中的位模式向左移动第二个操作数指定的位数.通过换档操作腾出的位是零填充的.这是逻辑移位而不是移位和旋转操作.
演示left-shift运算符的简单示例:
for (int i = 0; i < 10; i++)
{
var shiftedValue = 1 << i;
Console.WriteLine(" 1 << {0} = {1} \t Binary: {2}",i,shiftedValue,Convert.ToString(shiftedValue,2).PadLeft(10,'0'));
}
//Output:
// 1 << 0 = 1 Binary: 0000000001
// 1 << 1 = 2 Binary: 0000000010
// 1 << 2 = 4 Binary: 0000000100
// 1 << 3 = 8 Binary: 0000001000
// 1 << 4 = 16 Binary: 0000010000
// 1 << 5 = 32 Binary: 0000100000
// 1 << 6 = 64 Binary: 0001000000
// 1 << 7 = 128 Binary: 0010000000
// 1 << 8 = 256 Binary: 0100000000
// 1 << 9 = 512 Binary: 1000000000
Run Code Online (Sandbox Code Playgroud)
向左移动一位是两个等于多个.事实上,移动位比标准乘法更快.让我们看一个证明这个事实的例子:
假设我们有两种方法:
static void ShiftBits(long number,int count)
{
long value = number;
for (int i = 0; i < count; i+=128)
{
for (int j = 1; j < 65; j++)
{
value = value << j;
}
for (int j = 1; j < 65; j++)
{
value = value >> j;
}
}
}
static void MultipleAndDivide(long number, int count)
{
long value = number;
for (int i = 0; i < count; i += 128)
{
for (int j = 1; j < 65; j++)
{
value = value * (2 * j);
}
for (int j = 1; j < 65; j++)
{
value = value / (2 * j);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我们想要像这样测试它们:
ShiftBits(1, 10000000);
ShiftBits(1, 100000000);
ShiftBits(1, 1000000000);
...
MultipleAndDivide(1, 10000000);
MultipleAndDivide(1, 100000000);
MultipleAndDivide(1, 1000000000);
...
Run Code Online (Sandbox Code Playgroud)
结果如下:
Bit manipulation 10.000.000 times: 58 milliseconds
Bit manipulation 100.000.000 times: 375 milliseconds
Bit manipulation 1.000.000.000 times: 4073 milliseconds
Multiplication and Division 10.000.000 times: 81 milliseconds
Multiplication and Division 100.000.000 times: 824 milliseconds
Multiplication and Division 1.000.000.000 times: 8224 milliseconds
Run Code Online (Sandbox Code Playgroud)
Zah*_*med 57
它是按位左移它通过给定(右手侧)数字移动数字的二进制等价数字来工作.
所以:
temp = 14 << 2
Run Code Online (Sandbox Code Playgroud)
二进制当量为14 00001110将它移动2次意味着从右手侧推零并将每个数字移到左侧使其00111000等于56.
在你的例子中:
i < (1 << list.Count)
Run Code Online (Sandbox Code Playgroud)
等等.一般来说它是相等的2 ^ list.Count(2提升到list.Count的力量)
Ada*_*son 36
那是左移位操作符.它将左操作数的位模式向左移动右操作数中指定的二进制数字的数量.
Get = 1 << 0, // 1
Post = 1 << 1, // 2
Put = 1 << 2, // 4
Delete = 1 << 3, // 8
Head = 1 << 4 // 16
Run Code Online (Sandbox Code Playgroud)
这在语义上等同于 lOperand * Math.Pow(2, rOperand)
use*_*227 23
循环的目的很可能是生成或操作列表中项集的所有子集.并且循环体很可能也具有按位运算的良好位(har har),即另一个左移位和按位运算.(所以重写它以使用Pow将是非常愚蠢的,我几乎不相信有那么多人实际建议.)
Fab*_*ian 15
多数民众赞成位移.它基本上只是通过向右侧添加0来向左移动位.
public enum HttpVerbs {
Get = 1 << 0, // 00000001 -> 00000001 = 1
Post = 1 << 1, // 00000001 -> 00000010 = 2
Put = 1 << 2, // 00000001 -> 00000100 = 4
Delete = 1 << 3, // 00000001 -> 00001000 = 8
Head = 1 << 4 // 00000001 -> 00010000 = 16
}
Run Code Online (Sandbox Code Playgroud)
更多信息请访问http://www.blackwasp.co.uk/CSharpShiftOperators.aspx
Tho*_*mar 12
除了Selman22的答案之外,还有一些例子:
我将列出一些值list.Count以及循环的内容:
list.Count == 0: for (int i = 0; i < 1; i++)
list.Count == 1: for (int i = 0; i < 2; i++)
list.Count == 2: for (int i = 0; i < 4; i++)
list.Count == 3: for (int i = 0; i < 8; i++)
Run Code Online (Sandbox Code Playgroud)
等等.
"比特左移." 1 << 0表示"取整数值1并将其位向左移位".即,00000001保持不变. 1 << 1表示"取整数值1并将其位移到一处." 00000001成为00000010.
小智 8
它(<<)是一个按位左移位运算符,它移动二进制对象的位值.左操作数指定要移位的值,右操作数指定值移位的位数.
在你的情况下,如果list.count的值是4,那么循环将运行直到i <(1 << 4)为16(00010000)
00000001 << 4 = 00010000(16)
它隐含在许多答案中,但从未直接说明......
对于您移动二进制数的每个位置,您将该数字的原始值加倍.
例如,
左移1的十进制5二进制是十进制10,或十进制5加倍.
向左移动3的十进制5二进制是十进制40,或十进制5加倍3倍.
以前的答案已经解释了它的作用,但似乎没有人猜测为什么.我觉得这个代码的原因很可能就是循环遍历列表成员的每个可能组合 - 这是我可以看到为什么你想要迭代到2 ^ {list的唯一原因.计数}.i因此,变量将被严格命名:而不是索引(这是我通常将'i'解释为含义),其位代表列表中项目的组合,因此(例如)如果位可以选择第一项零i是set((i & (1 << 0)) != 0),第二项是第一项是否设置((i & (1 << 1)) != 0)等等.1 << list.Count因此,第一个整数与列表中的项的有效组合不对应,因为它表示选择不存在的项list[list.Count].
我知道这个答案已经解决了,但我认为可视化可能对某人有所帮助.
[Fact] public void Bit_shift_left()
{
Assert.Equal(Convert.ToInt32("0001", 2), 1 << 0); // 1
Assert.Equal(Convert.ToInt32("0010", 2), 1 << 1); // 2
Assert.Equal(Convert.ToInt32("0100", 2), 1 << 2); // 4
Assert.Equal(Convert.ToInt32("1000", 2), 1 << 3); // 8
}
Run Code Online (Sandbox Code Playgroud)