求一个二进制数最高位1的索引位置——探讨最高效的算法

ly8008csko 2010-02-06 11:11:29
求一个二进制数最高位1的索引位置。

我想到的方法是:

int c = -1;
while(n)
{
n >>= 1;
c++;
}

看看大家有没有更高效的算法
...全文
3733 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
BEN36 2011-10-28
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 ben36 的回复:]

引用 3 楼 mstlq 的回复:

32bit版本,思路是二分法
C/C++ code
int f1(unsigned x)
{
int n=1;
if(x==0) return -1;
if ((x>>16) == 0) {n = n+16; x = x<<16;}
if ((x>>24) == 0) {n = n+8; x = x<<8;}
if ((x>>28) ==……
[/Quote]

纠正一下,n = n-(x>>31); 是二分的最后一步用来判断最高位1是在高1位还是低1位。所以不能简单的用if(x>>31) return 31;来代替。
BEN36 2011-10-25
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 mstlq 的回复:]

32bit版本,思路是二分法
C/C++ code
int f1(unsigned x)
{
int n=1;
if(x==0) return -1;
if ((x>>16) == 0) {n = n+16; x = x<<16;}
if ((x>>24) == 0) {n = n+8; x = x<<8;}
if ((x>>28) == 0) {n ……
[/Quote]

看了好一会才看明白,容我做个注解给后来人。。。如有不对还请大大们纠正
if ((x>>16) == 0) {n = n+16; x = x<<16;} cout<<n<<", "; printf("%x\n", x);
if ((x>>24) == 0) {n = n+8; x = x<<8;} cout<<n<<", "; printf("%x\n", x);
if ((x>>28) == 0) {n = n+4; x = x<<4;} cout<<n<<", "; printf("%x\n", x);
if ((x>>30) == 0) {n = n+2; x = x<<2;} cout<<n<<", "; printf("%x\n", x);
这几行是二分,依次判断最高位是在高16位还是低16位,是在16位中的高8位还是低8位...
n = n-(x>>31);
这行是针对当x高位为31时的情况,此时n原本应该是0, 这样最后31-n=31,但如果n赋初值0,位移就没法做了,所以此处做一判断修正n的值。如果写的更直白一点可以直接在一开始就判断:
if(x>>31) return 31;
yzx714 2010-02-06
  • 打赏
  • 举报
回复
只返回一分啊……
mstlq 2010-02-06
  • 打赏
  • 举报
回复
下载后评论+评星级……
分数就回来了……
yzx714 2010-02-06
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 mstlq 的回复:]
引用 6 楼 xylicon 的回复:
引用 3 楼 mstlq 的回复:
32bit版本,思路是二分法
C/C++ codeint f1(unsigned x)
{int n=1;if(x==0)return-1;if ((x>>16)==0) {n= n+16; x= x < <16;}if ((x>>24)==0) {n= n+8; x= x < <8;}if ((x>>28)==0) {n= n+4; x= x < <4;}if ((x>>30)==0) {n= n+2; x= x < <2;}
    n= n-(x>>31);return31-n;
}


没想到还可以这样玩啊。小桥,我对你的敬仰就如涛涛江水啊。


别敬仰我……
请到do_fork的资源下载频道……
很多好东西……
你看你也会……
[/Quote]一律三分,太贵了!!我只有50分了
yzx714 2010-02-06
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 mstlq 的回复:]
引用 6 楼 xylicon 的回复:
引用 3 楼 mstlq 的回复:
32bit版本,思路是二分法
C/C++ codeint f1(unsigned x)
{int n=1;if(x==0)return-1;if ((x>>16)==0) {n= n+16; x= x < <16;}if ((x>>24)==0) {n= n+8; x= x < <8;}if ((x>>28)==0) {n= n+4; x= x < <4;}if ((x>>30)==0) {n= n+2; x= x < <2;}
    n= n-(x>>31);return31-n;
}


没想到还可以这样玩啊。小桥,我对你的敬仰就如涛涛江水啊。


别敬仰我……
请到do_fork的资源下载频道……
很多好东西……
你看你也会……
[/Quote]我也去看下
ly8008csko 2010-02-06
  • 打赏
  • 举报
回复
Michael_g 内嵌汇编很简单,不过据说 bsr 指令不是很快,所以和 mstlq 的算法那个更快还得验证一下
xylicon 2010-02-06
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 mstlq 的回复:]
引用 6 楼 xylicon 的回复:
引用 3 楼 mstlq 的回复:


别敬仰我……
请到do_fork的资源下载频道……
很多好东西……
你看你也会……
[/Quote]

多谢指点,我去搵下先。
mstlq 2010-02-06
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 xylicon 的回复:]
引用 3 楼 mstlq 的回复:
32bit版本,思路是二分法
C/C++ codeint f1(unsigned x)
{int n=1;if(x==0)return-1;if ((x>>16)==0) {n= n+16; x= x < <16;}if ((x>>24)==0) {n= n+8; x= x < <8;}if ((x>>28)==0) {n= n+4; x= x < <4;}if ((x>>30)==0) {n= n+2; x= x < <2;}
    n= n-(x>>31);return31-n;   
}


没想到还可以这样玩啊。小桥,我对你的敬仰就如涛涛江水啊。
[/Quote]

别敬仰我……
请到do_fork的资源下载频道……
很多好东西……
你看你也会……
xylicon 2010-02-06
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 mstlq 的回复:]
32bit版本,思路是二分法
C/C++ codeint f1(unsigned x)
{int n=1;if(x==0)return-1;if ((x>>16)==0) {n= n+16; x= x<<16;}if ((x>>24)==0) {n= n+8; x= x<<8;}if ((x>>28)==0) {n= n+4; x= x<<4;}if ((x>>30)==0) {n= n+2; x= x<<2;}
n= n-(x>>31);return31-n;
}
[/Quote]

没想到还可以这样玩啊。小桥,我对你的敬仰就如涛涛江水啊。
Michael_g 2010-02-06
  • 打赏
  • 举报
回复
pos 里返回的是 num 左边起第一个1的位置索引(索引以右边0为基础)
Michael_g 2010-02-06
  • 打赏
  • 举报
回复
int num =0x1245;
int pos =0;
_asm{
bsr eax,num;
mov pos,eax;
}
mstlq 2010-02-06
  • 打赏
  • 举报
回复
32bit版本,思路是二分法
int f1(unsigned x)
{
int n=1;
if(x==0) return -1;
if ((x>>16) == 0) {n = n+16; x = x<<16;}
if ((x>>24) == 0) {n = n+8; x = x<<8;}
if ((x>>28) == 0) {n = n+4; x = x<<4;}
if ((x>>30) == 0) {n = n+2; x = x<<2;}
n = n-(x>>31);
return 31-n;
}
xylicon 2010-02-06
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 xylicon 的回复:]
http://topic.csdn.net/u/20100122/20/6b5f6591-4ba5-4f18-a0d1-d75e2052b4f0.html

看看这个是不是你要的答案
[/Quote]

貌似和你的问题不一样。其实lz的那个已经很高效了。时间复杂度也只是O(n)
xylicon 2010-02-06
  • 打赏
  • 举报
回复

69,382

社区成员

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

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