把一个整数拆成 2 的N次方的和 ,当然这个整数是刚好可以拆的如:50=32+16+2  
我所用的二个算法如下:
第一个:
Int64 sum=50;
                                Int64  p ;
                                int i=(int)(System.Math.Log((double)sum)/System.Math.Log(2));
                                for( ; i > 0 ; i--)
                                {
                                        p = (Int64)System.Math.Pow(2,i);
                                        if(sum >= p)  
                                        {
                                                Int64 c=(Int64)System.Math.Pow((double)2,(double)i);
                                                this.textBox1.Text += " ---->" + i.ToString() ;
                                                sum -= p;
                                        }
                                }
第二个:
Int64 i=50;
                                int b=0;
                                Int64 a;
                                do
                                {
                                        a=i&1;
                                        if(a==1)
                                        {
                                                textBox1.Text+="--->"+b.ToString();
                                        }
                                        i=i>>1;
                                        b++;
                                }while(i!=0);
这两个算法的效率还能不能再优化,请高手指点,还有第一个的算法要比第二个快也请高手指点移位为什么函数要慢呢?只是慢一点点

解决方案 »

  1.   

    最重要你的输出是什么……我想到了一个很高效的算法:long i = 50;long mask = 1;
    while ( mask > 0 )
    {
      Console.Write( i & mask );
      mask <<= 1;
    }
      

  2.   

    求得的值是2的N次方的计算值,或者是 N 的值===================bbs.shoucao.cn========================    QQ群:13827630 ,论坛bbs.shoucao.cn更会有想不到的收获        幸运草为大家提供控件源码下载,开源项目收集。===================bbs.shoucao.cn========================
      

  3.   

    算法来了:
    其中i是你输入的整数。public string getshu(long i)
    {
    string ss=Convert.ToString(i,2);
    int k=ss.Length;
    string st="";
    for(int j=0;j<k;j++)
    {
    if(ss[j]=='1')st+=Math.Pow(2,k-j-1).ToString()+"+";
    }
    return i.ToString()+"="+st.Substring(0,st.Length-1);
    }
      

  4.   

    同意Ivony()稍微改下,输出漂亮点
    long i = 50;
    long mask = 1;
    long cur=0;
    while ( mask > 0 )
    {
      
      cur=mask&i;
      if(cur>0)
       Console.Write(cur+" ");
      mask <<= 1;
    }
      

  5.   

    感谢以上各位的帮助,通过比较   Ivony()  shrinerain(圣影雨) 整理的算法更快一点
      

  6.   

    用位运算应该会高效些。
                long i = 50;            long mask = 1;
                while (mask <i)
                {
                    if ((i & mask)!=0)
                    {
                        Console.WriteLine(i & mask);
                    }
                    mask <<= 1;
                }Ivony(),STRONG
      

  7.   

    public String getBinStr(long i)
    {
     String tmp="";
    if (i!=0){
     tmp+=getBinstr(i/2);
     if (i%2==0) tmp+="0"; else tmp+="1"; 
    }
    return tmp;
    }
      

  8.   

    同意Ivony()稍微改下,输出漂亮点
    long i = 50;
    long mask = 1;
    long cur=0;
    while ( mask > 0 )
    {
      
      cur=mask&i;
      if(cur>0)
       Console.Write(cur+" ");
      mask <<= 1;
    }=======================================这个是故意不这样写的,因为不确定输出是什么,比如说,我自己做了一个输出,类似于这样public void Output( int i )
    {
      ...
    }
    我就可以直接在这里拦截:
    public void Output( int i )
    {
      if ( i == 0 ) return;  ...
    }不过后来想想,函数调用一次也存在一次拷贝操作,而且花费也颇大,所以还是直接在代码中拦截也许更好。数值越大,这个算法效率越高……
    因为它就是弄一位二进制不断左移把所有的二进制位输出的。
    如果是C++,那么就有更极端的写法了,呵呵……
      

  9.   

    如果要追求效率最大,还是不能那样:long i = 50;for ( long mask = 1; mask > 0; mask <<= 1 )
    {
      if ( i & mask == 0 )
        continue;
      Console.Write( mask + " " );
    }简洁,高效……
      

  10.   

    麻烦Ivony() 说明一下上面的循环什么时候结束。。也即mask<=0什么时候发生?为什么?
      

  11.   

    用while (mask <i)作循环条件不是可以吗?关于for ( long mask = 1; mask > 0; mask <<= 1 )什么时候结束,应该是移位超过64次的时候吧,long。
      

  12.   

    谢谢楼上的。。我知道结果了。。
    一直到mask=-9223372036854775808。。没错是超过long的范围的时候。。如果加上条件mask<=i就不用循环那么多次了。。
      

  13.   

    对,应该用mask < i比较好mask < 0是因为当1到最顶位的时候,由于那个位是符号位,所以mask就会变负数了……
      

  14.   

    最终优化结果:long i = 50;for ( long mask = 1; mask <= i; mask <<= 1 )//要用<=
    {
      if ( i & mask == 0 )
        continue;
      Console.Write( mask + " " );
    }