我需要求一整形变量的位长,如3的位长是2“11(二进制)”
我的代码如下:
if(i < 0)
   i = -1 * i; 
length = 0; 
while(i != 0)

   i = i >> 1; 
   length ++;
};
i为整形变量,length为位长,由于该断代码在程序中反复调用,有没有办法可以做到比我这段代码效率更高(我已做成宏了,但速度没见高多少).

解决方案 »

  1.   

    改为
    for(length=0;(i>>=1)!=0;length++)
    {
    }
    for的效率 比 while的 效率高!
    或者
    内嵌ASSEMBLY,ASSEMBLY的执行效率是很高的,
      

  2.   

    首先做一个数组,下面用二进制
    下标:值
    0:   1
    1:   11
    2:   111其余类推。这个数组的作为mask,通过二酚的方法用mask对证书进行检测,一个32位的证书,
    最多检测5次。
      

  3.   

    ============================================================================
    http://www.betajin.com/alphasun/index.htm
    DocWizard C++程序文档自动生成工具 | Wave OpenGL | HttpProxy | AjaxParser词法分析
      

  4.   

    static int list[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 }; for (int check = 1; check != 0; check = check << 1 )
    {
    unsigned char *pb = (unsigned char *)&check; for (int i = 3; pb[i] == 0; i --) {};
    int length = (i << 3) + list[ pb[i] ]; cout << "length = " << length << endl;
    }
      

  5.   

    如果是 8-bit 值就好了,直接int length = list[ check ];
      

  6.   

    if(i < 0)
       i = -1 * i; 
    length = 0; 
    char temp[16]="";
    sprintf(temp,"%x",i);
    int temp_len=strlen(temp);
    if(temp[0]>=0x38) length = temp_len*4;
    else if(temp[0]>0x34) length = temp_len*4-1;
    else if(temp[0]>0x32) length = temp_len*4-2;
    else length = temp_len*4-3;
      

  7.   

    check == 0 时有错误,修正一下:int length = 0;if (check)
    {
        unsigned char *pb = (unsigned char *)&check;
        for (int i = 3; i > 0 && pb[i] == 0; i --) {};
        length = (i << 3) + list[ pb[i] ];
    }cout << "length = " << length << endl;
      

  8.   

    TO alphapaopao(炮炮) 你的判断是只需要5次,但是你的数组要多么大?
      

  9.   

    最终版,呵呵:static int list[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 }; inline int _length8(unsigned char v8)
    {
    return list[v8];
    }inline int _length16(unsigned short v16)
    {
    return (v16 > 255) ? 8 + _length8(v16 >> 8) : _length8(v16);
    }inline int _length32(unsigned int v32)
    {
    return (v32 > 65535) ? 16 + _length16(v32 >> 16) : _length16(v32);
    }
      

  10.   

    还是In355Hz(好象一条狗) 的数组
    static int list[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 }; int returnbitvalue(unsigned m)
    {
    if(m<=0xff)
    return list[m];
    else if(m<=0xffff)
    return list[m>>8]+list[m&0xff00]
    else if(m<=0xffffff)
    return list[m>>16]+list[m&(0xff<<16]+list[m&(0xff<<8]
    else if(m<=0xffffffff)
    return list[m>>24]+list[m&(0xff<<0xff000000]+list[m&0xff0000]+list[m&0xff00];
    }具体位置根据你实际的概率。
      

  11.   

    To In355Hz(好象一条狗) 真狠啦!数组是静态的,函数是内联的。
      

  12.   

    BinaryWorld(小生菜鸟)
    我的数组只有 32 个元素,因为32位的mask,只要 32 个。
      

  13.   


    if(i < 0)
       i = -i; 
    length = 0; 
    while(i != 0)

       i = i >> 1; 
       length ++;
    };可以少一个字节
      

  14.   

    我还是把代码写一下吧//////////////////////////////////////////////
    //mask数组准备DWORD aMask[31];
    int i=31;
    DWORD w = -1;
    while(i>=0)
    {
    aMask[i--] = w>>1;
    }//////////////////////////////////////////////
    // 计算位长
    int a=31, b=0, m;
    DWORD dwTest; // 测试这个整数
    while(a-b>1)
    {
    m=(a+b);
    m = m>>1;
    if(dwTest & aMask[m])
    b = m;
    else
    a = m;
    }int nLen = b+1; // 这就是最后的位长度
      

  15.   

    修正i初始值错误//////////////////////////////////////////////
    //mask数组准备DWORD aMask[31];
    int i=30;
    DWORD w = -1;
    while(i>=0)
    {
    aMask[i--] = w>>1;
    }
      

  16.   

    谢过各位了.
    我是要对一组图像做JPEG无损压缩,大小是1k*1k*100frames,现在能做到10s左右,总觉得还可以在快一些,我知道优化应当在算法流程和结构上下功夫,但总想不出更好的解决途径,只好在语法上解决,但这样做不会导致效率的大幅度提高。我见到一国外的软件自称能做到30帧/s,感觉差距好大亚,汗。难道非得用汇编吗?我大部分的运算已经是位操作了,总感觉用汇编相差也不会很大
      

  17.   

    其实算法是关键,编译器的优化只能作补充。另外,CPU的多媒体指令,可以加以利用,效果也不错,不过难度高。
      

  18.   

    int fn(long v){
    int iret;
    _asm{
     mov edx v
     mov eax 32
    loop:
     shl edx
     dec eax
     gz loop
     mov iret eax
    }
    return iret;
    }
      

  19.   

    楼上的代码是汇编吧,我在VC里怎么用ya?
      

  20.   

    To alphapaopao(炮炮) 
    不好意思,在下理解错误了!
    只要判断到最大一位位置就可以了。
    二分查找的速度快!
      

  21.   

    __asm
    {
     //vc中的汇编代码
    }

    __asm mov ....
    __asm .......//汇编代码
      

  22.   

    我已经很长时间没用汇编了,前面的代码范了很多低级错误。下面的代码已在vc6.0上调试通过。这是嵌入式汇编,你可以直接copy过去用。盖函数返回value的位长 。
    int fn(long value){
      int num;
      _asm{
         mov eax,0
         mov edx,value
         add edx,0
         jz exit
      isnotzero:
         inc eax
         shr edx,1
         jnz isnotzero
      exit:
         mov num, eax
      }
      return num;
    }
    不过我还要提醒你几句,这样的优化对你“一组图像做JPEG无损压缩”来说,不见得能有多少提高。像这种问题最关键还是算法,你应该先找一个优良的算法,然后再考虑编码的优化,而编码优化由谈何容易,内存分页,线程调度,cpu的指令预测,高速缓存命中,所有这些都会使看似优化的代码在执行是莫名其妙的要用很多时间。
      

  23.   

    我写几行代码大家看看,能否实现功能:CString tempStr;
    int yourNumber = 100;
    int yourResult = 0;_itoa(yourNumber, tempStr.GetBuffer(20), 2);//将整型数据转换成二进制的字符串,
    //如3转换成“11”,然后获取长度就可以了,如果位数多,可用_ltoa()函数等;
    tempStr.ReleaseBuffer(-1);
    yourResult = tempStr.GetLength();这几行代码没有测试,如果只要实现获取位数的功能的话,是完全可以实现的,不需要用循环和判断,效率应该是很客观的。