[Bug libstdc++/90638] Wrong results of pow(complex , T1) function when the T1 type differs from T and from int
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90638 --- Comment #10 from Jonathan Wakely --- As a workaround for C++03, you can either change the type of lp1 and lp2 to double, or cast them when used: std::cout<<' '<&, int) overload being used.
[Bug libstdc++/90638] Wrong results of pow(complex , T1) function when the T1 type differs from T and from int
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90638 Jonathan Wakely changed: What|Removed |Added Status|WAITING |RESOLVED Resolution|--- |INVALID --- Comment #9 from Jonathan Wakely --- (In reply to Richard Biener from comment #3) > The change in output occurs with GCC 6 so that might be the version > this was fixed. That difference is because GCC 6 uses -std=gnu++14 by default. In C++03 the only overloads of std::pow for std::complex values are: template complex pow(const complex& x, int y); template complex pow(const complex& x, const complex& y); template complex pow (const complex& x, const T& y); template complex pow (const T& x, const complex& y); Calling std::pow(var0, LONG_MAX) or std::pow(var0, LONG_MAX+1UL) will select the first overload but overflow the int argument. So it's not doing what you think it's doing. Your code is undefined in C++03, and you should fix it. For C++11 that overload was removed by https://wg21.link/lwg844 and so there's no more overflow. Instead std::pow(var0, LONG_MAX) is equivalent to std::pow(var0, (double)LONG_MAX) and chooses the third overload. We don't actually remove the int overload, as explained by this comment in the source: // In C++11 mode we used to implement the resolution of // DR 844. complex pow return type is ambiguous. // thus the following overload was disabled in that mode. However, doing // that causes all sorts of issues, see, for example: // http://gcc.gnu.org/ml/libstdc++/2013-01/msg00058.html // and also PR57974. template inline complex<_Tp> pow(const complex<_Tp>& __z, int __n) { return __n < 0 ? complex<_Tp>(1) / std::__complex_pow_unsigned(__z, -(unsigned)__n) : std::__complex_pow_unsigned(__z, __n); } But we do add additional overloads which get called instead, and then forward to the right one. So this is not a bug, libstdc++ is following the C++03 standard here.
[Bug libstdc++/90638] Wrong results of pow(complex , T1) function when the T1 type differs from T and from int
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90638 --- Comment #8 from Igor Smirnov --- Let me add corrections to my previous post. 1. It needs to add (long double) before M_PI / LONG_MAX in the line long double phid = M_PI / LONG_MAX; in the above example. But the result is not changed significantly. 2. Two results for the very last expression for C++ and C++17 are correct. 3. In the other expressions only the versions 4.8.5, C++03 and C++03(GNU) give completely wrong results. Do you support "C++03"? The other versions give the correct real component and the imaginary component with wrong sign, but since this component is anyway extremely small, this can be explained by precision problems.
[Bug libstdc++/90638] Wrong results of pow(complex , T1) function when the T1 type differs from T and from int
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90638 --- Comment #7 from Igor Smirnov --- There can be still problems with big integer powers of complex numbers in the latest versions. I just don't see a single correct answer. As above the expected correct responses are marked by "should be" and the received by "actually". Notations of version started from "C++" are from the above mentioned site: --- #include #include #include int main(void) { double phi = M_PI / LONG_MAX; std::cout< var0 = std::polar(1.0, phi); std::cout< vard0 = std::polar((long double)1.0, phid); std::cout< var1 = std::polar(1.0, phi1); std::cout<
[Bug libstdc++/90638] Wrong results of pow(complex , T1) function when the T1 type differs from T and from int
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90638 --- Comment #6 from Igor Smirnov --- Mark, thank you for useful advice. So, my conclusion is that the rules for resolution in the presence of function templates are not changed in gcc. For all versions of C++ the result generated by this site was the same. The program is compiled without "call ... is ambiguous" complaints, and calls the variant of the function for "int" argument when called with long double: fun(1.1, 1)= fun(T, int) is working. 1.1 fun(1.1, 1/2.0)= fun(T, const T&) is working. 0.55 fun(1.1, (long double)1/2.0)= fun(T, int) is working. 0 This behaviour is counter to logic because an identical program with with almost identical ordinary functions is NOT compiled with complaint "prog.cc:21:28: error: call of overloaded 'fun(double, double)' is ambiguous", see an example below. Since the user may not even know that the functions are template (an ordinary function can depend on agruments having a fully specified template type), he may not notice this error. #include double fun(double x, int i) { std::cout<<"fun(double, int) is working.\n"; return x * i; } double fun(double x, const long double& d) { std::cout<<"fun(double, const long double&) is working.\n"; return x * d; } int main(void) { std::cout<<"fun(1.1, 1)="<<'\n';
[Bug libstdc++/90638] Wrong results of pow(complex , T1) function when the T1 type differs from T and from int
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90638 --- Comment #5 from Marc Glisse --- Igor, there are free websites that let you check it for yourself very easily, for instance https://wandbox.org/ , you can test many versions of the compiler online there.
[Bug libstdc++/90638] Wrong results of pow(complex , T1) function when the T1 type differs from T and from int
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90638 --- Comment #4 from Igor Smirnov --- Richard, thanks for checks. Yes this is correct result. I am wondering, do they correct this problem for complex<> and for inbuilt types only? Is there a possibility for you to run the following program on these new versions and to show the results: #include template< class T> double fun(const T& x, int i) { std::cout<<"fun(const T&, int) is working.\n"; return x * i; } template< class T> double fun(const T& x, const T& d) { std::cout<<"fun(const T&, const T&) is working.\n"; return x * d; } int main(void) { std::cout<<"fun(1.1, 1)="<<'\n';
[Bug libstdc++/90638] Wrong results of pow(complex , T1) function when the T1 type differs from T and from int
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90638 --- Comment #3 from Richard Biener --- GCC 7, 8 and 9 for me output (1,1.46292e-09) 2147483647 2147483648 (-1,7.77156e-16) (-1,-1.46292e-09) (1.55377,0.643594) (1.55377,0.643594) (1.55377,0.643594) (1.55377,0.643594) (1.55377,0.643594) (1.55377,0.643594) (1.55377,0.643594) (1.55377,0.643594) (1.55377,0.643594) (1.55377,0.643594) (1.55377,0.643594) (1.55377,0.643594) if this is the correct result this is FIXED. I can confirm your reported result with GCC 4.8 but as said that's out of maintainance. The change in output occurs with GCC 6 so that might be the version this was fixed.
[Bug libstdc++/90638] Wrong results of pow(complex , T1) function when the T1 type differs from T and from int
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90638 --- Comment #2 from Igor Smirnov --- Strange... It came with freshiest available CentOS 7.6.
[Bug libstdc++/90638] Wrong results of pow(complex , T1) function when the T1 type differs from T and from int
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90638 Jonathan Wakely changed: What|Removed |Added Status|UNCONFIRMED |WAITING Last reconfirmed||2019-05-26 Ever confirmed|0 |1 --- Comment #1 from Jonathan Wakely --- (In reply to Igor Smirnov from comment #0) > The identical problem was found for gcc versions > 4.8.5 (the output below is from it), 4.4.5, 4.4.7. All of these versions have been unsupported by the GCC project for many years. Does the problem still exist in current releases?