两个左尖括号是什么意思<<&引用;用C#表示什么意思?

两个左尖括号是什么意思<<&引用;用C#表示什么意思?,c#,.net,operators,bitwise-operators,bit-shift,C#,.net,Operators,Bitwise Operators,Bit Shift,基本上是标题中的问题。我正在看MVC2源代码: [Flags] public enum HttpVerbs { Get = 1 << 0, Post = 1 << 1, Put = 1 << 2, Delete = 1 << 3, Head = 1 << 4 } [标志] 公共枚举HttpVerbs{ Get=1这是运算符。它将左操作数的位模式向左移位,移位量为右操作数中指定的二进制位数 Get

基本上是标题中的问题。我正在看MVC2源代码:

[Flags]
public enum HttpVerbs {
    Get = 1 << 0,
    Post = 1 << 1,
    Put = 1 << 2,
    Delete = 1 << 3,
    Head = 1 << 4
}
[标志]
公共枚举HttpVerbs{

Get=1这是运算符。它将左操作数的位模式向左移位,移位量为右操作数中指定的二进制位数

Get = 1 << 0, // 1
Post = 1 << 1, // 2
Put = 1 << 2,  // 4
Delete = 1 << 3, // 8
Head = 1 << 4  // 16
Get=1这将是运算符


对于每一次左移,值都有效地乘以2。因此,例如,写入
value,这就是位移动。基本上,它只是通过在右侧添加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
}
公共枚举HttpVerbs{
Get=1000000000001=1
Post=10000010=2
投入=10万100=4
删除=1 000011000=8
水头=1 00010000=16
}

更多信息请访问“左移位”。
1我知道这个答案已经基本解决了,但我认为可视化可能会对某些人有所帮助

[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
}
[Fact]公共无效位左移()
{

Assert.Equal(Convert.ToInt32(“0001”,2),1它被称为左移位运算符

左移位运算符使第一个操作数中的位模式向左移位第二个操作数指定的位数。移位操作腾空的位为零填充。这是逻辑移位,而不是移位和旋转操作

演示
左移
运算符的简单示例:

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
结果如下:

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
当你写作时

1 << n
所以


对于5个项目的列表,您的
将循环32次。

除了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++)
list.Count==0:for(int i=0;i<1;i++)
list.Count==1:for(inti=0;i<2;i++)
list.Count==2:for(inti=0;i<4;i++)
list.Count==3:for(inti=0;i<8;i++)
以此类推。

它的工作原理是用给定的(右手边)数字移动与数字等价的二进制数字

因此:

  • 000000000 1=1如果list.Count=0结果为000000000 1=1
  • 000000000 1=1如果list.Count=1结果为00000000 10=2
  • 000000000 1=1如果list.Count=2结果为00000000=4
  • 000000000 1=1如果list.Count=3结果为0000001000=8

以此类推。一般来说,它等于
2^list.Count
(2提升为list.Count的幂)

Its(循环的目的很可能是生成或操作列表中项目集的所有子集。循环体也很可能有一个好的位(har-har)关于按位操作,即另一个左移位和按位and。(因此,将其重写为使用Pow将是非常愚蠢的,我几乎不能相信有这么多人真的提出了这一点。)

表达式
(1前面的答案已经解释了它的作用,但似乎没有人猜测原因。在我看来,这段代码的原因很可能是循环正在迭代列表中每个可能的成员组合——这是我能理解为什么要迭代到2^{list.Count}因此,变量
i
的名称会很糟糕:它的位表示列表中项目的组合,而不是索引(我通常将“i”解释为含义),因此(例如)如果设置了
i
的位0(
(i&(1许多答案都暗示了这一点,但从未直接说明过

对于每一个将二进制数向左移位的位置,都会使该数字的原始值加倍

比如说,

小数点5左移1的二进制数为小数点10,或小数点5加倍


小数点5向左移位3的二进制数是小数点40,或小数点5加倍3次。

对于第一个示例,我认为您的意思是“零位”,但其余的都是正确的。@亚当,谢谢,你说得完全正确。我已经更新了帖子。+1,用于实际显示左移位在本例中的作用。或者更具体地说:0000100010001000,10000“按右操作数中指定的二进制位数”-事实上,这并不完全正确;例如,对于32位,它只考虑前5位,因此
@Robert Fricke:是的。位移位的基数限制为2(缺点),但比Math.Pow()快得多(优点)它更灵活,甚至可以有浮点基和指数。它变成了一个单一的机器代码指令。@IlyaIvanov哈哈,是的。还有你的老板怎么再也不能让你走了:你的代码快得惊人,其他开发人员都无法理解。我很难相信性能如此之高,以至于它不会一次找到循环计数,就不会对
Math.Pow
更有意义了。这样,你就不必担心让开发人员被胡说八道绊倒了。@Plutor不知道这是可以的(这就是语言规范的目的)。发现它“难以理解”、“难以阅读”、“其他开发人员无法理解”或者,这是一种不愿意学习+、-、*、/以外的任何东西的迹象。要么是这样,要么完全不熟悉整数是什么以及它们是如何表示的。解决方法
Math.pow(n,2)简直是怪诞的。例如,在java中,它会带来对DouLi的转换,而不是每个人都把它看作是一个优化。对我来说,这是一个表达两个力量的自然习语,我永远不会考虑用另一种方式来写。使用一个库函数来执行两个计算的幂使得它变得更难。ead(可怕的前缀表示法,而不是可读性更高的
value运算符value
)。说真的,你真的认为
1 << n
2^n
1 << 10
1024
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++)
temp = 14 << 2
i < (1 << list.Count)