运算符“<<”在 C# 中是啥意思?

Posted

技术标签:

【中文标题】运算符“<<”在 C# 中是啥意思?【英文标题】:What does the operator "<<" mean in C#?运算符“<<”在 C# 中是什么意思? 【发布时间】:2011-01-01 17:26:30 【问题描述】:

我正在使用 NAudio 包在 C# 中进行一些基本的音频编程,我遇到了以下表达式,但我不知道它是什么意思,因为我以前从未见过

请快速解释一下这个表达式。

short sample = (short)((buffer[index + 1] << 8) | buffer[index + 0]);

【问题讨论】:

+1 撤消反对票。我认为这是一个很好的问题 我没有反对,但它让我觉得这是一个 RTFD 问题。 serhio:用谷歌搜索“ @Johannes:但是你可以直接在VS文档的索引中输入。 只要还没有在 SO 上被问到,最好放在这里 【参考方案1】:

定义

左移运算符 (<< Operator (MSDN C# Reference)

对于二进制数,它是一种移位操作数的所有位的按位运算;操作数中的每个位都简单地移动给定数量的位位置,然后填充空位。

用法

算术移位可用作执行有符号整数乘以或除以 2 的幂的有效方法。在有符号或无符号二进制数上左移 n 位具有将其乘以 2n 的效果。将二进制补码符号二进制数右移 n 位的效果是将其除以 2n,但它总是向下舍入(朝向负无穷大)。这不同于通常在有符号整数除法中进行舍入的方式(向 0 舍入)。这种差异导致多个编译器出现错误。

另一种用法是使用颜色位。 Charles Petzold Foundations article "Bitmaps And Pixel Bits" 展示了

ushort pixel = (ushort)(green << 5 | blue);

【讨论】:

我已经更新了这个答案,因为移位乘以/除以 2^n,而不是 2n 请注意,虽然只有一种类型的左移,但有两种类型的右移。 “算术移位”符号扩展,而“逻辑移位”零扩展。 C# 根据操作数的类型做正确的事。另一方面,C 对正数做了正确的事情,但将包含负数的有符号类型的处理保留为“实现定义”。【参考方案2】:

左移(和对应的右移)在给定方向移动位。

左移或多或少是 2 的倍数,但更快

右移或多或少除以 2,但更快

【讨论】:

您可以放心地忽略比较乘以或除以二。这让我们又多了一群程序员,他们认为他们可以通过编写x &lt;&lt; 1 而不是x * 2 来超越编译器。我没有-1,但很接近。 但这可能是他的音频代码中使用它的原因。所以 - 我的希望是帮助他不仅了解它的作用,而且了解可能的意图。 如果意图是算术,i。 e. × 2,那么我认为使用位移是一个非常糟糕的主意。如果意图是按位的,我。 e. “将这些位移动一点”,那当然是正确的成语。请记住,它必须对阅读代码的人有意义。编译器几乎总是更善于弄清楚如何正确编写它以尽可能快地执行。 (看到代码,很明显它是一个 bitwise 上下文,而不是算术上下文——它将两个字节组合成一个单词)。 @Benjamin:“但更快”的说法具有误导性。我很确定编译器和/或 JITter 可以识别整数 *2/2 计算并尽可能使用移位指令,因此在 C# 中没有性能优势。 +1 给卢克。在某些情况下,像x * 2 这样的东西甚至可能被重写为x + x :-)【参考方案3】:

这是一个左移操作,一个非常常见的编程习惯:http://en.wikipedia.org/wiki/Arithmetic_shift

【讨论】:

如果你在扮演一个有点蹩脚的角色 :) 很多做 C# 的人不是“水管工”,所以他们看不到所有的漂亮。 @Kragen,恕我直言,不仅在 C# 中而且在其他编程语言中并不常见。显然,如果您执行复杂的二进制或逻辑位操作,这对您来说很常见...... @serhio - 这是故意的双重否定吗?让你很难理解你的观点。你同意克拉根的观点吗?好像你是,但你最后一句话暗示你不是。 @runrunraygun:是的,我不仅同意 Kragen 的观点,而且还将他的肯定扩展到整个编程世界。过去,当更多地使用二进制数时,这应该是一个常见的(甚至可能是非常常见的)运算符。不是现在,在 OOP 时代......如果你明白了......【参考方案4】:

称为左移运算符。

关注this链接了解更多详细信息。

【讨论】:

【参考方案5】:

位运算符已经解释了好几次了。假设 buffer[0] 包含 1buffer[1] 包含 2 并且 index 为 0 并替换这些值:

short sample = (short)((buffer[1] << 8) | buffer[0]);
short sample = (short)((1 << 8) | 2);

现在,一个半图形表示。这是二进制表示中的数字 1:

0000 0001

向左移动八个位置会使这个数字从单个字节“溢出”。但是,编译器足够聪明,可以给我们更多空间。

0000 0001 0000 0000

现在,右边的部分:数字 2 在二进制中看起来像这样:

0000 0010

还有“|”运算符(按位或)只需将两个值放在一起并逐位比较。

  0000 0001 0000 0000
| 0000 0000 0000 0010
= 0000 0001 0000 0010

最终值存储在您的“样本”变量中(在本例中为 258。)反向操作类似:

buffer[0] = sample & 255;
buffer[1] = (sample & (255 << 8)) >> 8;

【讨论】:

【参考方案6】:

左移 这里有一些 msdn 可以帮助你:http://msdn.microsoft.com/en-us/library/ayt2kcfb(VS.80).aspx

【讨论】:

【参考方案7】:

“x y 将位模式 x y 位置向左移动。

例如,如果 x0001 0101 并且 y 是 1,那么结果将是 0010 1010 .就好像有人往左推一样。

【讨论】:

【参考方案8】:

正如一些人已经指出的那样,这是一个移位操作。

然而值得注意的是,根据操作数是有符号整数类型还是无符号整数类型,它将应用算术或逻辑移位。

查看本页底部on msdn.

【讨论】:

【参考方案9】:

正如其他人所说,

因此,在示例代码中,Buffer 包含在交替样本中使用左右编码的 sterio。作者通过将第一个左移 8 和第二个 oring 组合起来形成一个 16 位立体声样本,其中高 8 位是一个通道,低 8 位是另一个。

如果在您的示例中缓冲区包含:

1001 0100 (Right)
1001 0011 (Left)

你会在样本中得到的结果是:

(Left)    (Right)
1001 0011 1001 0100

【讨论】:

以上是关于运算符“<<”在 C# 中是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

<< 在 Ruby 中是啥意思?

<< 在 Java 中是啥意思?

语句“out |= (in & 0x7F) << (bytes++ * 7);”是啥意思?在java中是啥意思?

/=/ 在 Netezza 中是啥意思?

c#中 new 这个关键字是啥意思

:= 运算符在 mysql 中是啥意思?