快速找到以 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
计算浮点数以 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