【问题标题】:linux kernel code ">>" operatorlinux内核代码“>>”运算符
【发布时间】:2012-11-12 18:03:36
【问题描述】:

我们被分配了对 Linux 内核代码进行一些修改并重新编译的任务。我很难弄清楚这段代码行是做什么的:

p->time_slice = (current->time_slice + 1) >> 1;

更准确的说,为什么末尾有“>> 1”?

【问题讨论】:

  • 因为此代码实现的算法指定该值应向右移动一位。
  • 为什么人们不赞成这个问题? bks正在努力学习;这是课堂作业,他可能还在学习 C。提问是一个很好的方法。告诉他不要破解 Linux 内核并否决这个问题对任何人都没有帮助。
  • @BrianCampbell 不要误会我的意思,但是>> 运算符不是在任何像样的 C 教程中解释的吗?
  • @H2CO3 也许;虽然如果你不做一些玩弄有点模糊,所以我可以想象有些人可能会掩盖它,或者如果他们没有上下文来理解为什么他们第一次过去时它很重要,那么有人学习不记得它它。无论如何,这个问题并不清楚,这是很难搜索的,因为大多数搜索引擎不能很好地处理特殊字符。对问题投反对票并侮辱提出问题的人是卑鄙的,没有帮助。
  • 好的,我真的不明白关闭这个问题的人。如果这个问题太本地化了,那么这个网站上的几乎每个问题都太本地化了。问“这里有一些我不明白的语法,这是什么意思?”不是一个特别本地化的问题;答案中的语法和解释适用于任何 C 代码。他碰巧在 Linux 内核的上下文中提出这个问题的事实是无关紧要的。为什么人们觉得有必要否决初学者提出的完美问题?我们是来提供帮助的,而不是为了羞辱人们到别处寻求帮助。

标签: c linux linux-kernel operating-system


【解决方案1】:

">>" 表示将值按位向右移动。 "x >> y" 与除以 2^y 并截断结果相同。截断结果意味着在几乎所有情况下四舍五入,但是对于负数,可能存在替代实现。如果您认为这发生在您身上,请查看 cmets。

【讨论】:

  • *除以二并截断结果。
  • 哦,向零舍入。如果是负整数,则截断舍入 向上
  • @H2CO3:它与截断相同;它相当于正值的截断和负值的实现定义(大多数常见的实现会将负值向下舍入)。
  • @StephenCanon 对。我想我们会在不久的将来吓坏可怜的 dbeer。 :P
  • @H2CO3, @ Stephen Caron -- 澄清一下:在负数的情况下,您有两种可能的结果 /实现: (1) shift with sign extension,将 DOWN 截断(向负无穷大,而不是零),或 (2) shift WITHOUT sign extension,这完全改变了数字(-1 >> 1 变成一个非常非常大的正数。)
【解决方案2】:

这是一个按位移位运算符。将值视为位数组,它将所有内容向右移动一位(向最低有效位)。对于正数,这相当于除以 2,向下取整。移位用作除以 2 的幂的快速方法;如果移动 1 (>> 1),则除以 2,如果移动 2 (>> 2),则除以 4,依此类推。

例如,如果您使用 4 位整数,这里有几个例子说明了它是如何工作的:

6 >> 1
  0110  ->  0011 
               3

7 >> 1
  0111  ->  0011
               3

6 >> 2
  0110  ->  0001
               1

对于负数,它有点复杂。 C 标准没有指定负数的格式。在大多数现代机器上,它们存储在two's complement;也就是说,要表示一个负数,你取正表示,反转每一位,然后加 1。然后取最高有效位来表示符号位。如果你右移一个负数,有两种可能的解释;一种总是将 0 移入最高有效位,一种将匹配值移入已经存在的值,称为“符号扩展”。

-2 >> 1
   1110  ->  0111
                7
   1110  ->  1111
               -1

C 标准没有指定实现必须使用这些解释中的哪一种。 GCC 做了一个更令人期待的符号扩展,它相当于除以二并向下舍入,就像正例一样。请注意,向下舍入意味着“向负无穷大”,而不是您可能假设的“向零”。

-3 >> 1
   1101  ->  1110
               -2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-22
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多