【问题标题】:What does the ">>" operator in C# do?C# 中的“>>”运算符有什么作用?
【发布时间】:2011-03-29 23:16:41
【问题描述】:

我在一段代码中遇到了这个语句:

Int32 medianIndex = colorList.Count >> 1;

colorList 是类System.Drawing.Color 的列表。

现在该语句应该检索列表的中位数索引 .. 就像它的半点一样 .. 但我无法理解 >> 符号是如何工作的,以及“1”应该如何给出中位数指数..我将不胜感激:S

【问题讨论】:

    标签: c# .net syntax operators


    【解决方案1】:

    >> 运算符执行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

    **实际上,只有当列表具有奇数个元素时,才以这种方式定义中位数。对于偶数个元素,这种方法严格来说不会给出中位数。

    【讨论】:

    • 非常感谢您的解释..我熟悉移位方法及其含义,但我不明白这是这里使用的方式..我还有另一个问题..这是对 2 进行除法的时间复杂度低于普通的“/”除法?
    • @Majd:这取决于您运行代码的平台。请记住,C# 被编译为 CIL,而 CIL 又被翻译(“jitted”)为不同平台的本地机器代码。有些抖动很可能会自动将x/2 转换为右移指令。
    • 在第一个脚注中,将x >> 1x /= 2 进行比较有点令人困惑,我认为= 符号是一个错字。当然x >> 1x / 2 相当,x >>= 1x /= 2 相当。
    【解决方案2】:

    这是一个按位运算符,我刚刚从http://en.wikibooks.org/wiki/C_Sharp_Programming/Operators 获取的定义:

    二元运算符>>计算其操作数并返回结果第一个参数右移了第二个参数指定的位数。它丢弃超出其第一个参数大小的低位,并将新的高位设置为第一个参数的符号位,如果第一个参数是无符号的,则设置为零。

    它基本上是除以 2...

    【讨论】:

    • +1 用于链接到文档。我发现如果有趣的话,OP 甚至会费心在这里发帖,而不是仅仅前往语言定义。问这样的问题会让我和我的员工谈论他们的态度(不是:我不明白什么是 bigshift”,而是“嘿,我懒得查找我审查的代码的语言规范”)。
    【解决方案3】:

    >> 是按位右移运算符,将colorList.Count 右移 1 或多或少等同于 colorList.Count / 2

    a >> b 的右移可以定义为a / 2 ^ b

    至于为什么要使用右移而不是除以 2,我不知道。

    【讨论】:

    • 不要使用它而不是除以 2。JIT 优化了这种东西。
    【解决方案4】:

    C 程序员(我已经是其中一员 20 多年了)通常使用按位移位来乘以或除以 2 的幂。原因是在较旧的架构中(想想 2 MHz 处理器、32K 内存和没有磁盘)转移速度明显更快,并且通常编译为单个机器指令。尽管我现在主要编写 C#,但出于习惯,我仍然有时会使用这个技巧。大多数 C# 程序员从未见过的另一个常见 C 约定是在条件中嵌入赋值。例如:

    if ( (a = getmeanumber()) == 0 )
       /* do something */ ;
    

    无论如何,至于最初的问题和使用它的原因,它们基本上不再存在,除非在嵌入式编程的有限领域中每个字节和时钟周期都可能很重要。

    【讨论】:

      【解决方案5】:

      这不是很可读的代码,基本上它只是将数字除以2。

      >> 是右移运算符,将所有位右移一位。

      0110 (6) 变为 0011 (3)

      【讨论】:

        猜你喜欢
        • 2010-11-21
        • 1970-01-01
        • 2015-10-15
        • 1970-01-01
        • 2022-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多