[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 Richard Biener changed: What|Removed |Added Target Milestone|9.5 |---
[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 Richard Biener changed: What|Removed |Added Target Milestone|9.4 |9.5 --- Comment #16 from Richard Biener --- GCC 9.4 is being released, retargeting bugs to GCC 9.5.
[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 Jakub Jelinek changed: What|Removed |Added Target Milestone|9.3 |9.4 --- Comment #15 from Jakub Jelinek --- GCC 9.3.0 has been released, adjusting target milestone.
[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 Jonathan Wakely changed: What|Removed |Added Resolution|FIXED |--- Status|RESOLVED|REOPENED --- Comment #14 from Jonathan Wakely --- Reopening due to the failing test.
[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 --- Comment #13 from Christophe Lyon --- It's still failing on trunk: https://gcc.gnu.org/ml/gcc-testresults/2019-11/msg00131.html
[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 --- Comment #12 from Jonathan Wakely --- I probably missed a later fix that got made to the trunk version of the test. I'll take a look.
[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 Christophe Lyon changed: What|Removed |Added CC||clyon at gcc dot gnu.org --- Comment #11 from Christophe Lyon --- The new test (26_numerics/complex/proj.cc) passes on arm, but fails on aarch64-none-elf (passes on aarch64-linux-gnu). /libstdc++-v3/testsuite/26_numerics/complex/proj.cc:105: void test01(): Assertion 'eq( std::proj(c0p) , std::complex(pinf, +0.0) )' failed. FAIL: 26_numerics/complex/proj.cc execution test According to gcc-testresults, it fails on other targets too.
[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 Jonathan Wakely changed: What|Removed |Added Target Milestone|10.0|9.3
[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 --- Comment #10 from Jonathan Wakely --- Author: redi Date: Thu Oct 24 12:55:21 2019 New Revision: 277392 URL: https://gcc.gnu.org/viewcvs?rev=277392=gcc=rev Log: PR libstdc++/61761 fix std::proj for targets without C99 cproj The current generic implementation of __complex_proj used when cproj is not available calculates the wrong projection, giving a different result than given by C99's cproj. When C99 cproj is not available but isinf and copysign are, use those to give correct results for float, double and long double. Otherwise, and for other specializations of std::complex, just use a generic version that returns its argument, and so doesn't support infinities. We might want to consider adding additional overloads of __complex_proj to support extended types such as _Float64x, _Float128 etc. Backport from mainline 2019-05-01 Jonathan Wakely PR libstdc++/61761 * include/std/complex (__complex_proj): Return parameter unchanged. [_GLIBCXX_USE_C99_COMPLEX] (__complex_proj): Change overloads for floating-point types to take std::complex arguments. [_GLIBCXX_USE_C99_MATH_TR1] (__complex_proj): Add overloads for floating-point types. * testsuite/26_numerics/complex/proj.cc: New test. Added: branches/gcc-9-branch/libstdc++-v3/testsuite/26_numerics/complex/proj.cc Modified: branches/gcc-9-branch/libstdc++-v3/ChangeLog branches/gcc-9-branch/libstdc++-v3/include/std/complex
[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 --- Comment #9 from Jonathan Wakely --- Author: redi Date: Fri May 3 19:25:05 2019 New Revision: 270859 URL: https://gcc.gnu.org/viewcvs?rev=270859=gcc=rev Log: Fix new testcase to not require std::copysign Use __builtin_copysign{,f,l} when std::copysign isn't available. PR libstdc++/61761 * testsuite/26_numerics/complex/proj.cc: Don't assume defines std::copysign. Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/testsuite/26_numerics/complex/proj.cc
[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 Jonathan Wakely changed: What|Removed |Added Status|ASSIGNED|RESOLVED Resolution|--- |FIXED --- Comment #8 from Jonathan Wakely --- I fixed it differently in the end, but using the same logic. Thanks again.
[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 --- Comment #7 from Jonathan Wakely --- Author: redi Date: Wed May 1 00:08:36 2019 New Revision: 270759 URL: https://gcc.gnu.org/viewcvs?rev=270759=gcc=rev Log: PR libstdc++/61761 fix std::proj for targets without C99 cproj The current generic implementation of __complex_proj used when cproj is not available calculates the wrong projection, giving a different result than given by C99's cproj. When C99 cproj is not available but isinf and copysign are, use those to give correct results for float, double and long double. Otherwise, and for other specializations of std::complex, just use a generic version that returns its argument, and so doesn't support infinities. We might want to consider adding additional overloads of __complex_proj to support extended types such as _Float64x, _Float128 etc. PR libstdc++/61761 * include/std/complex (__complex_proj): Return parameter unchanged. [_GLIBCXX_USE_C99_COMPLEX] (__complex_proj): Change overloads for floating-point types to take std::complex arguments. [_GLIBCXX_USE_C99_MATH_TR1] (__complex_proj): Add overloads for floating-point types. * testsuite/26_numerics/complex/proj.cc: New test. Added: trunk/libstdc++-v3/testsuite/26_numerics/complex/proj.cc Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/include/std/complex
[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 --- Comment #6 from Jonathan Wakely --- (In reply to Jan van Dijk from comment #5) > Does the usage of numeric_limits<_Tp> in complex work well for user-defined > _Tp? We can assume it does. > For complex, at present MyType can be required to be constructible > from INFINITY to make proj work. Wouldn't using numeric_limits<_Tp> dictate > a (forbidden) numeric_limits specialization to provide > numeric_limits::infinity()? There's nothing forbidden about specializing numeric_limits.
[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 --- Comment #5 from Jan van Dijk --- Does the usage of numeric_limits<_Tp> in complex work well for user-defined _Tp? For complex, at present MyType can be required to be constructible from INFINITY to make proj work. Wouldn't using numeric_limits<_Tp> dictate a (forbidden) numeric_limits specialization to provide numeric_limits::infinity()?
[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 --- Comment #4 from Jonathan Wakely --- I think your patch as as good as anything else we'll come up with, apart from using numeric_limits::infinity() instead of INFINITY. Anybody who wants to use std::proj with types other than float, double and long double will have to ensure that std::isinf and std::copysign work. I'll add some tests and commit it shortly, thanks.
[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 Jonathan Wakely changed: What|Removed |Added Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |redi at gcc dot gnu.org Target Milestone|--- |10.0 Severity|minor |normal
[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 --- Comment #3 from Jonathan Wakely --- (In reply to Jan van Dijk from comment #2) > 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?) Look at the source. defines the full std::complex primary template as well as explicit specializations for std::complex, std::complex and std::complex.
[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 Jan van Dijk changed: What|Removed |Added CC||j.v.dijk at tue dot nl --- Comment #2 from Jan van Dijk --- 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
[Bug libstdc++/61761] [C++11] std::proj returns incorrect values
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761 Jonathan Wakely redi at gcc dot gnu.org changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2015-04-09 Ever confirmed|0 |1 Severity|normal |minor --- Comment #1 from Jonathan Wakely redi at gcc dot gnu.org --- I suppose something like this isn't usable because it won't work unless _Tp is float, double or long double: --- a/libstdc++-v3/include/std/complex +++ b/libstdc++-v3/include/std/complex @@ -1887,11 +1887,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION 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()) + || isnan(__z.real()) || isnan(__z.imag())) + return std::complex_Tp(INFINITY, copysign(0.0, __z.imag())); + return __z; } #if _GLIBCXX_USE_C99_COMPLEX