zoukankan      html  css  js  c++  java
  • 取最小的比n大的2的幂

    是不是很拗口?
    判断一个数n是否是2的幂,只要看n&(n-1)是不是0就行了。
    而找比它大的2的幂,可以先把它最高的一个1位之后全填充1然后加1。
    填充的方法可以是log32 = 5次的按位或。这样就不必做判断而出现分支了。
    也许有更快更好的方法吧,借此抛砖引玉一把。

    #include <cstdio>
    inline 
    bool is_power_of_2(int n)
    {
        
    return (n & (n-1)) == 0;
    }

    inline 
    int min_power_of_2_g(int n)
    {
        
    //return n |= n>>16, n |= n>>8, n |= n>>4, n |= n>>2, n |= n>>1, n + 1; 其实是一样的,显得短一些而已
        return ((((n |= n>>16|= n>>8|= n>>4|= n>>2|= n>>1, n + 1;
    }

    inline 
    int min_power_of_2_eg(int n)
    {
        
    if (is_power_of_2(n))
            
    return n;
        
    return min_power_of_2_g(n);
    }


    int main()
    {
        
    int n;
        
    while(scanf("%d"&n) == 1)
        
    {
            n 
    = min_power_of_2_eg(n);
            printf(
    "%x %d\n", n, n);
        }

        
    return 0;
    }

    /*这里是vc6 release生成的代码:
    mov ecx,dword ptr [esp]    ; 取出n
    mov eax,ecx
    lea edx,[ecx-1]    ;n-1
    test ecx,edx         ; n & (n-1)
    je END1
    sar eax,10h   ; n |= n>>16
    or eax,ecx
    mov ecx,eax
    sar ecx,8   ; n |= n>>8
    or eax,ecx
    mov edx,eax
    sar edx,4  ; n |= n>>4
    or eax,edx
    mov ecx,eax
    sar ecx,2  ; n |= n>>2
    or eax,ecx
    mov edx,eax
    sar edx,1  ; n |= n>>1
    or eax,edx
    inc eax    ; 最后加1
    END1:
    */

  • 相关阅读:
    正则表达式 之领宽断言
    bat(续七)-for语句(循环结构)
    RBAC权限管理
    Redis缓存服务搭建及实现数据读写
    Myeclipse集成Maven(图文说明)
    实习第四周
    POJ 3461 Oulipo KMP算法题解
    原创文章
    apue和unp的学习之旅07——多种边界条件的讨论
    单链表的实现
  • 原文地址:https://www.cnblogs.com/kaikai/p/251925.html
Copyright © 2011-2022 走看看