【问题标题】:Can anyone explain why '>>2' shift means 'divided by 4' in C codes?谁能解释为什么'>>2'移位在C代码中意味着'除以4'?
【发布时间】:2012-11-14 15:46:35
【问题描述】:

我知道并理解结果。

例如:

<br>
 7 (decimal) = 00000111 (binary) <br>

and 7 >> 2 = 00000001 (binary) <br>
00000001 (binary) is same as 7 / 4 = 1 <br>
So 7 >> 2 = 7 / 4 <br>
<br>

但我想知道这个逻辑是如何创建的。
谁能详细说明这个逻辑?
(也许它只是突然出现在天才的脑海中?)

还有其他类似的逻辑吗?

【问题讨论】:

  • 除以 2,而不是 4
  • @RavindraBagale 右移一次将数字除以 2。右移两次将其除以 4

标签: c shift divide


【解决方案1】:

它并没有在天才的脑海中“弹出”。右移二进制数会将一个数除以 2,左移数会将其乘以 2。这是因为 10 在二进制中是 2。将一个数字乘以10(无论是二进制、十进制还是十六进制)都会在数字上附加一个0(实际上是左移)。类似地,除以10(或 2)会从数字中删除一个二进制数字(实际上是右移)。这才是真正的逻辑。

在计算机世界中有很多这样的bit-twiddlery(我在一分钟前发明的一个词)。

http://graphics.stanford.edu/~seander/bithacks.html 这是初学者。

这是我最喜欢的书:http://www.amazon.com/Hackers-Delight-Edition-Henry-Warren/dp/0321842685/ref=dp_ob_image_bk on bit-twiddlery。

【讨论】:

  • 良好的可视化效果。
【解决方案2】:

在 C 标准中实际上是这样定义的。

从第 6.5.7 节开始:

E1 >> E2 的结果是 E1 右移 E2 位位置。 [...] 结果的值是E1 / 2的商的整数部分E2

在大多数架构上,x &gt;&gt; 2 仅等于 x / 4 用于非负数。对于负数,它通常向相反的方向取整。

编译器始终能够将x / 4 优化为x &gt;&gt; 2。这种技术被称为“强度降低”,即使是最古老的编译器也可以做到这一点。所以把x / 4写成x &gt;&gt; 2没有任何好处。

【讨论】:

    【解决方案3】:

    详述Aniket Inge's 答案:

    数量:30710 = 1001100112

    乘以 10 在十进制系统中的工作原理

    10 * (30710)

    = 10 * (3*102 + 7*100)

    = 3*102+1 + 7*100+1

    = 3*103 + 7*101

    = 307010

    = 30710

    二进制乘以 2,

    2 * (1001100112)

    = 2 * (1*28 + 1*25 + 1*24 + 1*21 1*20)

    = 1*28+1 + 1*25+1 + 1*24+1 + 1*21+1 1*20+1

    = 1*29 + 1*26 + 1*25 + 1*22 + 1*21

    = 10011001102

    = 1001100112

    【讨论】:

      【解决方案4】:

      我想你对"2" in: 感到困惑:

      7 >> 2
      

      并且认为它应该除以 2。

      这里的"2" 表示将数字(在这种情况下为"7""2" 位位置向右移动。

      将一个数字"1"bit位置右移会产生除以2的效果:

      8 >> 1 = 4    // In binary: (00001000) >> 1 = (00000100)
      

      并将数字"2"bit 位置向右移动将产生除以4的效果:

      8 >> 2 = 2    // In binary: (00001000) >> 2 = (00000010)
      

      【讨论】:

        【解决方案5】:

        它固有在计算机中使用的二进制数系统中。

        类似的逻辑是---左移'n'次意味着乘以2^n。

        【讨论】:

          【解决方案6】:

          一个简单的方法来了解它为什么起作用,就是看一下熟悉的十进制数字系统,050 是 50,将它向右移动,它变成 005,5,相当于将它除以 10。同样左移的东西,050变成500,五百,相当于乘以10。

          所有其他数字系统的工作方式都相同。

          【讨论】:

            【解决方案7】:

            他们这样做是因为移位比实际除法更有效。您只是将所有数字向右或向左移动,逻辑上每班乘/除以 2

            如果您想知道为什么 7/4 = 1,那是因为结果的其余部分 (3/4) 被截断,因此它是一个整数。

            【讨论】:

              【解决方案8】:

              只是我的两分钱:我没有看到任何提及右移并不总是产生与除以 2 相同的结果这一事实。由于右移舍入负无穷大而整数除法舍入为零,因此某些值(如二进制补码中的-1)在除法时不会按预期工作。

              【讨论】:

                【解决方案9】:

                这是因为&gt;&gt;&lt;&lt; 运算符正在移动二进制数据。

                Binary value 1000 is the double  of binary value 0100
                Binary value 0010 is the quarter of binary value 1000
                

                【讨论】:

                  【解决方案10】:

                  您可以称其为天才头脑的想法,或者仅仅是对计算机语言的需求。

                  在我看来,作为设备的计算机永远不会对数字进行除法或乘法运算,而只是具有将位相加或简单地从这里移到那里的逻辑。您可以通过告诉您的计算机将它们相乘或相减来使算法起作用,但是当逻辑达到实际处理时,您的结果将是位移位或只是位相加的结果。

                  你可以简单地认为,为了得到一个数除以 4 的结果,计算机实际上将位右移两位,并给出结果:

                  7 in 8-bit binary = 00000111
                  Shift Right 2 places = 00000001 // (Which is for sure equal to Decimal 1)
                  
                  Further examples:
                  //-- We can divide 9 by four by Right Shifting 2 places
                  9 in 8-bit binary = 00001001
                  Shift right 2 places: 00000010 // (Which is equal to 9/4 or Decimal 2)
                  

                  对汇编语言编程有深入了解的人可以用更多的例子来解释它。如果你想知道这一切背后的实际意义,我想你需要学习计算机的位级算术和汇编语言。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2019-05-29
                    • 2021-11-04
                    • 2020-08-09
                    • 1970-01-01
                    • 1970-01-01
                    • 2018-11-30
                    • 1970-01-01
                    相关资源
                    最近更新 更多