快速找到以 2 为底的对数的整数部分

quickly find the integer part of the base 2 logarithm

计算浮点数以 2 为底的对数的整数部分的有效方法是什么?像

N = ceil( log2( f ))

N = floor( log2( f ))

对于浮点数 f。我想这有可能以某种方式非常有效地实现,因为人们可能只需要访问浮点指数。

EDIT2:我主要对精确性不感兴趣。我可以容忍 +-1 的错误。我列出这两种变体只是作为示例,因为其中一种可能在计算上比另一种更便宜(但我不知道)。

我需要这个来控制算法的精度,其中参数 f 是一些公差,并且需要对数来控制项数。 log的计算准确不重要

编辑:这与其他许多要求 整数 参数(例如 How to do an integer log2() in C++?)的 log2 的问题不重复。这是关于 浮点数 的论点和一个完全不同的故事。具体来说,对于 f < 1,我需要它,这对于整数方法

根本不可能

标准库函数 frexp 正是这样做的:它将双精度分解为整数指数和归一化尾数。

如果您对对数的下限感到满意,而不是将对数四舍五入到最接近的整数,您可能最好使用较新的标准库函数 ilogb

请注意,这两个函数对零和无穷大的处理方式不同,因此它们不能完全互换。

受 rici 的启发,他向我指出了 frexp,我想我找到了答案。在 C99 和最近的 C++ 中,我们有函数 ilogb,它完全满足我的需要

int ilogb( float arg );
int ilogb( double arg );

相当于

(int)logb( arg )

它returns比frexp少了一位。所以 frexp 结果对应

floor(log2(arg)+1 

和 ilogb(arg) 到

floor(log2(arg))

这是一个可怕的 hack,它从 little-endian 中提取指数 float 尽管我不保证可移植性等

#include <stdio.h>

int main(void) {
    float f;
    unsigned i;
    unsigned *ip = (unsigned*)&f;

    printf("Enter a float: ");
    scanf("%f", &f);
    i = *ip;
    i = (i >> 23) & 0xFF;
    i -= 127;
    printf("%f %d\n", f, (int)i);
    return 0;
}

程序输出:

Enter a float: 0.125
0.125000 -3