[C/C++]一种超级快且简洁的log2取整算法

相关文章我以前也发过一次,但是那种写法显然不够简洁,今天意外又发现了一种:

int log_2(int x) {
    float f = x;
    return (*(int*)&f >> 23) - 0x7f;
}

benchmark下来跟以前那种差距不大,下面简单描述一下原理:

根据 IEEE 754,float类型在内存中占32bit,依次存储1bit符号位、8bit阶码和22bit尾数。这里阶码就是我们所需要的,另外既然取以2为底的对数那么真数必然非负,所以符号位可以不考虑,只要进行一次移位操作就可以得到阶码,根据标准阶码减去0x7f就是我们所需。

另外,上面的代码中来回用指针的目的只是把float类型的数据一个比特不动地强制转换到int,如果你认为其不优雅,可以使用以下c++20中新加入的内容实现:

#include <bit>

int log_2(int x) {
    float f = x;
    return (std::bit_cast<int>(f) >> 23) - 127;
}
bit·ieee-754·c++
150 views
Comments
登录后评论
Sign In
·

notice:第一种写法可能会触发警告,请谨慎使用!