C程序设计语言第二版习题2-9

简介: 在求反码时,表达式 x &= (x - 1) 用于把x最右边的值为1的位删除掉。请解释一下这样做的道理。用这一方法重写bitcount函数 ,使之执行得更快一点

问题描述

在求反码时,表达式 x &= (x - 1) 用于把x最右边的值为1的位删除掉。请解释一下这样做的道理。用这一方法重写bitcount函数 ,使之执行得更快一点

问题分解

  • 主函数main
  • 核心函数 bitcount(x)。我们先来看看书中例子 bitcount的算法实现:
int bitcount(unsigned x)
{
  int b;
  for(b = 0; x != 0; x >>= 1)
  {
    if(x & 1)
      b++;
  }
  return b;
}

从以上代码可知, bitcount 的实现逻辑是根据任何数与1进行位与计算可判断出次数的最右侧是否为1, 根据此原理不断将x右移,妹出现一次1记录一次。 根据题意,我们现在要改造bitcount的实现方式,借用 x &= (x - 1) 。如何理解呢? 我们知道二进制的特性, 不是0 就是1, 所以x & x - 1操作后的最右边值一定是互反的, 这样,x & (x - 1)的最右边的值一定为0,如此循环后x的最终值为0,循环次数即为x中值为1的个数。

代码实现


#include<stdio.h>
int bitcount(unsigned x);
​
int main()
{
  unsigned x;
  int r;
  x = 3;
  r = bitcount(x);
  printf("The result is: %u \n", r);
  return 0;
}
​
//使用求反码的方式 
int bitcount(unsigned x)
{
  int b;
  for(b = 0; x != 0; b++)
  {
    x &= (x - 1);
  }
  return b;
}

对比两个bitcount函数,我们发现第一个bitcount 中,for每执行一次,比第二个的bitcount 多执行了一次位与(&)操作,因此可以说第二个bitcount的执行速度是更快的。

目录
相关文章
|
存储 自然语言处理 程序员
【维生素C语言】第十八章 - C语言程序环境
程序环境是什么?我们都 "经历" 过,但不曾感知到 "他" 的存在。我们其实在不知不觉中早就已经接触到了程序环境…… 第一次创建了一个文件(test.c),敲下那句 "hello world" 随后保存后点击运行后编译出可执行文件(test.exe)时,其实就已经接触到了 "他" 了。
107 0
【维生素C语言】第十八章 - C语言程序环境
|
C语言
明解C语言第七章习题
明解C语言第七章习题
|
C语言
明解C语言第八章习题
明解C语言第八章习题
|
C语言
明解C语言第五章习题
明解C语言第五章习题
|
存储 C语言
明解C语言第六章习题
明解C语言第六章习题
|
C语言
明解C语言第四章习题
明解C语言第四章习题
|
数据安全/隐私保护 C语言
C语言第四章 分支结构程序设计习题2【修改版,看水印】
C语言第四章 分支结构程序设计习题2【修改版,看水印】
179 0
C语言第四章 分支结构程序设计习题2【修改版,看水印】
C程序设计语言第二版习题4-1
编写一个函数strrindex(s, t),用于返回字符串t在s中最右出现的位置,如果 s中不 包含t,那么返回-1。
3699 0
|
机器学习/深度学习 算法 JavaScript
C程序设计语言第二版习题3-5
编写函数itob(n, s, b) ,用于把整数n转换成以b为基数的字符串并存到字符串s中。例如, itob(n, s, 16) 表示将n转换成16进制数,并存入s中。
999 0
|
机器学习/深度学习 算法 JavaScript
C程序设计语言第二版习题3-6
修改itoa函数,使得该函数可以接收三个参数。其中,第三个参数为最小字段宽度。为了保证转换后所得的结果至少具有第三个参数指定的最小宽度,在必要时应在所得结果的左边填充一定的空格。
770 0