https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121615

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Or just use hypot(real, imag) for integer types, which will promote them to
double that way instead.

  // 26.2.7/3 abs(__z):  Returns the magnitude of __z.
#if _GLIBCXX_USE_C99_COMPLEX
  inline float
  __complex_abs(__complex__ float __z) { return __builtin_cabsf(__z); }

  inline double
  __complex_abs(__complex__ double __z) { return __builtin_cabs(__z); }

  inline long double
  __complex_abs(const __complex__ long double& __z)
  { return __builtin_cabsl(__z); }

  template<typename _Tp>
    inline _Tp
    abs(const complex<_Tp>& __z) { return hypot(__z.real(), __z.imag()); }
#else
  template<typename _Tp>
    inline
    typename __gnu_cxx::__enable_if<!__is_integer<_Tp>::__value, _Tp>::__type
    abs(const complex<_Tp>& __z)
    {
      _Tp __x = __z.real();
      _Tp __y = __z.imag();
      const _Tp __s = std::max(abs(__x), abs(__y));
      if (__s == _Tp())  // well ...
        return __s;
      __x /= __s;
      __y /= __s;
      return __s * sqrt(__x * __x + __y * __y);
    }

  template<typename _Tp>
    inline
    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, _Tp>::__type
    abs(const complex<_Tp>& __z) { return hypot(__z.real(), __z.imag()); }
#endif

Reply via email to