32位整数的二进制位数

redstorm_fyy 2007-02-05 03:00:48
求任意32位整数的二进制位数的算法
比如,4用二进制表示为100,二进制位数为3.
8表示为1000,二进制位数为4,等等
要求效率高,
...全文
1370 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
晨星 2007-02-06
  • 打赏
  • 举报
回复
完全二叉树,好象不管什么情况,一分律要循环5次,而按字节查表法是在最环的情况下循环4次。
当然,具体的效率只有执行了才知道,呵呵。
bpttc 2007-02-06
  • 打赏
  • 举报
回复
上面的算法对最大的32位数"111111...1"循环32次而已
bpttc 2007-02-06
  • 打赏
  • 举报
回复
晕了 搞了半天居然没看清题目 罪过...

i=0;
while(n!=0)
{
n/=2;
++i;
}

i就是结果
bpttc 2007-02-06
  • 打赏
  • 举报
回复
#include <stdio.h>

void main()
{
int num[16]={4,1,2,2,
3,3,3,3,
4,4,4,4,
4,4,4,4};

unsigned int n=0, i=0, j=0;

scanf("%d",&n);

while(n!=0)
{
j=n%16;
n/=16;
++i;
}

printf("%d\n",num[j]+(i-1)*4);
}

先判断出转换成16进制数的位数,再判断16进制数首位数对应的2进制数的位数

这样对"0xFFFF"也只用4次循环而已
bpttc 2007-02-06
  • 打赏
  • 举报
回复
也可以先利用堆栈先转换到16进制数

构建一个栈;

while(n!=0)
{
n%16入栈;
n/=16;
}

从栈逐个弹出,并利用一个16进制数对应一个4位二进制数进行转换,注意第一个弹出元素前面的0
fosjos 2007-02-06
  • 打赏
  • 举报
回复
int get_bit_num(unsigned int m) {
static const int TABLE[256] = {...};
const int size = sizeof(unsigned int);
char *b = (char *)&m; //这样可以省去移位操作,没试过,应该不会出错吧
for(int i = 0; i < size; ++i) {
if(TABLE[b[i]]) {
return TABLE[b[i]] + 8*(size-i-1);
}
}
return 0;
}
bpttc 2007-02-05
  • 打赏
  • 举报
回复
构建一个栈

while(!n)
{
n%2入栈;
n/=2;
}

逐个弹出栈,得答案
fosjos 2007-02-05
  • 打赏
  • 举报
回复
突然想到完全二叉查找树,不知道效率如何

int search(long int n){
static long int tree[64]={ 0,
0xffff0000,0xff000000,0x0000ff00,/*第1,2层*/
0xf0000000,0x00f00000,0x0000f000,0x000000f0,/*3*/
0xc0000000,0x0c000000,0x00c00000,0x000c0000,/*4*/
0x0000c000,0x00000c00,0x000000c0,0x0000000c,/*4*/
0x80000000,0x40000000,0x08000000,0x04000000,/*5*/
0x00800000,0x00400000,0x00080000,0x00040000,/*5*/
0x00008000,0x00004000,0x00000800,0x00000400,/*5*/
0x00000080,0x00000040,0x00000008,0x00000004,/*5*/
32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,/*6*/
16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1/*6*/
};
int i=1; /* root */
while (i<32) {
if(tree[i] & n)
i <<= 1; /*left child*/
else {
i <<= 1; /*right right*/
i ++;
}
}
return tree[i];
}
redstorm_fyy 2007-02-05
  • 打赏
  • 举报
回复
牛!
不过我测试出来居然没有查表的方法快
晨星 2007-02-05
  • 打赏
  • 举报
回复
BSR,强。
gxqcn 2007-02-05
  • 打赏
  • 举报
回复
typedef unsigned int UINT32;

const UINT32 GetBits( const UINT32 u32Num )
{
/* 这是我从 HugeCalc 源代码中抽取的,保证很快!*/

UINT32 u32Bits;
_asm
{
bsr eax, u32Num
mov [u32Bits], eax
}

return ++u32Bits;
}
晨星 2007-02-05
  • 打赏
  • 举报
回复
失策了,省掉了移位运算,却多出来求下标的指针加法运算。- -b
redstorm_fyy 2007-02-05
  • 打赏
  • 举报
回复
难道不能通过简单几个位运算办到吗?
晨星 2007-02-05
  • 打赏
  • 举报
回复
如果确定了CPU的字节顺序类型,还可以再把移位运算省掉:

#include <string>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;

struct base {
static const int TABLE[256];
static const int UINT_SIZE = sizeof(unsigned int);
union uint_uchar {
unsigned int i;
unsigned char a[UINT_SIZE];
};
};

const int base::TABLE[256] = {
0,
1,
2, 2,
3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
};

template <bool LITTLE_ENDIAN>
struct CPU : base {
static int get_bit_num(unsigned int m) {
uint_uchar uc;
uc.i = m;
for(int i = UINT_SIZE - 1; i >= 0; --i) {
int bits = TABLE[uc.a[i]];
if(bits) {
return bits + i * 8;
}
}
return 0;
}
};

template<>
struct CPU<false> : base {
static int get_bit_num(unsigned int m) {
uint_uchar uc;
uc.i = m;
for(int i = 0; i < UINT_SIZE; ++i) {
int bits = TABLE[uc.a[i]];
if(bits) {
return bits + (UINT_SIZE - i - 1) * 8;
}
}
return 0;
}
};

int main() {
unsigned int testors[] = {1, 2, 3, 4, 16, 32, 33, 64, 127, 128, 65536,
2147483647, 2147483648, 2147483656};
for(int i = 0; i < sizeof(testors) / sizeof(testors[0]); ++i) {
cout << testors[i] << ": " << CPU<true>::get_bit_num(testors[i]) << endl;
}
}
redstorm_fyy 2007-02-05
  • 打赏
  • 举报
回复
To: doubhor()
看错了,按字节查表,确实是目前讨论出最快的
redstorm_fyy 2007-02-05
  • 打赏
  • 举报
回复
To: taodm(taodm)
查表只适用于8位整数不适用于32位
To: doubhor()
循环算法太慢,此帖的目的就是为了找一个高效的算法

To:jixingzhong(瞌睡虫·星辰)
经过测试 很慢
晨星 2007-02-05
  • 打赏
  • 举报
回复
查表法应该更快:

int get_bit_num(unsigned int m) {
static const int TABLE[256] = {
0,
1,
2, 2,
3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
};
const int size = sizeof(unsigned int);

for(int i = 0; i < size; ++i) {
const int low_bits = 8 * (size - i - 1);
unsigned int t = m >> low_bits;
if(TABLE[t]) {
return TABLE[t] + low_bits;
}
}
return 0;
}
doubhor 2007-02-05
  • 打赏
  • 举报
回复
int lenInt(int c)
{
if (c < 0)
{
return 32;
}

int len = 0;
while (c != 0)
{
c >>= 1;
len++;
}
return len;
}
taodm 2007-02-05
  • 打赏
  • 举报
回复
查表法。每个字节对应的0~255放在表里。
jixingzhong 2007-02-05
  • 打赏
  • 举报
回复
关键就是 itoa 将数值转化为 2进制序列字符串,
然后计算该字符串的长度即可 ~
加载更多回复(3)

69,382

社区成员

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

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