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的幂

    貌似很高效。留记录。

  • 相关阅读:
    oracle 11g行转列 列转行
    System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本
    ORA-00257: 归档程序错误。在释放之前仅限于内部连接
    java 回传参数
    Oracle 删除表分区
    Oracle 删除重复数据只留一条
    cmd下windows批处理,获取当前系统时间,生成日志文件名
    c# 应用程序部署发布
    eclipse 集成 STS 插件
    Mamen所需要的jar包怎么生成
  • 原文地址:https://www.cnblogs.com/lcinx/p/10570469.html
Copyright © 2011-2022 走看看