std :: norm(std :: complex)使用平方根而不是快速实现

特里

在C ++中norm,复数c的定义为abs(c)^2这意味着它re(c)^2+im(z)^2

这是实现:

template<bool>
struct _Norm_helper
{
  template<typename _Tp>
    static inline _Tp _S_do_it(const complex<_Tp>& __z)
    {
      const _Tp __x = __z.real();
      const _Tp __y = __z.imag();
      return __x * __x + __y * __y;
    }
};

template<>
struct _Norm_helper<true>
{
  template<typename _Tp>
    static inline _Tp _S_do_it(const complex<_Tp>& __z)
    {
      _Tp __res = std::abs(__z);
      return __res * __res;
    }
};

为什么有人要使用第二种实现?

第一个显然更快,因为它不使用abssqrt涉及到位置。

静脉血

如果我们研究实施方案,就会在这里找到答案,

  // 26.2.7/5: norm(__z) returns the squared magnitude of __z.
  //     As defined, norm() is -not- a norm is the common mathematical
  //     sens used in numerics.  The helper class _Norm_helper<> tries to
  //     distinguish between builtin floating point and the rest, so as
  //     to deliver an answer as close as possible to the real value.
  template<bool>
    struct _Norm_helper
    {
      template<typename _Tp>
        static inline _Tp _S_do_it(const complex<_Tp>& __z)
        {
          const _Tp __x = __z.real();
          const _Tp __y = __z.imag();
          return __x * __x + __y * __y;
        }
    };

  template<>
    struct _Norm_helper<true>
    {
      template<typename _Tp>
        static inline _Tp _S_do_it(const complex<_Tp>& __z)
        {
          _Tp __res = std::abs(__z);
          return __res * __res;
        }
    };

  template<typename _Tp>
    inline _Tp
    norm(const complex<_Tp>& __z)
    {
      return _Norm_helper<__is_floating<_Tp>::__value 
         && !_GLIBCXX_FAST_MATH>::_S_do_it(__z);
    }

因此,当第二实现被称为norm施加到内置浮点类型的值(这是floatdoublelong double,或__float128每GCC 4.8.1如),并且如果-fast-math未设置选项。这样做是为了符合norm定义为的标准定义the squared magnitude of z

由于舍入误差z.real()*z.real() + z.imag()*z.imag()不相等abs(z)*abs(z),因此第一个版本将与规范措辞不一致(这可能表示规范存在问题)。为了更容易理解,为什么措辞很重要,请考虑期望这样做的代码norm(x) / abs(x) = x当然,这是一个错误的代码,但是从某种意义上说,该标准保证了这应该是正确的。

但是,一旦设置了FAST_MATH或complex将其专用于非内置类型,该标准就不再具有其功能(因为它清楚地说明了行为是未定义的),并且该实现将落入第一个实现(可以说是1)更快,更精确。


1))它实际上取决于许多因素(例如是否使用内置的内在函数)和yada,yada,yada,因此让我们以一小撮盐来接受这一主张。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

TOP 榜单

热门标签

归档