简单代码实现:判断一个数x是不是2的n次方,是的话输出n

kkjiajieshi 2012-05-13 07:00:42
这是我的:
int main(){
int i=1,j=0,k=8;
while(!(k&i<<j++));
k==i<<--j?printf("yes,%d",j):printf("not\n");
return 0;
}
个人感觉效率还是很高的,有效率更高的请回帖。
...全文
853 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
liangbch 2012-05-22
  • 打赏
  • 举报
回复
楼主,该结贴了
cbzjzsb123 2012-05-14
  • 打赏
  • 举报
回复
不限定数最大多少吗?
liangbch 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 的回复:]
#include <stdio.h>
#include <stdlib.h>

typedef unsigned long DWORD;

int log2(DWORD n)
{
_asm { bsr eax,n }
}
int _log2(DWORD n){
_asm{bsf eax,n}
}
int main()
{
DWORD i=8;
log2(i……
[/Quote]


当然,也可以其他写法了
1.
if ( x>0 && 0 == (x & (x - 1)) )
{
int c=log2(x);
printf("yes, %d\n", n);
}
else
{
printf("no\n");
}


2.
if ( x>0 )
{
int c=log2(x);
if ( x== (1 << c))
printf("yes, %d\n", n);
else
printf("no\n");

}
else
{
printf("no\n");
}
youkuxiaobin 2012-05-14
  • 打赏
  • 举报
回复
还不错哦
赵4老师 2012-05-14
  • 打赏
  • 举报
回复
不限定数最大多少吗?
kkjiajieshi 2012-05-14
  • 打赏
  • 举报
回复
你得求出n的值啊
kkjiajieshi 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 的回复:]
判断u&(u-1)的结果是否为0就行了。因为2的n次方的值的最高位为1,其它都位为0.


C/C++ code
#include<iostream>
using namespace std;
int main()
{

unsigned int u;
for(;;) {
cin>>u;
if((u&(u-1)……
[/Quote]你得求出n的值啊
ljhhh0123 2012-05-14
  • 打赏
  • 举报
回复
判断u&(u-1)的结果是否为0就行了。因为2的n次方的值的最高位为1,其它都位为0.

#include<iostream>
using namespace std;
int main()
{

unsigned int u;
for(;;) {
cin>>u;
if((u&(u-1)) )
cout << u << " not!" <<endl;
else cout << u << " is!" <<endl;
}

return 0;
}
nice_cxf 2012-05-14
  • 打赏
  • 举报
回复
如果你只是想知道是不是的n次方(n<32),3楼正解,如果你想同时知道n是多少,查表最快
nice_cxf 2012-05-14
  • 打赏
  • 举报
回复
显然查表最快
unsinged int charbit[32] ={1,2,4,8,16,32..........}
for (int i =0;i< 32;i++)
{
if (x==charbit[i])
return true;
}
return false ;
kkjiajieshi 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 的回复:]
我已经在22#说过,“且返回log2(n)的整数部分”,
log2(9)=3.1699250014423123629074778878956,其整数部分是3,这个函数的返回值也是3,有什么不对吗?

任何定理或者解决方案都只在一定的条件下成立或者可行。就本楼这个问题而言,这个条件是“判断一个数x是不是2的n次方,是的话输出n”,只有是2的整数次方,才调用log2这个函数,有什么不对吗?我不确……
[/Quote]只是感觉有点局限而已,代码很漂亮,我只是改了一下,让不是2的整数次方的也能调用,别无他意
didijiji 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 的回复:]

我已经在22#说过,“且返回log2(n)的整数部分”,
log2(9)=3.1699250014423123629074778878956,其整数部分是3,这个函数的返回值也是3,有什么不对吗?

任何定理或者解决方案都只在一定的条件下成立或者可行。就本楼这个问题而言,这个条件是“判断一个数x是不是2的n次方,是的话输出n”,只有是2的整数次方,才调用log2这个函数,有什么不对吗?我不……
[/Quote]
不错了。
kkjiajieshi 2012-05-14
  • 打赏
  • 举报
回复
作为lz表示看清楚再回帖啊
liangbch 2012-05-14
  • 打赏
  • 举报
回复
我已经在22#说过,“且返回log2(n)的整数部分”,
log2(9)=3.1699250014423123629074778878956,其整数部分是3,这个函数的返回值也是3,有什么不对吗?

任何定理或者解决方案都只在一定的条件下成立或者可行。就本楼这个问题而言,这个条件是“判断一个数x是不是2的n次方,是的话输出n”,只有是2的整数次方,才调用log2这个函数,有什么不对吗?我不确信楼上的各位到底有没有在本题目这个上下文环境下思考我的结论,有没有去运行我的代码。


说的题外话。
任意定理只在一定的条件下才能成立。
如a和b都属于数域D, b!=0, 那么a/b仍然属于数域D,在有理数域成立,在整数域就不成立了。7/3的结果不是整数。
负数不能开方,在实数域成立,在复数域就不成立了。
牛顿的经典力学在研究常规物体的运动时,是正确的,在高能物理领域就不正确了。

kkjiajieshi 2012-05-14
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>

typedef unsigned long DWORD;

int log2(DWORD n)
{
_asm { bsr eax,n }
}
int _log2(DWORD n){
_asm{bsf eax,n}
}
int main()
{
DWORD i=8;
log2(i)==_log2(i)?printf("%d\n",log2(i)):printf("not\n");
return 0;
}

感谢17楼,lz根据你的思路改编而来,这个比你的更合理一点吧,觉得这个算法比以前那个更快。
请大家谈谈看法
kkjiajieshi 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 的回复:]
判断x是不是2的n次方,3楼正解。若需要求出n。在x86CPU,这些方法都不是最快的。intel从386开始,增加指令bsr,AMD同期稍后的CPU同样支持这条指令,在最新的45ns的CPU,这条指令的延迟只有2个周期。下面给出在VC++(VC6,VC2008,VC2010)中测试代码。


C/C++ code

#include <stdio.h>
#include <stdlib……
[/Quote]百度百科:bsr是从源操作数的的最高位向低位搜索,将遇到的第一个“1”所在的位序号存入目标寄存器中, 这样log2(9) 也会返回3的,所以是有问题的。
不过c语言嵌入汇编给人另一种思路啊
ychaeong 2012-05-14
  • 打赏
  • 举报
回复
显然查表LUT最快。
liangbch 2012-05-14
  • 打赏
  • 举报
回复
这个函数仅对这到题目成立,
具体约束条件是,n必须是大于0的无符号整数,且返回log2(n)的整数部分

如有疑问,请指出错误,不要仅仅说“这个log2肯定是错的”
stjay 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 的回复:]

判断x是不是2的n次方,3楼正解。若需要求出n。在x86CPU,这些方法都不是最快的。intel从386开始,增加指令bsr,AMD同期稍后的CPU同样支持这条指令,在最新的45ns的CPU,这条指令的延迟只有2个周期。下面给出在VC++(VC6,VC2008,VC2010)中测试代码。

C/C++ code

#include <stdio.h>
#include <stdlib.h>……
[/Quote]

虽然不懂汇编,但这个log2肯定是错的
int log2(DWORD n)
{
_asm { bsr eax,n }
}
liangbch 2012-05-14
  • 打赏
  • 举报
回复
给出参考资料:
关于bsr指令的用法,请参考一下文档。

1.Intel的官方文档。 《Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 2A: Instruction Set Reference, A-M》

2.Agner Fog 给出的指令表,文档名称《instruction_tables.pdf》,摘要见下。链接:http://www.agner.org/optimize/instruction_tables.pdf

Lists of instruction latencies, throughputs and micro-operation breakdowns for Intel, AMD and VIA CPUs
By Agner Fog. Copenhagen University College of Engineering.
Copyright © 1996 - 2012. Last updated 2012-02-29.
加载更多回复(13)

70,037

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧