【发布时间】:2011-03-29 23:16:41
【问题描述】:
我在一段代码中遇到了这个语句:
Int32 medianIndex = colorList.Count >> 1;
colorList 是类System.Drawing.Color 的列表。
现在该语句应该检索列表的中位数索引 .. 就像它的半点一样 .. 但我无法理解 >> 符号是如何工作的,以及“1”应该如何给出中位数指数..我将不胜感激:S
【问题讨论】:
我在一段代码中遇到了这个语句:
Int32 medianIndex = colorList.Count >> 1;
colorList 是类System.Drawing.Color 的列表。
现在该语句应该检索列表的中位数索引 .. 就像它的半点一样 .. 但我无法理解 >> 符号是如何工作的,以及“1”应该如何给出中位数指数..我将不胜感激:S
【问题讨论】:
>> 运算符执行bit shift。
表达式>> 1 几乎* 与/ 2 相同,因此程序员正在计算索引colorList.Count / 2,即**median。要了解为什么会出现这种情况,您需要查看所涉及数字的二进制表示。例如,如果您的列表中有 25 个元素:
n : 0 0 0 1 1 0 0 1 = 25
\ \ \ \ \ \ \
n >> 1: 0 0 0 0 1 1 0 0 = 12
一般来说,当你真的想要执行除法时使用按位运算符是一种不好的做法。这可能是一个过早的优化,因为程序员认为执行按位运算而不是除法会更快。写一个除法会更清楚,如果两种方法的性能相当,我不会感到惊讶。
*表达式x >> 1 对所有正整数和所有负偶数给出与x / 2 相同的结果。但是,对于负奇数,它给出了不同的结果。例如-101 >> 1 == -51 而-101 / 2 == -50。
**实际上,只有当列表具有奇数个元素时,才以这种方式定义中位数。对于偶数个元素,这种方法严格来说不会给出中位数。
【讨论】:
x/2 转换为右移指令。
x >> 1 与x /= 2 进行比较有点令人困惑,我认为= 符号是一个错字。当然x >> 1 与x / 2 相当,x >>= 1 与x /= 2 相当。
这是一个按位运算符,我刚刚从http://en.wikibooks.org/wiki/C_Sharp_Programming/Operators 获取的定义:
二元运算符>>计算其操作数并返回结果第一个参数右移了第二个参数指定的位数。它丢弃超出其第一个参数大小的低位,并将新的高位设置为第一个参数的符号位,如果第一个参数是无符号的,则设置为零。
它基本上是除以 2...
【讨论】:
>> 是按位右移运算符,将colorList.Count 右移 1 或多或少等同于 colorList.Count / 2。
a >> b 的右移可以定义为a / 2 ^ b。
至于为什么要使用右移而不是除以 2,我不知道。
【讨论】:
C 程序员(我已经是其中一员 20 多年了)通常使用按位移位来乘以或除以 2 的幂。原因是在较旧的架构中(想想 2 MHz 处理器、32K 内存和没有磁盘)转移速度明显更快,并且通常编译为单个机器指令。尽管我现在主要编写 C#,但出于习惯,我仍然有时会使用这个技巧。大多数 C# 程序员从未见过的另一个常见 C 约定是在条件中嵌入赋值。例如:
if ( (a = getmeanumber()) == 0 )
/* do something */ ;
无论如何,至于最初的问题和使用它的原因,它们基本上不再存在,除非在嵌入式编程的有限领域中每个字节和时钟周期都可能很重要。
【讨论】:
这不是很可读的代码,基本上它只是将数字除以2。
>> 是右移运算符,将所有位右移一位。
0110 (6) 变为 0011 (3)
【讨论】: