Ian Taylor <[email protected]> writes: > I don't know what's up with the complex number change. In general the > Go compiler and libraries go to some effort to produce the same > answers on all platforms. We need to understand why we get different > answers on s390 (you may understand the differences, but I don't).
Oh, I know this one. I've even filed yet another bug about it:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59714
I assume s390 has a fused multiply add instruction? It's because
libgcc's implementation of complex division is written in a way such
that gcc compiles an expression like a*b-c*d as fma(a,b,-c*d) and even if
a==c and b==d the latter expression doesn't return 0 unless things are
in power of 2 ratios with one another.
> I won't change the tests without a clear understanding of why we are
> changing them.
I think the *real* fix is for libgcc to use ""Kahan's compensated
algorithm for 2 by 2 determinants"[1] to compute a*b-c*d when fma is
available.
Cheers,
mwh
[1] That's something like this:
// This implements what is sometimes called "Kahan's compensated algorithm
for
// 2 by 2 determinants". It returns a*b + c*d to a high degree of precision
// but depends on a fused-multiply add operation that rounds once.
//
// The obvious algorithm has problems when a*b and c*d nearly cancel, but
the
// trick is the calculation of 'e': "a*b = w + e" is exact when the operands
// are considered as real numbers. So if c*d nearly cancels out w, e
restores
// the result to accuracy.
double
Kahan(double a, double b, double c, double d)
{
double w, e, f;
w = b * a;
e = fma(b, a, -w);
f = fma(d, c, w);
return f + e;
}
Algorithms like this is why the fma operation was introduced in the
first place!
pgpEbbVCSQqC8.pgp
Description: PGP signature
