【位操作笔记】计算以2为底整数N的对数 查表法
计算以2为底整数N的对数log2Nlog_2Nlog2N 查表法
用于计算以2为底整数N的对数log2Nlog_2Nlog2N。例如 log28=3log_28=3log28=3,log216=4log_216=4log216=4。
算法说明
该算法通过查表的方式来计算以2为底整数N的对数log2Nlog_2Nlog2N。以2为底整数N的对数log2Nlog_2Nlog2N,与最高有效位(most significant bit set,MSB)的位置相同,例如4 = 0x4 = 0b0100,最高有效位在第2位,与log24=2log_24=2log24=2值相等。然后通过查表的方式来计算最高有效位在第几位。32 bit 数最多有 4294967296 种情况,所以生成 32 位数的表来进行查表是不合适的,由于 8 bit 数最多只有 256 个,也就是最多只有 256 种情况,所以通过建 8 bit 数表的方式,然后根据要计算的数的最高有效位在哪个区间,分成 4 种情况来查表计算 log2Nlog_2Nlog2N 的值。四个区间分别为0 - 7 bit,8 - 15 bit, 16 - 23 bit, 24 - 31 bit 四个区间,我们只计算这 8 bit数的最高有效位是多少,然后将计算值加上对应区间的偏移值 0, 8, 16, 24,得到实际的最高有效位在第几位,也就得到了log2Nlog_2Nlog2N。
实现代码
实现方式为:
static const char LogTable256[256] =
{-1,0,1, 1,2, 2, 2, 2,3, 3, 3, 3, 3, 3, 3, 3,4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 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, 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, 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
};unsigned int bit_log2(unsigned int val)
{unsigned int ret;unsigned int tmpval1, tmpval2;if ((tmpval2 = (val >> 16))){ret = (tmpval1 = tmpval2 >> 8) ? 24 + LogTable256[tmpval1] : 16 + LogTable256[tmpval2];}else {ret = (tmpval1 = val >> 8) ? 8 + LogTable256[tmpval1] : LogTable256[val];}return ret;
}
注意,如果传入的参数val
不是2的次幂,则返回值是val
的值向下舍入到最近的2的次幂的对数值。例如 val
的值为10,则返回值为log210=3log_210=3log210=3。
测试程序:
int main(int argc, char* argv[])
{printf("%d\n", bit_log2(32));printf("%d\n", bit_log2(16));printf("%d\n", bit_log2(8));printf("%d\n", bit_log2(10));printf("%d\n", bit_log2(20));return 0;
}
运行结果如下:
5
4
3
3
4
算法计算过程
该算法通过查表的方式来计算以2为底32 bit整数N的对数log2Nlog_2Nlog2N。根据要计算的数最高有效位在哪个范围,分成 4 种情况来查表计算 log2Nlog_2Nlog2N 的值。
第一步,判断要计算的32 bit 整数的高16位(16 - 31 bit)是否有值,有值的话进入第二步,没有的话进入第三步
第二步,判断要计算的数是高8位(24 - 31 bit)是否有值,有值的话将这 8 bit 数进行查表计算,得到的值加上偏移值 24 得到实际的最高有效位;如果高8位(24 - 31 bit)没有值,则将低8位(16 - 23 bit)这 8 bit 数进行查表计算,得到的值加上偏移值 16 得到最高有效位。
第三步,判断要计算的数是32 bit 数的低16位中的高8位(8 - 15 bit)是否有值,有值的话将这 8 bit 数进行查表计算,得到的值加上偏移值 8 得到最高有效位;如果高8位(8 - 15 bit)没有值,则将低8位(0 - 7 bit)这 8 bit 数进行查表计算直接得到最高有效位。
计算示例
例如:
val = 16 = 0x10 = 0b10000,最高有效位在第4位,所以log216=4log_216=4log216=4。
模拟这个计算的过程:
0b10000 >>= 16 => tmpval2 = 0高16位(16 - 31 bit)没有值0b10000 >>= 8 => tmpval1 = 0高8位(8 - 15 bit)没有值LogTable256[val] => LogTable256[16] => 4
结束计算,得到答案4。
[参考资料]
Bit Twiddling Hacks By Sean Eron Anderson
本文链接:https://blog.csdn.net/u012028275/article/details/126843708
【位操作笔记】计算以2为底整数N的对数 查表法相关推荐
- crc16modbus查表法_查表法计算CRC16校验值
/******************************************************************************* * Copyright (c) 201 ...
- crc16码表的使用_查表法计算CRC16校验值
CRC16是单片机程序中常用的一种校验算法.依据所采用多项式的不同,得到的结果也不相同.常用的多项式有CRC-16/IBM和CRC-16/CCITT等.本文代码采用的多项式为CRC-16/IBM: X ...
- 常用crc查表法_查表法计算CRC
(查表法)CRC检验码的计算过程 (1)将上次计算出的CRC校验码右移一个字节: (2)将移出的这个字节与新的要校验的字节进行XOR 运算: (3)用运算出的值在预先生成码表中进行索引,获取对应的值( ...
- 常用crc查表法_请教查表法计算CRC的原理
自己写过的, 希望对你有帮助 Cyclic Redundancy Check(CRC) 原理及实现 /// 1: 需求 在数据传送过程中,为了能够进行错误检测, 往往在数据后追加一些检测码, 当接受方 ...
- CRC算法 个人学习笔记 直接法、查表法注意点
CRC检验码主要是用在数据校验中,用于判断对应数据是否发生传输错误,详细的介绍百度就可以.本文主要是记录我个人在这几天学习使用CRC的过程中遇到的问题.各位在阅读时如果有发现问题,可在评论区留言,谢谢 ...
- C语言与,或,非,同或,异或,左移,右移及优先级,查表法计算一个十进制数中1的个数
1.与:& 2.或:| 3.非:~ 4.异或:^ 5.同或:~^ 6.左移:(<<) 7.右移:(>>) 注意:位运算符中求反运算"~"优先级最高, ...
- 【基础知识】CRC(循环冗余校验)直接计算和查表法
CRC概述 校验 校验是什么,个人理解就是经过一个算法,使用大量数据(几MB的数据)生成较小长度的一串信息(如16Bit),并切要做到 原数据不同时,生成的信息大概率不同(不是加密算法不考虑刻意造数据 ...
- QT ModbusCRC16 校验码计算(非查表法,直接计算)
记录一下QT中如何实现 ModbusCRC16 校验码计算 #include <QCoreApplication> #include <QDebug>//CRC16计算函数 u ...
- CRC16计算代码(查表法)
unsigned short CRC16 (unsigned char *puchMsg,unsigned short usDataLen ) /* 函数以 unsigned short 类型返回 C ...
- C语言查表法实现CRC-16计算
文章目录 函数实现 示例代码 运行结果 函数实现 /*16 bit CRC with polynomial x^16+x^12+x^5+1 */ uint16_t crc16_compute(cons ...
最新文章
- (记忆宏)Function问题
- 记一次libfreenect2安装配置的经历
- vue2.0小示例一个~~新鲜出炉哦。欢迎大家留言
- 【STM32】窗口看门狗 WWDG 实验代码详解
- 简单易上手的Bootstrap
- Spring5的数据访问与集成
- Marketing Cloud profile界面功能介绍
- SPI模式下MCU对SD卡的控制及操作命令
- Http\Https\Socket
- jQuery之.queue()
- python读写不同编码txt文件
- Android 微信分享后留在微信,没有回调的问题解决方案
- iOS Crash类别总结
- LEADBBS 不要验证码
- 运行spark及hadoop版本不一致解决方法
- 第七届山东理工大学ACM趣味编程循环赛 Round#2 sdut4120 城堡问题
- GPU 共享内存地址映射方式
- 【jzoj5289】【NOIP2017提高组A组模拟8.17】【偷笑】【数据结构】
- sqli-labs第十三关--十五关
- 喜欢的现代诗 -。-