快速找到基数2对数的整数部分

时间:2016-09-05 19:22:45

标签: c++ c floating-point ieee-754

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

这样的东西
N = ceil( log2( f ))

N = floor( log2( f ))

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

EDIT2:我对准确性并不感兴趣。我可以容忍+ -1的错误。我列举了这两个变种只是作为一个例子,因为一个可能在计算上比另一个更便宜(但我不知道)。

我需要这个用于算法的精确控制,其中参数f是一些容差,并且需要日志来控制术语的数量。准确计算日志并不重要。

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

是完全不可能的

3 个答案:

答案 0 :(得分:7)

标准库函数frexp完全相同:它将double分解为整数指数和标准化尾数。

如果您满足于对数的最低限度,而不是将对数舍入到最接近的整数,那么使用较新的标准库函数ilogb可能会更好。

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

答案 1 :(得分:1)

受到rici指点我的启发,我想我找到了答案。在C99和最近的C ++中,我们有函数ilogb,它完全符合我的需要

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

并且相当于

(int)logb( arg )

它返回比frexp少一个。所以frexp结果对应

floor(log2(arg)+1 

和ilogb(arg)到

floor(log2(arg))

答案 2 :(得分:0)

这是一个可怕的黑客,它从小端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