https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761
Jan van Dijk <j.v.dijk at tue dot nl> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |j.v.dijk at tue dot nl --- Comment #2 from Jan van Dijk <j.v.dijk at tue dot nl> --- Is it not perfectly fine that your patch works only for _Tp equal to float, double or long double? Anything else is unspecified per 24.5(2). Does libstdc++ advertise to go beyond the standard and support other scalar types as well? (And if so: is that policy documented anywhere?) That said, I think that the correct patch would be: Index: libstdc++-v3/include/std/complex =================================================================== --- libstdc++-v3/include/std/complex (revision 270684) +++ libstdc++-v3/include/std/complex (working copy) @@ -1902,11 +1902,9 @@ std::complex<_Tp> __complex_proj(const std::complex<_Tp>& __z) { - const _Tp __den = (__z.real() * __z.real() - + __z.imag() * __z.imag() + _Tp(1.0)); - - return std::complex<_Tp>((_Tp(2.0) * __z.real()) / __den, - (_Tp(2.0) * __z.imag()) / __den); + if (isinf(__z.real()) || isinf(__z.imag())) + return std::complex<_Tp>(INFINITY, copysign(0.0, __z.imag())); + return __z; } #if _GLIBCXX_USE_C99_COMPLEX Note that the combinations finite,nan and nan,finite should return __z unmodified. As the OP mentions, this was a problem in glibc as well that was later fixed, see: https://sourceware.org/ml/libc-alpha/2013-08/msg00374.html The patch above makes libstdc++ do exactly what is also found in current glibc's implementation in s_cproj_template.c