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

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #0)
> #define _GLIBCXX_ASSERTIONS
> #include <complex>
> #include <limits>
> 
> int main()
> {
>   double nan = std::numeric_limits<double>::quiet_NaN();
>   std::pow(10, std::complex<double>(nan, 1));

Actually maybe the assertion is OK. This violates [complex.numbers] p3:

"If the result of a function is not mathematically defined or not in the range
of representable values for its type, the behavior is undefined."

10^(nan + 1i) is not mathematically defined, an assertion seems OK.

If we want to prevent the assertion here we could do:

--- a/libstdc++-v3/include/std/complex
+++ b/libstdc++-v3/include/std/complex
@@ -699,12 +699,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        && !_GLIBCXX_FAST_MATH>::_S_do_it(__z);
     }

+  template<typename _Tp>
+    inline complex<_Tp>
+    __polar(const _Tp& __rho, const _Tp& __theta)
+    { return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); }
+
   template<typename _Tp>
     inline complex<_Tp>
     polar(const _Tp& __rho, const _Tp& __theta)
     {
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 2459. std::polar should require a non-negative rho
       __glibcxx_assert( __rho >= 0 );
-      return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta));
+      return std::__polar<_Tp>(__rho, __theta);
     }

   template<typename _Tp>
@@ -778,7 +785,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     inline complex<_Tp>
     __complex_exp(const complex<_Tp>& __z)
-    { return std::polar<_Tp>(exp(__z.real()), __z.imag()); }
+    { return std::__polar<_Tp>(exp(__z.real()), __z.imag()); }

 #if _GLIBCXX_USE_C99_COMPLEX
   inline __complex__ float
@@ -1038,7 +1045,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         return pow(__x.real(), __y);

       complex<_Tp> __t = std::log(__x);
-      return std::polar<_Tp>(exp(__y * __t.real()), __y * __t.imag());
+      return std::__polar<_Tp>(exp(__y * __t.real()), __y * __t.imag());
     }

   template<typename _Tp>
@@ -1075,8 +1082,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     inline complex<_Tp>
     pow(const _Tp& __x, const complex<_Tp>& __y)
     {
-      return __x > _Tp() ? std::polar<_Tp>(pow(__x, __y.real()),
-                                          __y.imag() * log(__x))
+      return __x > _Tp() ? std::__polar<_Tp>(pow(__x, __y.real()),
+                                            __y.imag() * log(__x))
                         : std::pow(complex<_Tp>(__x), __y);
     }

Reply via email to