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

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. 看不懂来打我,Vue3的watch是如何实现监听的?

    前言 watch这个API大家都很熟悉,今天这篇文章欧阳来带你搞清楚Vue3的watch是如何实现对响应式数据进行监听的.注:本文使用的Vue版本为3.5.13. 关注公众号:[前端欧阳],给自己一个 ...

  2. mongo之常见问题

    最近发现服务器上的MongoDB由于oom导致服务被杀死 1.查看oom时间 grep "Out of memory" /var/log/message 或者 dmesg -T|g ...

  3. PythonDay2Base

    PythonDay2Base 前文见上一篇文章 数据类型详解 字符串 str 补充 startswith 判断字符串是否以某个小字符串开头 s1 = "shujia数加科技学习study&q ...

  4. springboot 实现通用责任链模式

    1.概述 在我们平时的工作中,填写分布填写数据,比如填入商品的基本信息,所有人信息,明细信息,这种情况就可以使用责任链模式来处理. 2.代码实现 2.1商品对象 public class Produc ...

  5. Intel Pin初探

    1.在/home/hf/Desktop/pin/pin-3.30-98830-g1d7b601b3-gcc-linux/source/tools/ManualExamples/目录下写自己的pinto ...

  6. Terraform Aliyun 创建ecs, kubernetes 实例

    Terraform Aliyun 创建ecs, kubernetes 实例 terraform demo for aliyun 创建vpc, 网关, EIP, ecs, kubernetes, Ser ...

  7. 使用PG的部分索引

    PG 又带来一个惊喜. 现在有一张表,每天增加几十万数据,数据量迅速超过 1亿.此时 create_at 上的索引已经非常庞大,检索速度很慢. 接下来要分表分区了? NO,PG 有一个非常有意思的特性 ...

  8. [SQL]null值被比较的结果问题

    场景还原 有一个字段是 已删除 deleted 如果0 则是未删除 如果1 则是已删除 我写的where条件是 deleted != 1 然后数据库里面这个字段的值都是null 我当时就想,null值 ...

  9. 【转载】茅台巽风app地图详解,做任务不迷路,纯手绘

    茅台发布了新的app"巽风" 根据"巽值"的排名,发放20000个虎年茅台的资格,还是可以玩一玩的 哪些途径获取"巽值" 1.做任务,和游戏 ...

  10. JVM实战—2.JVM内存设置与对象分配流转

    大纲 1.JVM内存划分的原理细节 2.对象在JVM内存中如何分配如何流转 3.部署线上系统时如何设置JVM内存大小 4.如何设置JVM堆内存大小 5.如何设置JVM栈内存与永久代大小 6.问题汇总 ...