• 求一个整数是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的幂

    貌似很高效。留记录。

  • 相关阅读:
    引用 Geoprocessing调用ArcToolBox工具使用总结
    MySQL权限改观何时生效
    Ubuntu下安装*.bin挨次
    创立初始的MySQL权限
    MySQL的日期和光阴范例
    MySQL存取节制, 阶段1:连接证明
    让Linux操作零碎可以Mount NTFS分区
    Citrix进级XenDesktop桌面虚拟化产物
    如何在两台MySQL数据库间完成同步
    MySQL的数字
  • 原文地址:https://www.cnblogs.com/lcinx/p/10570469.html
Copyright © 2020-2023  润新知