怎样判断一个数是2的多少次方。欢迎大家进来讨论,进者有分

wgy081 2003-08-22 01:40:22
怎样判断一个数是2的多少次方。欢迎大家进来讨论,进者有分
...全文
1392 143 打赏 收藏 转发到动态 举报
写回复
用AI写文章
143 条回复
切换为时间正序
请发表友善的回复…
发表回复
masterz 2003-08-31
  • 打赏
  • 举报
回复
讨论一下也好,当运算量达到百万,千万的时候,就该考虑算法的速度了。平时积累一下这方面的经验,需要的时候才不会技穷啊。
VC++提供了__asm关键字,怎么能对他熟视无睹呢, intel出了新的指令,新的技术,都是有实际需求才做的,这些功能不去用它,实在浪费。
另外,请大家讨论问题的时候保持冷静,不要搞人身攻击。
baobeixiong 2003-08-31
  • 打赏
  • 举报
回复
int i=0;
int num=100;
int j =2
while(j <= num)
{
j = pow(j,2);
i++;
}


ylgoodman 2003-08-31
  • 打赏
  • 举报
回复
喂,大家是在干什么啊?
判断一个数是2的多少次方有这么复杂吗?
有的甚至还用起了循环,不会这样浪废我们的CPU资源了吧?!
用位的办法,好象还有一点点道理;
我想这应该是有现成的类库,不应该来浪费我们的时间和精力了
taolei 2003-08-31
  • 打赏
  • 举报
回复
靠,在VC里解决这种问题用到ASM我看已经算是技穷了。
zxyin1 2003-08-31
  • 打赏
  • 举报
回复
呵呵,masterz() 老大果然不同凡响,佩服!
tuxw 2003-08-31
  • 打赏
  • 举报
回复
错了,上面漏了n=±1的情况

bool Is(unsigned n)
{
bitset<32> a(abs(n));
return a.count()<=1 && n!=1;
}
tuxw 2003-08-31
  • 打赏
  • 举报
回复
int n;

……

bitset<32> a(abs(n));

cout << boolalpha << (a.count()<=1) << endl;
EA000000021 2003-08-31
  • 打赏
  • 举报
回复
up
VCP4 2003-08-31
  • 打赏
  • 举报
回复
这个问题真的不要讨论太多,大家还是将时间花在看VC区的精华贴更好些。本来是个函数能搞OK的,却越搞越复杂,汇编都要出来,这样下去SSE2指令都要出山了。

int nTemp = 256 * 64; //或256,18,3,168,6400等试试
int nBkTemp = nTemp;
int nCount_2 = 0;//记录是2的多少次方
while( nTemp > 1)
{
if( nTemp % 2 )
{
nCount_2 = 0;
break;
}
nTemp = nTemp >> 1;
nCount_2++;
}
//显示
CString strDisp;
if( nCount_2 )
strDisp.Format("%d 是2的 %d次方", nBkTemp, nCount_2);
else
strDisp.Format("%d 这个数不是2的乘方",nBkTemp);

CClientDC dc(this);
int nBkMode = dc.SetBkMode(TRANSPARENT );
dc.TextOut( 100, 50, strDisp);

dc.SetBkMode( nBkMode );


vbhelp 2003-08-30
  • 打赏
  • 举报
回复
有人能解释清楚这两个程序妙在何处?
vbhelp 2003-08-30
  • 打赏
  • 举报
回复
楼上认为有价值,我看上面程序还不如下面的(权且反击!因为我不懂,响应楼上要求.离开VC)

float ln( unsigned int x ){

const float ln2 = log(2);
int powers_of_2 = 0;
float sum = 0;


while( 2 <= x ){

if( x & 1 ){
sum += 1.0 / (float)x ;
};
x = x >> 1;
powers_of_2++;
};
return( ln2 * powers_of_2 + sum );
}

//程序2:

float ln( unsigned int x ){

const float ln2 = log(2);
int powers_of_2 = 0;
float sum = 0;


while( 2 <= x ){

if( 1 == (x & 3) ){
sum += 1.0 / (float)x ;
x-- ;
};

if( x && 1 ){
sum -= 1.0 / (float)x ;
x++;
};


x = x >> 1;
powers_of_2++;
};
return( ln2 * powers_of_2 + sum );
}

leavesxy 2003-08-30
  • 打赏
  • 举报
回复
if( ( a & ~a ) == a )
//a 是
否则不是 vesl
liangbch 2003-08-30
  • 打赏
  • 举报
回复
我说说我的看法:
1。说这个题太简单,不值得讨论者,只能说明你思考问题的深度不够,自然,求对数是有c运行时刻库函数可以用,这个大多数人都明白。但这类函数一般使用了浮点指令,通过协处理器的实现(浮点指令:FYL2X),速度较整数指令较慢。
2。多数人思考问题的角度是如何不用库函数来计算整数的base 2的对数,在理解问题时,有2种观点.
1.认为只取结果的整数部分,任何整数都可以,在这种情况下,log2(3)=1,log2(4)=2.
2.认为只计算2的整数次幂的对数,其它整数返回错误。
3.在解决问题时,如果只停留在能够求得计算结果即可,说明不是一个好的编程者,大家普遍的想法是,如何能使程序速度更快,大多数人都使用了循环的方式求得,在循环过程中,使用 <<1 或者 >>1者,说明对程序优化有一定认识,知道移位比除法快,
下面是inter cpu 移位运算的速度。

Operands 808x 286 386 486(时钟周期) Bytes
reg,1 2 2 3 2
mem,1 15+EA 7 7 2-4 (W88=23+EA)
reg,CL 8+4n 5+n 3 2
mem,CL 20+EA+4n 8+n 7 2-4 (W88=28+EA+4n)

reg,immed8 - 5+n 3 3
mem,immed8 - 8+n 7 3-5

4。masterz(MS MVP)和 ( duwenyong(啸海) 使用了一个鲜为人知的 asm 指令,这个的确比较快,这种方法用一条指令实现了查找 最高的 为1的 bit,我查了一下资料。bsr的速度为参见下面,但是这个指令较耗时,和传统的循环方式比(使用多条 移位,跳转,比较指令)相比速度快的也有限,并没有数量级的提高.

Clocks Size
Operands 808x 286 386 486 Bytes

reg,reg - - 10+3n 6-103 3
reg,mem - - 10+3n 7-104 3-7
reg32,reg32 - - 10+3n 6-103 3-7
reg32,mem32 - - 10+3n 7-104 3-7
5。iicup(双杯献酒) 使用了switch(x){ case n1:case n2:case n3:..} 语句
case 语句的特点是:当 n1,n2...比较小时,编译程序直接生成地址表,地址表中的每一个元素存储了程序在不同情况下要跳转的地址:
例如:如果地址表为t,则 x=10,则下一指令的地址为t[10],程序可直接跳转,程序的速度和case语句的个数没有关系,但是当某些n(n1,n2)较大时,编译程序将其按if语句来处理。所有当 case n(n较大时)越多,程序的速度就越慢,这样程序的速度和循环语句速度差不多,在该例子中,抛开该程序处理的数的范围(1..32768)较小不谈,程序的速度和循环移位相差不大。
这里比我牛的人很多,也许我没有资格对大家说三道四,如有不当和错误请大家指正。
duqiang2050 2003-08-30
  • 打赏
  • 举报
回复
循环的、递归的、位移的、汇编的,你们别不服气,
人家问题是“怎样判断一个数是2的多少次方。欢迎大家进来讨论,进者有分”,我就问你们“3是2的多少次方?”,你们的方法能求么?功能都没实现,还说什么那
duqiang2050 2003-08-30
  • 打赏
  • 举报
回复
VCP4(左麟右李) :我还是问你“3是2的多少次方?”,你移位的方法能作出来么?功能都没实现,还谈什么速度?还说别的方法是做Show?
limu810812 2003-08-30
  • 打赏
  • 举报
回复
我认为还是右移最快,方法简洁
VCP4 2003-08-30
  • 打赏
  • 举报
回复
这条题后来变了如何是最快的算法,VBHELP的log( double x );由于用了浮点慢很多。
  如果VC真的像上面的两个程序般解决了就达到精通阶段,恐怕100%的人都愿意去做。
VC博大精深,没有人可以说是样样精通,只能是精通某一、二、三方面,即使masterz也如是。数据库的专家,可能连条网络的菜鸟问题也不会答;相反也如此。网络、线程的专家,可能连最简单的DirectX都不会。
  只是这一条题“判断一个数是2的多少次方”较为“碍眼”,其它的置顶包括以前都几乎有“看头的”。
  这条题除了右移最快外,其它的都是在显示各种各样的方法在做Show。
VCP4 2003-08-29
  • 打赏
  • 举报
回复
master答的许多问题都很有水准的,仅写一个:
http://search.csdn.net/expert/topic/50/5010/2002/8/21/959257.htm
VBHELP,你会RSA加密算法或CRC检验算法吗?

VCP4 2003-08-29
  • 打赏
  • 举报
回复
master()水平是很高的,VBHelp你还是去学VB吧,VC不适合你的。
master的
__asm
{
mov ecx, data
bsf eax, ecx
bsr edx, ecx
cmp eax, edx
jz exit_func
mov eax,-1
}
如果你看不明白就从此离去VC吧。
双杯献酒 2003-08-29
  • 打赏
  • 举报
回复
BOOL Is2Pow(unsigned short N)
{
switch(N)
{
case 0x0001:
case 0x0002:
case 0x0004:
case 0x0008:
case 0x0010:
case 0x0020:
case 0x0040:
case 0x0080:
case 0x0100:
case 0x0200:
case 0x0400:
case 0x0800:
case 0x1000:
case 0x2000:
case 0x4000:
case 0x8000:
return TRUE;
default:
return FALSE;
}
}
加载更多回复(123)

16,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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