Here are three ways to express complex<double>(-4.,0.):

    // complex<double> operator-<double>(const double&, const complex<double>&)
    complex<double> a1 = 1.
                       - complex<double>(5.0, 0.0);
    cout << a1 << endl;  // (-4,-0)
    // complex<double> operator-<double>(const complex<double>&, const
complex<double>&)
    complex<double> a2 = complex<double>(1.0, 0.0)
                       - complex<double>(5.0, 0.0);
    cout << a2 << endl;  // (-4,0)
    // complex<double> operator-<double>(const complex<double>&, const double&)
    complex<double> a3 = complex<double>(1.0, 0.0)
                       - 5.0;
    cout << a3 << endl;  // (-4,0)

In the first version, the imaginary part gets a spurious minus sign.  That is
quite disruptive when you consider that a1 could be the argument of a logarithm
because it then ends up on the wrong side of the branch cut.

While I am currently unable to track this to any standard, I would guess that
the resulting imaginary part should be governed by what 0.0-0.0 is.  By analogy,
the first result would be wrong, unless its undefined behavior (which would be a
pity).

The problem is in libstdc++-v3/include/std/std_complex.h:366.  I propose to
change the function body to not use unary operator- in the imaginary part.  I'm
going to attach two analogous patches.

-- 
           Summary: operator-(const T&, const complex<T>&) vs operator-
                    (const complex<T>&, const complex<T>&)
           Product: gcc
           Version: 4.0.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: libstdc++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: kreckel at ginac dot de
                CC: gcc-bugs at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20759

Reply via email to