zoukankan      html  css  js  c++  java
  • 求一个整数是2的几次幂(极其高效)

    1.源自linux内核源码中的一段(有汇编的,不过摘抄的c实现的,并做了一点变形)

    汇编的不做比较,记录下而已
    Linux/arch/avr32/include/asm/page.h

    /* Pure 2^n version of get_order */
    static inline int get_order(unsigned long size)
    {
            unsigned lz;
    
            size = (size - 1) >> PAGE_SHIFT;
            asm("clz %0, %1" : "=r"(lz) : "r"(size));
        return 32 - lz;
    }

    内核中的原版
    Linux/arch/mn10300/include/asm/page.h

    #define PAGE_SHIFT 12
    /* Pure 2^n version of get_order */
    static inline int get_order(unsigned long size) __attribute__((const));
    static inline int get_order(unsigned long size)
    {
            int order;
    
            size = (size - 1) >> (PAGE_SHIFT - 1);
            order = -1;
            do {
                    size >>= 1;
                    order++;
            } while (size);
            return order;
    }

    小变更后的:

    static inline int get_order(unsigned long size)
    {
        int order;
        size = (size - 1) >> (0);
        order = -1;
        do {
            size >>= 1;
            order++;
        } while (size);
        return order;
    }

    2.源自lua源码中的一段

    int luaO_log2 (unsigned int x) {
      static const unsigned char log_2[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 l = -1;
      while (x >= 256) { l += 8; x >>= 8; }
      return l + log_2[x];
    }

    貌似纯C的话,还是lua的这个函数快吧。

    最近的一个小需求是,根据size值,变更为接近2的幂的一个数(还多亏看了下lua源码。。。)。
    1<<(luaO_log2(size)+1);
    判断一个数是否为2的幂,为真则为2的幂:
    #define is2power(a) (((a) & ((a)-1)) == 0)

    才发现求余的位运算版。。。
    #define dmod((a), (b)) ((a)&((b)-1)) 等于 a%b  b要为2的幂

    貌似很高效。留记录。

  • 相关阅读:
    qemu的几篇文章---涉及qemu的注入
    网络以及linux相关--重点参考--包含相关linux服务的部署和使用
    ipv6的相关情况简略说明
    向日葵服务器相关ip,通过ipset过滤(oray.com oray.net),可能不完整,需要dnsmasq ipset持续监听相关域名
    linux shell重要参考网站
    web信息收集分类
    针对管理员的信息收集 以及 它的意义
    目标网站弱点功能探测
    网站文件目录探测
    目标后台探测以及物理路径探测
  • 原文地址:https://www.cnblogs.com/lcinx/p/10570469.html
Copyright © 2011-2022 走看看