x64上的快速平方根倒数
Fast Inverse Square Root on x64
我在网上找到了http://en.wikipedia.org/wiki/Fast_inverse_square_root。它在x64上正常工作吗?有人用过认真的测试吗?
最初快速平方倒数是为32位浮点编写的,因此只要您在IEEE-754浮点表示上操作,x64体系结构就不会影响结果。
请注意,对于"双"精度浮点(64位),您应该使用另一个常量:
64位IEEE754尺寸型双。。。显示正是0x5fe6eb50c7b537a9
这里有一个双精度浮点的实现:
#include <cstdint>
double invsqrtQuake( double number )
{
double y = number;
double x2 = y * 0.5;
std::int64_t i = *(std::int64_t *) &y;
// The magic number is for doubles is from https://cs.uwaterloo.ca/~m32rober/rsqrt.pdf
i = 0x5fe6eb50c7b537a9 - (i >> 1);
y = *(double *) &i;
y = y * (1.5 - (x2 * y * y)); // 1st iteration
// y = y * ( 1.5 - ( x2 * y * y ) ); // 2nd iteration, this can be removed
return y;
}
我做了一些测试,它似乎运行良好
是的,如果使用正确的幻数和相应的整数类型,它就可以工作。除了上面的答案之外,这里还有一个适用于double
和float
的C++11实现。条件应该在编译时进行优化。
template <typename T, char iterations = 2> inline T inv_sqrt(T x) {
static_assert(std::is_floating_point<T>::value, "T must be floating point");
static_assert(iterations == 1 or iterations == 2, "itarations must equal 1 or 2");
typedef typename std::conditional<sizeof(T) == 8, std::int64_t, std::int32_t>::type Tint;
T y = x;
T x2 = y * 0.5;
Tint i = *(Tint *)&y;
i = (sizeof(T) == 8 ? 0x5fe6eb50c7b537a9 : 0x5f3759df) - (i >> 1);
y = *(T *)&i;
y = y * (1.5 - (x2 * y * y));
if (iterations == 2)
y = y * (1.5 - (x2 * y * y));
return y;
}
至于测试,我在我的项目中使用了以下doctest:
#ifdef DOCTEST_LIBRARY_INCLUDED
TEST_CASE_TEMPLATE("inv_sqrt", T, double, float) {
std::vector<T> vals = {0.23, 3.3, 10.2, 100.45, 512.06};
for (auto x : vals)
CHECK(inv_sqrt<T>(x) == doctest::Approx(1.0 / std::sqrt(x)));
}
#endif
相关文章:
- 平方根内禀反比
- 简单的平方根
- 如何找到数组中值倒数第二次出现的索引
- 是否有一个C++函数可以准确返回平方根反比的内置 CPU 操作 RSQRTSS 的值?
- 如何打印第一个和最后一个元素的和,然后打印第二个和倒数第二个元素的总和,依此类推
- 试图找到一个数字的平方根,但代码不起作用。C++
- 使用索引与迭代器将向量迭代到倒数第二个元素
- 使用二分法查找数的平方根时出现问题
- 期望_DEATH的倒数是多少
- 如何使用C 获取周期十进加点号的平方根
- 如何获取列表中的倒数第二个元素
- C 平方根 /巴比伦法
- 对于我扩展此程序来计算最高10x10矩阵的倒数的最简单方法是什么
- C++迭代到倒数第二个元素
- 这种浮点平方根近似是如何工作的
- 使用位移算法计算平方根始终输出相同的数字
- C++ 安全倒数到零"auto"整型
- 为什么我需要绑定姿势矩阵的倒数来计算动画
- 特征库:计算倒数时静态和动态大小矩阵之间的不同行为
- x64上的快速平方根倒数