Chinaunix
标题:
求一个整数是2的多少次方的算法
[打印本页]
作者:
changsha
时间:
2015-08-28 13:03
标题:
求一个整数是2的多少次方的算法
#include <stdio.h>
#include <time.h>
#ifdef __BBO
#define BIT_1_POS(__value, __ret) { \
unsigned long __n = __value; \
unsigned __lg = 0; \
if (__n > 0x80000000) { __lg += 32; __n >>= 32; } \
if (__n > 0x8000) { __lg += 16; __n >>= 16; } \
if (__n > 0x80) { __lg += 8; __n >>= 8; } \
if (__n > 8) { __lg += 4; __n >>= 4; } \
if (__n == 8) __lg += 4; \
else if (__n == 4) __lg += 3; \
else if (__n == 2) __lg += 2; \
else if (__n == 1) __lg += 1; \
__ret = __lg; \
}
#else
#define BIT_1_POS(__value, __ret) { \
int __i = 0; \
for (unsigned long __n = __value; __n != 0; ++__i) __n >>= 1; \
__ret = __i; \
}
#endif // 0
int main() {
unsigned pos;
struct timespec tp0, tp1;
clock_gettime(CLOCK_REALTIME, &tp0);
for (int i = 0; i < 1000000; ++i) {
unsigned long n = (1L<<63);
while (n) {
BIT_1_POS(n, pos);
// BIT_1_POS(1<<4, pos);
n >>= 1;
}
BIT_1_POS(n, pos);
}
clock_gettime(CLOCK_REALTIME, &tp1);
tp1.tv_sec -= tp0.tv_sec;
if (tp1.tv_nsec >= tp0.tv_nsec) {
tp1.tv_nsec -= tp0.tv_nsec;
} else {
tp1.tv_sec--;
tp1.tv_nsec += 1000000000 - tp0.tv_nsec;
}
printf("elsp. time: %li.%09li\n", (long)tp1.tv_sec, (long)tp1.tv_nsec);
}
复制代码
作者:
changsha
时间:
2015-08-28 13:05
本帖最后由 changsha 于 2015-08-28 13:06 编辑
二分算法比简单for循环效率高不少
作者:
Dannysd
时间:
2015-08-28 14:44
本帖最后由 Dannysd 于 2015-08-28 16:10 编辑
#include<stdio.h>
#include<stdlib.h>
int log_2(int value);
int log_2(int value)
{
if (value == 1) {
return 0;
}
else {
return 1+log_2(value>>1);
}
}
int main(int argc, char **argv)
{
int num;
printf("输入一个整数:");
scanf("%d", &num);
if(num <= 0) { //补充
printf("%d,输入非法\n", num);
return -1;
}
if(num & (num-1)) {
printf("%d不是2的幂次方!\n", num);
}
else {
printf("%d是2的%d次方!\n", num, log_2(num));
}
return 0;
}
复制代码
作者:
bruceteen
时间:
2015-08-28 15:16
为什么不直接用 bsr 函数(bit scan reverse)?
虽然 C/C++ 中没有,但 汇编、gcc、vc 中都有
作者:
serenemoon
时间:
2015-08-28 15:17
回复
3#
Dannysd
you missed 0.
given 0, you program will crash.
作者:
soul11201
时间:
2015-08-28 16:02
提示:
作者被禁止或删除 内容自动屏蔽
作者:
Dannysd
时间:
2015-08-28 16:07
回复
5#
serenemoon
谢谢serenemoon提醒,哈哈,真是忘记做判断了
作者:
seanking1987
时间:
2015-08-28 17:12
还是看三楼的代码舒服些
作者:
lost_templar
时间:
2015-08-28 17:57
uint32_t v; // find the log base 2 of 32-bit v
int r; // result goes here
static const int MultiplyDeBruijnBitPosition[32] =
{
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};
v |= v >> 1; // first round down to one less than a power of 2
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
r = MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27];
复制代码
这么老的代码,网上到处都是
作者:
soul11201
时间:
2015-08-28 19:42
提示:
作者被禁止或删除 内容自动屏蔽
作者:
changsha
时间:
2015-08-28 21:16
还是汇编最快
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2