我需要在C++中实现非常快速的log2(float x)函数.
我发现了一个非常有趣的实现(非常快!)
#include <intrin.h>
inline unsigned long log2(int x)
{
unsigned long y;
_BitScanReverse(&y, x);
return y;
}
Run Code Online (Sandbox Code Playgroud)
但是此函数仅适用于输入中的整数值.
问题:有没有办法将此函数转换为double类型的输入变量?
UPD:
我找到了这个实现:
typedef unsigned long uint32;
typedef long int32;
static inline int32 ilog2(float x)
{
uint32 ix = (uint32&)x;
uint32 exp = (ix >> 23) & 0xFF;
int32 log2 = int32(exp) - 127;
return log2;
}
Run Code Online (Sandbox Code Playgroud)
这比前一个示例快得多,但输出是无符号类型.
是否可以使此函数返回double类型?
提前致谢!
如果只需要对数的整数部分,则可以直接从浮点数中提取.
可移植:
#include <cmath>
int log2_fast(double d) {
int result;
std::frexp(d, &result);
return result-1;
}
Run Code Online (Sandbox Code Playgroud)
可能更快,但依赖于未指定和未定义的行为:
int log2_evil(double d) {
return ((reinterpret_cast<unsigned long long&>(d) >> 52) & 0x7ff) - 1023;
}
Run Code Online (Sandbox Code Playgroud)
编辑:在下面的评论中查看 Job 的链接以获得更好的版本。
快速日志()函数 (5× faster approximately)
也许你感兴趣。代码在这里工作;虽然它不是无限精确。由于网页上的代码已损坏(> 已删除),我将在此处发布:
inline float fast_log2 (float val)
{
int * const exp_ptr = reinterpret_cast <int *> (&val);
int x = *exp_ptr;
const int log_2 = ((x >> 23) & 255) - 128;
x &= ~(255 << 23);
x += 127 << 23;
*exp_ptr = x;
val = ((-1.0f/3) * val + 2) * val - 2.0f/3; // (1)
return (val + log_2);
}
inline float fast_log (const float &val)
{
return (fast_log2 (val) * 0.69314718f);
}
Run Code Online (Sandbox Code Playgroud)
小智 5
提供XX.XXXXXXX + -0.0054545的MSVC + GCC兼容版本
float mFast_Log2(float val) {
union { float val; int32_t x; } u = { val };
register float log_2 = (float)(((u.x >> 23) & 255) - 128);
u.x &= ~(255 << 23);
u.x += 127 << 23;
log_2 += ((-0.3358287811f) * u.val + 2.0f) * u.val -0.65871759316667f;
return (log_2);
}
Run Code Online (Sandbox Code Playgroud)
Pup*_*ppy -2
该函数不是 C++ 函数,而是 MSVC++ 特有的函数。另外,我非常怀疑是否存在这样的内在函数。如果他们这样做了,标准函数只需配置为使用它即可。所以只需调用标准提供的库即可。
| 归档时间: |
|
| 查看次数: |
11849 次 |
| 最近记录: |