• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

kaikai向前走

转职任务完成。崭新fn诞生
  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

取最小的比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:
*/

posted on 2005-10-10 20:15  kaikai  阅读(981)  评论(1)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3