簡體   English   中英

x64 上的快速反平方根

[英]Fast Inverse Square Root on x64

我在http://en.wikipedia.org/wiki/Fast_inverse_square_root上的網上找到了 Fast Inverse Square Root。 它在 x64 上是否正常工作? 有沒有人用過並認真測試過?

Fast Inverse Square Root 最初是為 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;
  }

我做了一些測試,似乎工作正常

是的,如果使用正確的幻數和相應的整數類型,它就可以工作。 除了上面的答案之外,這里還有一個適用於doublefloat的 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM