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

            Bug ID: 115117
           Summary: std::exp(Inf) result invalid with --disable-c99
           Product: gcc
           Version: 13.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: tomas.kalibera at gmail dot com
  Target Milestone: ---

Created attachment 58218
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58218&action=edit
Example program ("im(e^inf):" should be 0, but is not with --disable-c99)

When the C++ library is built without C99 support (e.g. via passing
--disable-c99 to configure of gcc), the result of complex std::exp(Inf) is
incorrect, the imaginary part is NaN, but it should be zero.

It seems this is caused by this code in "complex", which doesn't handle special
cases:

  // 26.2.8/3 exp(__z): Returns the complex base e exponential of x
  template<typename _Tp>
    inline complex<_Tp>
    __complex_exp(const complex<_Tp>& __z)
    { return std::polar<_Tp>(exp(__z.real()), __z.imag()); }

that calls into:

  template<typename _Tp>
    inline complex<_Tp>
    polar(const _Tp& __rho, const _Tp& __theta)
    {
      __glibcxx_assert( __rho >= 0 );
      return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta));
    }

where __rho is Inf, so the imaginary part becomes Inf * 0.

For example, the glibc implementation handles this special case explicitly as
follows (./math/s_cexp_template.c):

else if (__glibc_likely (rcls == FP_INFINITE))
    {
      /* Real part is infinite.  */
      if (__glibc_likely (icls >= FP_ZERO))
        {
          /* Imaginary part is finite.  */
          FLOAT value = signbit (__real__ x) ? 0 : M_HUGE_VAL;

          if (icls == FP_ZERO)
            {
              /* Imaginary part is 0.0.  */
              __real__ retval = value;
              __imag__ retval = __imag__ x;
            }

I've this problem happen via _GLIBCXX11_USE_C99_COMPLEX being disabled by
accident, which still has to be investigated, but --disable-c99 reproduces it.
Example program from Andrew Johnson is attached.

I can reproduce the problem on Windows and Linux (on Windows I get nan, on
Linux I get -nan).

Reply via email to