【问题标题】:What is the logic behind this C Program?这个 C 程序背后的逻辑是什么?
【发布时间】:2013-11-06 05:09:15
【问题描述】:

这是一个小程序(14 行程序),它计算一个数字中设置的位数

输入-输出--> 0-->0(0000000), 5-->2(0000101), 7-->3(0000111)

int CountBits (unsigned int x)
{
  static unsigned int mask[] = { 0x55555555,
      0x33333333,
      0x0F0F0F0F,
      0x00FF00FF,
      0x0000FFFF
      } ;

      int i ;
      int shift ; /* Number of positions to shift to right*/
      for (i =0, shift =1; i < 5; i ++, shift *= 2)
              x = (x & mask[i ])+ ( ( x >> shift) & mask[i]);
      return x;
}

有人可以解释这里使用的算法/为什么会这样吗?

【问题讨论】:

  • 你有什么不明白的?
  • 程序的完整逻辑对我来说似乎很陌生。实际上,我是一名初学者 C 程序员,这就是为什么我很难理解这一点。拜托,你能告诉我程序的整个工作过程吗?谢谢。
  • 如果您是初学者,请暂时忽略这一点。在你努力理解一些巧妙的小把戏之前,先专注于学习基础知识——这只会让你对重要的事情感到困惑和分心。
  • 它看起来很像 FFT 变换的 DC 分量。
  • @SeanMcSomething - 我相信你的评论是善意的,但它并不是很有帮助。我们所有人都必须从某个地方开始。我们中的一些人选择从比其他人更困难的问题开始。 Bit twiddling 是 C 语言的强项之一,根据未来的兴趣,它可能是一个重要的学习领域。可以说,理解位旋转是 C 语言最基本的组成部分之一,因为它提供了对语言提供的原语的深入理解。

标签: algorithm c logic


【解决方案1】:

This post,作者 Ian Ashdown,更详细地解释了它:

Freed 的数字是序列的成员,其中第 N 个数字 序列本身是一个从右到左的无限序列,由 2*N 个 1 组成 接着是 2*N 个 0,然后是 2**N 个 1,依此类推。最初的 数字是:

...0101010101010101
...0011001100110011
...0000111100001111
...0000000011111111
...

对于 16 位的字长,我们有四个“B 常数”:

B[1] = 0101010101010101
B[2] = 0011001100110011
B[3] = 0000111100001111
B[4] = 0000000011111111

这就是mask[] 中的那些数字,例如。 0x55555555 是位模式1010101010101010101010101010101hexadecimal 表示。

算法本身就是这样做的:

  1. 将相邻位解释为数字(0 或 1)并将它们相加。结果是可以用两位表示的数字(即 0 到 3)。
  2. 将相邻的位解释为数字(0到3)并将它们相加。结果可以用四位表示(即 0 到 15)。
  3. 将相邻的 groups-of-4 位解释为数字(0 到 15)并将它们相加。结果可以用 8 位表示(即 0 到 255)。

...以此类推,直到你得到一个与你需要的位数一样宽的结果。

我建议您使用上面的二进制掩码在纸上手动尝试一些数字。然后您可能会对该代码所表达的算法有所了解。

【讨论】:

  • 非常感谢您的回答。它帮助很大。
猜你喜欢
  • 2020-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-18
  • 2017-10-17
  • 1970-01-01
相关资源
最近更新 更多