[Bug libstdc++/90638] Wrong results of pow(complex , T1) function when the T1 type differs from T and from int

2019-06-07 Thread redi at gcc dot gnu.org
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

2019-06-07 Thread redi at gcc dot gnu.org
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

2019-05-27 Thread Igor.Smirnov at cern dot ch
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

2019-05-27 Thread Igor.Smirnov at cern dot ch
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

2019-05-27 Thread Igor.Smirnov at cern dot ch
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

2019-05-27 Thread glisse at gcc dot gnu.org
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

2019-05-27 Thread Igor.Smirnov at cern dot ch
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

2019-05-27 Thread rguenth at gcc dot gnu.org
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

2019-05-26 Thread Igor.Smirnov at cern dot ch
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

2019-05-26 Thread redi at gcc dot gnu.org
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?