先上核心代码(文末附针对多种整数类型的代码):

inline int log_2(int x) {
int rst = 0;
if (x & 0xffff'0000U) rst += 16, x >>= 16;
if (x & 0x0000'ff00U) rst += 8, x >>= 8;
if (x & 0x0000'00f0U) rst += 4, x >>= 4;
if (x & 0x0000'000cU) rst += 2, x >>= 2;
if (x & 0x0000'0002U) rst += 1 ;
return rst;
}

原理很简单:

首先,任意正整数都可以拆分为数个互不相等的 2 的幂的和,且这些 2 的幂都小于等于该数;

其次,int 占用 32 位,故对于 int 范围内的数,其对数都不超过 31

最后,容易注意到二进制与对数间的天然联系,介于这种联系是显然且不易描述的,在此不予点明[doge];

综上,对于 int 类型的数据,其对数必然可以通过 {16, 8, 4, 2, 1} 组合出来,通过其二进制位即可判断其对数是由那几个数组合的。


附录(以下代码效率差别可以忽略不计,但代码量有显著差距):

inline auto log_2(uint64_t x) { // also unsigned long long
uint64_t rst = 0;
if (x & 0xffff'ffff'0000'0000ULL) rst += 32, x >>= 32;
if (x & 0x0000'0000'ffff'0000ULL) rst += 16, x >>= 16;
if (x & 0x0000'0000'0000'ff00ULL) rst += 8, x >>= 8;
if (x & 0x0000'0000'0000'00f0ULL) rst += 4, x >>= 4;
if (x & 0x0000'0000'0000'000cULL) rst += 2, x >>= 2;
if (x & 0x0000'0000'0000'0002ULL) rst += 1 ;
return rst;
}
inline auto log_2(uint32_t x) { // also unsigned int
uint32_t rst = 0;
if (x & 0xffff'0000U) rst += 16, x >>= 16;
if (x & 0x0000'ff00U) rst += 8, x >>= 8;
if (x & 0x0000'00f0U) rst += 4, x >>= 4;
if (x & 0x0000'000cU) rst += 2, x >>= 2;
if (x & 0x0000'0002U) rst += 1 ;
return rst;
}
inline auto log_2(uint16_t x) { // also unsigned short
uint16_t rst = 0;
if (x & 0x0000'ff00U) rst += 8, x >>= 8;
if (x & 0x0000'00f0U) rst += 4, x >>= 4;
if (x & 0x0000'000cU) rst += 2, x >>= 2;
if (x & 0x0000'0002U) rst += 1 ;
return rst;
}
inline auto log_2(uint8_t x) { // also unsigned char
uint8_t rst = 0;
if (x & 0x00f0U) rst += 4, x >>= 4;
if (x & 0x000cU) rst += 2, x >>= 2;
if (x & 0x0002U) rst += 1 ;
return rst;
}

快速 log2 取整算法 (O(1) 时间与空间复杂度)的更多相关文章

  1. 【转】C语言快速幂取模算法小结

    (转自:http://www.jb51.net/article/54947.htm) 本文实例汇总了C语言实现的快速幂取模算法,是比较常见的算法.分享给大家供大家参考之用.具体如下: 首先,所谓的快速 ...

  2. Raising Modulo Numbers_快速幂取模算法

    Description People are different. Some secretly read magazines full of interesting girls' pictures, ...

  3. 栈(stack)、递归(八皇后问题)、排序算法分类,时间和空间复杂度简介

    一.栈的介绍: 1)栈的英文为(stack)2)栈是一个先入后出(FILO-First In Last Out)的有序列表.3)栈(stack)是限制线性表中元素的插入和删除只能在线性表的同一端进行的 ...

  4. log2取整效率测试

    RMQ问题中有个ST算法,当然还有个标准算法.LCA问题可以转化为带限制的RMQ(RMQ+-1)问题来解决.我们姑且认为这些问题的时间复杂度是查询$O(1)$的.但是,注意到对于RMQ(/+-1)问题 ...

  5. 位运算之——按位与(&)操作——(快速取模算法)

    学习redis 字典结构,hash找槽位 求槽位的索引值时,用到了 hash值 & sizemask操作, 其后的scan操作涉及扫描顺序逻辑,对同模的槽位 按一定规则扫描! 其中涉及位运算 ...

  6. 【Java基础】14、位运算之——按位与(&)操作——(快速取模算法)

    学习redis 字典结构,hash找槽位 求槽位的索引值时,用到了 hash值 & sizemask操作, 其后的scan操作涉及扫描顺序逻辑,对同模的槽位 按一定规则扫描! 其中涉及位运算 ...

  7. Powmod快速幂取模

    快速幂取模算法详解 1.大数模幂运算的缺陷: 快速幂取模算法的引入是从大数的小数取模的朴素算法的局限性所提出的,在朴素的方法中我们计算一个数比如5^1003%31是非常消耗我们的计算资源的,在整个计算 ...

  8. 洛谷 P1226 【模板】快速幂||取余运算

    题目链接 https://www.luogu.org/problemnew/show/P1226 题目描述 输入b,p,k的值,求b^p mod k的值.其中b,p,k*k为长整型数. 输入输出格式 ...

  9. 《Java语言实现快速幂取模》

    快速幂取模算法的引入是从大数的小数取模的朴素算法的局限性所提出的,在朴素的方法中我们计算一个数比如5^1003%31是非常消耗我们的计算资源的,在整个计算过程中最麻烦的就是我们的5^1003这个过程 ...

  10. 你可能不知道的 JavaScript 中数字取整

    网上方法很多,标题党一下,勿拍 ^_^!实际开发过程中经常遇到数字取整问题,所以这篇文章收集了一些方法,以备查询. 常用的直接取整方法 直接取整就是舍去小数部分. 1.parseInt() parse ...

随机推荐

  1. SpringMVC源码剖析(四)- DispatcherServlet请求转发的

    SpringMVC完成初始化流程之后,就进入Servlet标准生命周期的第二个阶段,即"service"阶段.在"service"阶段中,每一次Http请求到来 ...

  2. python的orjson

    简介 首先我们先来了解下orjson的优缺点: 可以将datetime.date和time实例序列化为RFC 3339格式,例如:"2022-06-12T00:00:00+00:00&quo ...

  3. nginx之日志

    1)耗时问题定位 这几天在优化服务器的响应时间,在根据 nginx 的 accesslog 中 requesttime进行程序优化时,发现有个接口,直接返回数据,平均的requesttime进行程序优 ...

  4. Mybatis【18】-- Mybatis自关联多对一查询方式

    注:代码已托管在GitHub上,地址是:https://github.com/Damaer/Mybatis-Learning ,项目是mybatis-14-oneself-many2one,需要自取, ...

  5. CSS3 背景图片

    1.背景图大小(background-size) 这个属性设置单张背景图的大小,默认是原图的大小 当同时指定宽高时,会造成图片失真,如果要保持宽高比,可以使用 auto 字段让宽或者高自适应 值类型 ...

  6. 在centos上部署docker与wordpress

    简介 有一个wordpress服务器需要迁移了,之前都是别人维护的,现在需要迁移到自己维护,给的系统是linux centos 8.4.迁移包括mysql,php,phpmyadmin,wordpre ...

  7. 【机器学习】SVM(支持向量机)算法实验

    (一)实验名称:SVM(支持向量机)算法实验 (二)实验目的: 学习支持向量机SVM的基本概念 了解核函数的基本概念 掌握使用scikit-learn API函数实现SVM算法 (三)实验内容:使用s ...

  8. 【Python】conda基本使用、pip换源、pip超时问题解决

    conda问题 重要警告:安装conda的时候,安装目录不要包含空格以及特殊字符,最好不要直接装在C盘根目录, 往期笔记 conda安装: https://www.cnblogs.com/mllt/p ...

  9. 【SpringMVC】框架搭建

    pom.xml 注意,下面代码只是pom.xml中的dependencies部分 <dependencies> <!-- 萌狼蓝天 mllt.cc--> <!-- htt ...

  10. 【Linux】【UOS】为挂载的磁盘创建快捷方式(软链接)

    打开项目或者保存文件的时候,如果需求路径不是系统盘路径,那么找起来还真是麻烦.以下时候通过创建快捷方式(软链接)的方式,将打开磁盘的快捷方式放在用户目录下,就方便寻找打开了. 1.查询挂载点 sudo ...