• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > C语言判断一个数是否是2的幂次方或4的幂次方

C语言判断一个数是否是2的幂次方或4的幂次方

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c语言幂次方,c语言中幂次方,c语言幂次方怎么表示,c语言自幂数,c语言幂函数等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

快速判断一个数是否是2的幂次方,若是,并判断出来是多少次方!
将2的幂次方写成二进制形式后,很容易就会发现有一个特点:二进制中只有一个1,并且1后面跟了n个0; 因此问题可以转化为判断1后面是否跟了n个0就可以了。

如果将这个数减去1后会发现,仅有的那个1会变为0,而原来的那n个0会变为1;因此将原来的数与去减去1后的数字进行与运算后会发现为零。

最快速的方法:

   (number & number - 1) == 0

</div>

原因:因为2的N次方换算是二进制为10……0这样的形式(0除外)。与上自己-1的位数,这们得到结果为0。例如。8的二进制为1000;8-1=7,7的二进制为111。两者相与的结果为0。计算如下:

     1000
   & 0111
    -------
    0000
</div>

使用递归来实现的代码如下:

#include "stdio.h" 
#include "stdlib.h" 
 
int log2(int value)  //递归判断一个数是2的多少次方 
{ 
  if (value == 1) 
    return 0; 
  else 
    return 1+log2(value>>1); 
} 
 
int main(void) 
{ 
  int num; 
  printf("请输入一个整数:"); 
  scanf("%d",&num); 
  if(num&(num-1)) //使用与运算判断一个数是否是2的幂次方 
    printf("%d不是2的幂次方!\n",num); 
  else 
    printf("%d是2的%d次方!\n",num,log2(num)); 
  system("pause"); 
  return 0; 
} 
</div>

使用非递归来实现的代码如下:

#include "stdio.h" 
#include "stdlib.h" 
 
int log2(int value)  //非递归判断一个数是2的多少次方 
{ 
  int x=0; 
  while(value>1) 
  { 
    value>>=1; 
    x++; 
  } 
  return x; 
} 
 
int main(void) 
{ 
  int num; 
  printf("请输入一个整数:"); 
  scanf("%d",&num); 
  if(num&(num-1))   //使用与运算判断一个数是否是2的幂次方 
    printf("%d不是2的幂次方!\n",num); 
  else 
    printf("%d是2的%d次方!\n",num,log2(num)); 
  system("pause"); 
  return 0; 
} 
</div>

扩展:求一个数n的二进制中1的个数。
非常巧妙地利用了一个性质,n=n&(n-1) 能移除掉n的二进制中最右边的1的性质,循环移除,直到将1全部移除,这种方法将问题的复杂度降低到只和1的个数有关系。代码如下:

int Func3(int data) 
{  //利用了data&(data-1)每次都能移除最右边的1,移除了多少个1,就是包含了几个1 
  int count = 0; 
  while (data) 
  { 
    data = data & (data-1); 
    count++; 
  } 
  return count; 
} 
</div>

扩展问题二:

A和B的二进制中有多少位不相同。这个问题可以分为两步,(1)将A和B异或得到C,即C=A^B,(2)计算C的二进制中有多少个1。


快速判断一个数是否是4的幂次方,若是,并判断出来是多少次方!
将4的幂次方写成二进制形式后,很容易就会发现有一个特点:二进制中只有一个1(1在奇数位置),并且1后面跟了偶数个0; 因此问题可以转化为判断1后面是否跟了偶数个0就可以了。

4的整数次幂的二进制数都为 (4)100、(16)10000、(64)1000000......

另外,4的幂次方4^n也可以写为2^(2*n),即也可以写为2的幂次方,当然就满足2的幂次方的条件了,即num & num-1==0。

思路:首先用条件num & num-1==0来判断是否为2的幂次方,若不满足,则不是。若满足,在用条件num & 0x55555555来判断,若为真,则这个整数是4的幂次方,否则不是。

使用递归来实现的代码如下:

#include "stdio.h" 
#include "stdlib.h" 
 
bool fn(unsigned int x)   //判断x是否是4的幂次方 
{ 
 if ( x & (x - 1) )     //判断x是否为2的幂次方 
   return false; 
 return x & 0x55555555;   //判断1是否在奇数位置上 
} 
 
int log4(int value)   //递归判断一个数是4的多少次方 
{ 
  if (value == 1) 
    return 0; 
  else 
  { 
    value>>=1;    //往右移位 
    return 1+log4(value>>1);    //往右移位 
  } 
} 
 
int main(void) 
{ 
  int num; 
  printf("请输入一个整数:"); 
  scanf("%d",&num); 
  if(fn(num))   //使用与运算判断一个数是否是2的幂次方 
    printf("%d是4的%d次方!\n",num,log4(num)); 
  else 
    printf("%d不是4的幂次方!\n",num); 
  system("pause"); 
  return 0; 
} 

</div>

使用非递归来实现的代码如下:

#include "stdio.h" 
#include "stdlib.h" 
 
bool fn(unsigned int x)   //判断x是否是4的幂次方 
{ 
 if ( x & (x - 1) )     //判断x是否为2的幂次方 
   return false; 
 return x & 0x55555555;   //判断1是否在奇数位置上 
} 
 
int log4(int value)  //非递归判断一个数是4的多少次方   
{ 
  int x=0; 
  while(value>1) 
  { 
    value>>=1;   //往右移位 
    value>>=1; 
    x++; 
  } 
  return x; 
}  
 
int main(void) 
{ 
  int num; 
  printf("请输入一个整数:"); 
  scanf("%d",&num); 
  if(fn(num))   //使用与运算判断一个数是否是2的幂次方 
    printf("%d是4的%d次方!\n",num,log4(num)); 
  else 
    printf("%d不是4的幂次方!\n",num); 
  system("pause"); 
  return 0; 
} 

</div>

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C语言判断一个数是否是2的幂次方或4的幂次方
  • C语言求幂计算的高效解法
  • C语言快速幂取模算法小结

相关文章

  • 2017-05-28深入理解C语言内存对齐
  • 2017-05-28C++实现DES加密算法实例解析
  • 2017-05-28linux c 查找使用库的cflags与libs的方法详解
  • 2017-05-28C++实现图形界面时钟表盘代码
  • 2017-05-28C语言 条件判断详细介绍
  • 2017-05-28C++中关键字Struct和Class的区别
  • 2017-05-28数据结构 数组顺序存储详细介绍
  • 2017-05-28探讨:用两个栈实现一个队列(我作为面试官的小结)
  • 2017-05-28C语言中逻辑运算符与条件运算符的学习教程
  • 2017-05-28C语言中十六进制转十进制两种实现方法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 解析C++函数的默认参数和占位参数及较之C语言的拓展
    • 基于Protobuf C++ serialize到char*的实现方法分析
    • C语言中的strdup()函数和其与strcpy()函数的区别
    • 完全掌握C++编程中构造函数使用的超级学习教程
    • C语言获得电脑的IP地址的小例子
    • C++中的while循环和for循环语句学习教程
    • 常用的C语言排序算法(两种)
    • 基于C/C++时间函数的使用详解
    • 关于C语言除0引发的思考
    • C++中replace()函数使用方法汇总

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有